對ctfwiki格式化字串漏洞的一點補充

2021-10-19 09:41:47 字數 1132 閱讀 4280

看過ctfwiki格式化字串部分,把遇到的疑惑的理解記錄下來

拿改棧上乙個引數的值為例,更改我們的輸入

我起初不懂為什麼會有這個偏移,看wiki說的我以為是簡單的入棧順序造成的,後來看了這個才知道為什麼有這個偏移,簡單來說就是,例如

char a[

100]

;scanf

("%s"

,a);

printf

(a);

這裡輸入a時是把棧上a的值給替換成輸入的值,這個棧指的是main函式的棧,因為a是mian函式的區域性變數,然後就又有printf函式的呼叫,這時printf函式的棧在a棧楨的上面,然後printf入棧的引數是a的位址,在這裡就有了偏移,我們要改的不是printf入棧的那個引數,那個只是位址,改了之後只是不對應a了,對a真正的值沒影響,我們要改的是a,也就是在這個函式的棧裡去修改別的函式的棧的內容,我們要計算printf函式入參的那個棧楨相較a變數存的棧楨的差,這是偏移的原因

理解上面的偏移之後這裡就不難了,首先一點是在前在後的時候對應的要覆蓋的位址不同,偏移不同,在前那就是偏移小點,在後的話,payload前面的內容把本該在第乙個棧楨的要修改的值擠到了下面的棧楨裡,所以偏移要適當新增,而且這時在%k%n後面與位址之間也有必要填充,湊夠4或8對齊,理解上面的偏移之後這點不難

起初迷惑為什麼有了

elf = elf(

'./pwn'

)puts_got=elf.got[

'puts'

]

之後還要洩露位址才能得到puts的位址用來查libc,後來明白elf.got得到的是got表中的內容,對應的是puts函式的位址的位址(這麼說好像也不對),反正就是got表得到的並不是我們想要的,我們需要把這個值入棧,作為位址,利用格式化字串來獲得把這個值作為位址得到的值,那個才是真正的puts函式位址,才能用來查libc

就是wiki裡hijack retaddr部分,非要先用格式化字串偏移為6得到ebp的值,然後再用這個值和返回位址所在棧楨的差值來算出返回位址,而不是直接用偏移為7獲得,後來明白,我們需要的不是這個返回位址本身,我們要的是返回位址的位址,因為我們要改返回位址,所以知道了返回位址在哪後就能把這個位址的值改變,只知道原返回位址做不到這一步

格式化字串漏

當printf系列函式的格式化串裡包含使用者提交的資料時,就有可能出現格式化串漏洞。函式包括 snprintf vfprintf vprintf vsprintf vsnprintf 除了這呰函式外,其他接受c風格格式符的函式也可能存在類似風險,例如wind0ws上的wprintf函式。攻擊者可能提...

字串格式化

sprintf snprintf snprintf std stringstream std strstream boost lexical cast boost format cstring format 1 sprintf 使用 sprintf 不安全,輕則破壞資料的準確性,重則程式崩潰。請看下...

格式化字串

通常在使用字串的時候,會對字串進行格式化,然後輸出或呼叫 一般我們使用替換標記對字串進行格式化 string str1 string.format add is 1,2,3 而且在c 中的替換標記可以以任意順序和次數出現在格式化字串中,但替換值是按順序排的,而且替換標記不能超出索引範圍 string...