Bctf Zhongguancun分析

written by ling

一、找溢出点

分析程序,程序对手机或者表都定义了一个如下的结构体,其中前4个字节为一个虚表指针。一共可以添加16次这样的结构体,都布局在堆中。

Struct item
{
         +0dword vtable;
         +4 charname[32];
         +36char description[80];
         +116dword price;
         +120dword type;
}

同时,在生成menu时,程序会申请固定大小0xb18的空间来存放menu信息。经过测试,发现在最大可能填充item信息的情况下,menu会产生溢出,溢出刚好能覆盖item的前6个字节,也就是可以改写掉item的虚表。

 

二、失败的利用

程序的虚表中有2个函数指针,不过在调用这2个函数指针之前,都对虚表进行了如下判断。往虚表地址写数据失败,即虚表地址是不可写的。

 

既然虚表地址不可写,那就只能在只读代码段中找函数指针。

第一处函数指针是一个switch-case表,经分析发现这块进去之后能改写ebp-8处的值,而在调用虚表的函数中ebp-8处的值并没有什么意义。所以这儿应该是不行的。


剩下的函数指针就是原来的虚表了,不过因为虚表中是有2个函数指针的。可以通过虚表指针,让程序在调用本应该第一个函数指针时调用第二个函数,或者调用第二个函数的地方调用第一个函数。


 

分析下虚表地址使用的地方。

第一处函数指针:其中第二个参数是要买的个数,是用户可控的。对应的函数是计算打折的。


第二处函数指针,这是在生成menu时,生成单个item的信息时调用的,看了下参数基本不太可控。


对应的函数是往参数2所在地址生成一串字符串,其中字符串的后部分(description)是用户可控的。


所以当时想到了通过修改虚表在调用第一个虚表指针的地方调用sub_80492fe,可以往指定内存写入一段数据。

 

不过数据段中got表位于data段的最开始位置,而这样利用中能控制的数据在字符串的后面。所以没法直接往got表中写入固定的值。

同时,因为aslr的关系,所以根本不知道system的加载地址。而这样利用很难做到同时泄露库地址+改写got表。

 

所以到比赛最后也没想出利用方法。

 

三、赛后学习

比赛后,看了国外某队公布的利用脚本,发现它改写的是通过上面的sprintf改写了一个数据指针。


而这个数据指针中存放的是当前用户拥有多少钱。

在进行购买时,进行了如下操作:其中*(a1+116)是当前物品的价格,v1是购买的数量,这2个数据都是攻击者可控的。

因此如果将got表的地址(如sprintf)指向该数据指针。如果*(a1+116) * v1 与 offset(system-sprintf)的值相等,那么通过下列函数直接就可以将sprintf在got表中的地址改写成system的地址,之后就可以拿下shell了。


Exp下载地址:https://gist.github.com/Idolf/99ffa3c5f76165f77b19


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值