学弟问了一个ctf-wiki上pwn入门题的知识点,本身没什么意思,但引发的一些小思考感觉还挺好玩的……当然也有可能我作为一个单纯的re狗,pwn题总是被队友秒光了所以没什么写shellcode或者ROP的机会,因此对shellcode的编写比较生疏叭~
题目下载链接 - sniperoj-pwn100-shellcode-x86-64

题目简介


很明显栈溢出,buf位于栈顶,栈空间为0x10个字节(可以从buf的位置==rsp+0==rbp-10h看出),所以栈分布为

内容 偏移
buf rsp
last_rbp rsp+0x10
ret_addr rsp+0x18
other rsp+0x20
buf_end rsp+0x40

题目保护只有PIE,但是栈地址被刻意给出来了所以无所谓,因此这题本身很简单只需要把execve(’/bin/sh’)的shellcode放到buf里即可。

ret_addr是需要确定的,因此能放shellcode的地方分别有上下两部分,buf-last_rbp一共0x18即24个字节,other-buf_end一共0x20即32个字节。

学弟的问题就是网上很多WP说因为buf只有24个字节所以不能用shellcraft.sh()生成的44个字节的shellcode,然后最后给出的exp清一色全是长度为23的shellcode再加上

payload = 'a'*24 + p64(shellcode_addr) + shellcode

就让人很不能理解,明明这种方法是采用的后者32个字节的空间,跟24有啥关系尼?
这些payload是可以正常打通的,实际上任何小于32bytes的payload使用后边空间都是没问题的。

分析问题

至于为什么shellcode是23字节却不能使用前者,实际上是因为leave以及空间过于紧促。
首先我们看一下shellcode的组成:

注意到最大的栈需求是连续三次push,也就是说会把rsp抬高3*8=24字节。
而leave的时候实际上相当于

mov rsp, rbp
pop rbp

而上一个栈帧中rbp是指向last_rbp的,当赋值给rsp后,又进行了一次pop使得rsp-=8指向了ret_addr
另一方面我们的shellcode是23bytes,即0x17bytes,恰好占用了buflast_rbp的空间。
因此当shellcode执行的时候第一次push会覆盖ret_addr,第二次push就会覆盖last_rbp,而last_rbp现在是shellcode的末端,导致syscall指令无法执行。

绕过分析

那么如果想要修复它,就有两条思路:

  1. 降低栈的使用
  2. 降低rsp指针

刚开始我的思路是按1走,毕竟最终syscall只需要用到2个栈空间,虽然现在只有一个但是对于空闲的1bytes可以做一次pop来获取一个额外的栈空间。
但是看了一下shellcode就会发现这个顺序已经没有办法改变了:
execve的执行条件有如下几个:

  • rax==0x3b
  • rdx==rsi==0
  • rdi==rsp *这里的rsp必须是最终的栈顶
  • 栈上分别存放'/bin//sh'和0

因为栈上的两个参数是不可省略的,而rdi又必须指向放好参数后的栈顶,在rsp是通过栈传给rdi的情况下必然要用到3个栈空间。
(rsp->rdi的过程是push rsp, pop rdi,仅需要2bytes,而正常赋值需要3bytes以上。)

于是现在有如下条件:

  • 栈空间只有1个,空闲字节也只有1byte
  • 传参需要2个栈空间
  • rsp->rdi需要1个栈空间
  • pop可以+1栈空间,但消耗1个字节
  • rsp->rdi也可以用1个字节换1个栈空间

看起来似乎就差那1byte,怎么办呢?

搜索

不就差1byte嘛,这个shellcode不行,我们来康康还有没有更好的shellcode哇!
搜索了一下发现果然有22bytes的shellcode:

payload = "\x31\xF6\xF7\xE6\x50\x48\xBB\x2F\x62\x69\x6E\x2F\x2F\x73\x68\x53\x54\x5F\xB0\x3B\x0F\x05"

这样就又省出了1byte,把push rsp + pop rdi换成mov rdi, rsp或者索性在开头多pop rsi一次都可以。
最终exp:

shellcode2 = "\x5e\x5e\x31\xF6\xF7\xE6\x50\x48\xBB\x2F\x62\x69\x6E\x2F\x2F\x73\x68\x53\x54\x5F\xB0\x3B\x0F\x05"
payload = shellcode2+p64(shellcode_addr)

因地制宜

这个23bytes的shellcode真的没有办法了吗?
在搜索过程中发现有的shellcode使用了两字节的mov al, 59的指令,这样比起原来三字节的push 59, pop rax又能节省1bytes。
那本来为什么不用呢?因为这样的指令会使得原来的rax的高3字节保留下来。
可是我们这个程序有这样的顾虑吗?
注意到代码中:

return 0意味着什么?

