1. 程式人生 > 實用技巧 >攻防世界 int_overflow 超超超詳細

攻防世界 int_overflow 超超超詳細

pwn純新手教程 如有錯誤的地方 希望各位大佬們指出.

整數溢位

int_overflow

整數分為有符號(int)和無符號(unsigned int)兩種型別
有符號數以最高位作為其符號位
即正整數最高位為 1,負數為 0
無符號數取值範圍為非負數
常見各型別佔用位元組數如下:
型別 位元組 取值範圍
int 4 -2147483648~2147483647
short int 2 -32768~32767
long int 4 -2147483648~2147483647
unsigned int 4 0~4294967295
unsigned short int 2 0~65535
unsigned long int 4 0~4294967295

也就是說,對於一個2位元組的unsigned short int型變數
它的有效資料長度為兩個位元組
當它的資料長度超過兩個位元組
就溢位,溢位的部分則直接忽略
使用相關變數時,使用的資料僅為最後2個位元組
因此就會出現65539等於3的情況
其他型別變數和數值與之類似。

造成輸出錯誤的原因在於把32 bit的int整數賦值給16bit的unsign short整數,賦值後只會取數值的後16bit值,高位截斷,造成整數溢位

0B = 二進位制
bin(65535) =‘000b 1111 1111 1111 1111’
bin(65539) = ‘0001 0000 0000 0000 0011’
bin(3) = ‘0000 0000 0000 0000 0011’

可以看到 bin(65539) 最終的值為0011 bin(3)也相同
RELRO:Partial RELRO

在這裡插入圖片描述
在mian函式中看到呼叫login函式其他的地方沒問題
在這裡插入圖片描述
好像也沒什麼問題 但是出現了危險函式 check_passwd
在這裡插入圖片描述
首先 v3 設定了一個 unsigned _int8 v3 無符號 8位引數
v3 = 0 ~ 255
然後 v3 = strlen(s);
unsigned _init8 v3; 長度最大為8位 255
len是個unsigned int 8,而strlen()返回值是一個size_t型別的變數,它是無符號32bit的。
在這裡插入圖片描述
在第7行賦值的過程中,編譯器會截斷後者的末八位賦值給前者。8位的最大值是 255 ,所以如果passwd字串長度

超過255就會導致溢位.

在這裡插入圖片描述

看到上一層 read讀取的時候 可以讀取到0x199位資料 遠遠大於 255
在這裡插入圖片描述
在這裡插入圖片描述
所以存在整數型溢位漏洞.

因為 溢位部分會將後八位賦值給前面 所以 在 255的基礎上 加上 原本限制的4 - 8
在溢位後將255多餘的部分賦值給v3 然後就能繞過if判斷.

259 - 264

算取偏移值
在這裡插入圖片描述
首先看到 我們再繞過if 進入else以後 然後 將s的值賦值給dest然後進行賦值

在這裡插入圖片描述
可以看到 s 入棧以後 到 dest 系統stack預設分配了14個位元組給dest
stack中給出的儲存passwd的大小為0x14 :
在這裡插入圖片描述
再通過看彙編原始碼發現最後還有一個leave出棧 需要在多加4個位元組

從彙編程式碼中可以看到,想要覆蓋到返回地址,先使用0x14 個數據覆蓋stack拷貝的passed的記憶體區域,然後使用4位元組資料覆蓋ebp,再使用"cat flag"的地址覆蓋返回地址,最後接上262剩餘的資料即可。
(1)ESP:棧指標暫存器(extended stack pointer),其記憶體放著一個指標,該指標永遠指向系統棧最上面一個棧幀的棧頂。

(2)EBP:基址指標暫存器(extended base pointer),其記憶體放著一個指標,該指標永遠指向系統棧最上面一個棧幀的底部。

先用 0x14 覆蓋掉 stack給dest 也就是 passwd分配的空間 然後 再用四個位元組覆蓋掉EBP 然後再將返回地址 用 catflag地址覆蓋掉 最後將262個剩餘的資料接上即可.

取用 262個位元組 第一部分 0x14 stack給passwd分配的空間第二部分 0x4 leave分配的4個位元組 第三部分 cat flag 佔用的 十個位元組第四部分 262減去佔用的 剩下的部分/payload = ‘A’ * 0x14 + ‘a’ * 0x4 + p32(cat_flag_address) + ‘B’ * 234
p32/64 = 對資料進行打包 轉換為2進位制資料

在這裡插入圖片描述

payload 這地方 ‘B’ * 234 一定不能 寫成 0x234