ret前会为我们将rax清零!
因此这里我们也可以节省出1字节,同样的方法转换成栈空间,从而成功get shell~

有趣的Shellcode和栈相关推荐

  1. 64位虚拟机下asm()语法_一步步学写Windows下的Shellcode

    如何在WIndows下编写一个shellcode?为什么会问这个问题,前段时间在做win下的Exploit,但是都是使用大佬写的shellcode,无法实现个人的一些需求.而网络上编写shellcod ...

  2. shellcode加载器--从入门到放弃

    文章目录 重剑无锋--代码篇复现 1.C/C++(vs2019) (1).指针执行 shellcode放在data段 shellcode放在栈上,复制到堆上 shellcode放在web服务器上 使用 ...

  3. 关于简单的shellcode的学习

    题目(hackergame2019→shell骇客) 题目文件下载(提取码:emuy) chall1 对文件分析完发现只需要生成一个不超过0x200长度的shellcode填充栈即可 如果不了解she ...

  4. 同时替换栈中和.data中的Cookie突破GS

    文章是我之前发在吾爱破解论坛的,直接搬过来了.有问题大家可以直接提问. 最近刚刚接触漏洞调试逆向,希望能够将自己调试过程中的看法与大家分享,望大神们不要喷我.参考书籍就是有名的<0day> ...

  5. 浅谈2018年的MarTech技术栈

    MarTech越来越热,有时甚至成为一种营销社交术语,很多人高谈阔论,很多人迷茫困惑,很多人知道MarTech的缘起,却不知道未来,我也是算其中一个. 第一部分 MarTech和AdTech 经常有人 ...

  6. linux内核二当家,Linux PWN从入门到熟练(二)

    前言 上回说到,如何利用程序中system函数以及bin/sh字符串来进行pwn.这里我们会介绍,如何在栈可执行而system函数以及参数没有的情况下,如何自己布置payload进行pwn.此外,还提 ...

  7. Buuctf(pwn) ez_pz_hackover_2016 泄露栈地址,retshellcode;调试计算

    32位,开启了RELRO保护,堆栈地址随机化 没有开启nx保护,可利用写入shellcode来获取shell 一开始给我们输出了参数s的地址 strcmp函数: 两个字符串自左向右逐个字符相比(按AS ...

  8. 栈溢出笔记1.11 SafeSEH

    在上节写示例的过程中,我把要用到的POP+POP+RET指令写在了自己的一个DLL中.POP+POP+RET指令是很常见的指令,一般函数的末尾都是这种形式,因此,系统DLL中应该是有该指令的,比如nt ...

  9. 地址随机化 linux,GOT覆盖和Linux地址随机化

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 原理由于GOT表是可写的,把其中的函数地址覆盖为我们shellcode地址,在程序进行调用这个函数时就会执行shellc ...

最新文章

  1. 60 Permutation Sequence
  2. js获取select标签选中的值
  3. 20145231第四周学习笔记
  4. Redis之java操作篇(数据对象的存取)
  5. C++中的深拷贝和浅拷贝(详解)
  6. 2019年春季学习第七周学习总结
  7. JavaWeb开发模式
  8. macos 管理员权限 黑苹果_Mac OS X 黑苹果系统安装驱动Kext方法
  9. 无线路由器 tftp服务器怎么开启,水星路由器tftp服务器怎么开启
  10. linux安装nebula
  11. 关于语法节点Tree、类型Type和符号Symbol
  12. 写在2016的最后一周
  13. 编写lisp程序解一元二次方程_vb解一元二次方程代码
  14. java订单 并发_订单并发处理思路
  15. 适配器模式(Adapter)
  16. numpy之多维数组
  17. Linux工作站usb口无反应,usb接口没反应怎么办 usb接口没反应解决方法
  18. java 语法错误_java菜鸟提问:编译时异常和语法错误的区别?
  19. Elasticsearch:什么是相关性
  20. bzoj1599[Usaco2008 Oct]笨重的石子*

热门文章

  1. Eclipse 报错The method xxx of type must override a superclass method、Description Resource Path Locati
  2. Valgrind基本用法
  3. 虚拟主机可以运行java_下面哪种类型的文件可以在Java虚拟机中运行( ).
  4. 基于Bootstrap的后台管理系统模板。AceAdmin停更前最后的两个版本
  5. 陪诊服务系统源码,可以在线预约陪诊师的软件平台
  6. Sql Server char nchar varchar nvarchar 区别
  7. 先下手为强 Google桌面搜索出炉
  8. After Effects for Graphic Design After Effects for Graphic Design Lynda课程中文字幕
  9. 没有密码,如何清除PPT的限制编辑?
  10. [NLP] 实例讲解 N-gram语言模型 中 Good-Turning 平滑技术