吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6318|回复: 26
收起左侧

[CTF] 【极客巅峰】InterestingPointer

[复制链接]
whklhh 发表于 2018-7-22 22:26
本帖最后由 whklhh 于 2018-7-23 02:46 编辑

本场比赛只有3个逆向,前两个还都是比较水的简单题,最后一题虽然玩脱了但还算是有意思,发出来学习交流下=-=

Interesting Pointer

分析

一堆变量初始化直接放过,可以看到它读入data文件,所有内容放到了buff中
接着判断strlen和ftell给出的文件结尾是否相等,相等则结束
也就意味着文件中必须存在\x00来截断strlen

注意文件读取几乎晚于所有变量初始化,因此这里存在溢出点

处理过程如下

依次调用3个func,将返回值放在buff1、2、3中,要求buff[3]的值为0

3个Func的功能依次为exchange(buff[x], buff[y]), calc1(buff[x], buff[y]), calc2(buff[x], buff[y])

exchange固定
return 1
calc1具体过程为:
return abs(x + y) - abs(x) - abs(y) + 2
calc2具体过程为:
return abs(x) + abs(y) - abs(x + y) + 2

而三次函数的参数和返回值分别是
x = 3
y = 4
buff[1] = exchange(buff[x], buff[y])
buff[2] = calc1(buff[1], buff[2])
buff[3] = calc2(buff[2], buff[3])

这里我把x和y分离出来写的原因是,中间读入可以覆盖掉初始化,从而控制exchange的两个参数

首先如果不溢出的话,calc2想要返回0可以通过0x7fffffff和0x80000001来实现

由|x|+|y|>=|x+y|,即|x|+|y|-|x+y|+2>=2可知正常情况下无解
但是|x|+|y|-|x+y|+2==0x1 00000000却是有解的,令x、y互为相反数,则|x|==|y|==0x7fffffff

而calc1却不可能制造出这两个返回值,因此无解

calc1也很容易返回0, 有且仅有令两个操作数其中之一为-1即可

是吗?
令x, y都为正数, x+y=0x80000001则|x+y|=0x7fffffff,|x|+|y|-|x+y|正好就是2

返回buff[3]为0后,通过之前保存的buff[3]和buff[5]来得出flag
这里其实可以大概猜出来,关键的两个变量就是buff[3]和buff[5]了
然而比赛的时候我没注意这里23333导致从别的角度去考虑造成一堆多解

期望解

通过exchange交换calc1和calc2的位置,同时控制buff[3]为-1,则可满足条件
即构造data为
b"1"*(20+4*3) + b"\xff\xff\xff\xff" + b"\x07\x00\x00\x00" + b"\x08\x00\x00\x00"

生成flag的关键参数就是-1和8

非预期解

交换顺序非预期

这是最容易看到的多解,7和8两个数作为交换参数,当然8和7也是可行的,而生成flag提取的却只有最后一个参数
这个只有1种情况,试一下也可以接受

calc1的参数非预期

利用之前所说的calc1的溢出计算,使x和y都为正数的情况下和为0x80000001,则可同样使返回值为0
例如构造data为
b"1"*(20+4*3) + b"\xff\xff\xff\x7f" + b"\x07\x00\x00\x00" + b"\x08\x00\x00\x00"

通过交换过后的calc2来获得其中一个参数,由于exchange返回值只为1,从而可知calc2可获得的正数结果只有2
那么对应只要控制buff[3]为0x7fffffff即可

这样产生了2个多解

exchange的参数非预期

既然可以交换,凭什么非要交换calc1和calc2?
在buff前面有那么多可控字段,完全可以在其中填充上一个函数地址,然后通过exchange将其与calc2的指针变量交换,这个函数地址可以是calc1,还可以是随便什么返回0的函数

例如构造data为
b"\x00"*(20+4*3) + b"\xe8\x1f\x40\x00" + b"\x08\x00\x00\x00" + b"\x03\x00\x00\x00"

这里是利用strlen配合头部为'\0'从而返回0的示例

由于该程序没有ASLR,因此地址全部固定

这种情况下产生的多解就多了去了,一方面交换目标可以随意放置,即使在限制长度的情况下每个交换函数也有前面4个位置可以选择
而更关键的是此种情况下校验通过与否根本与第三个参数无关,因此生成的flag完全没有意义,硬要说的话每个buff[5]都有0x100000000个buff[3]可以组合

函数指针覆盖非预期

这个是最容易想到的,也是我最早提交的多解
反正都能溢出,凭什么还要通过exchange函数

例如构造data
b"1"*(20+4*3) + b"\xffffffff" + b"\x00"*(2*4) + b"\x97\x13\x40\x00" + b"\x97\x13\x40\x00"

直接将calc2处的指针修改为calc1
具体情况与上面exchange的情况相同,只不过不用通过exchange多此一举,缺点就是长度会长一些

总结

总体来说基本上是一个pwn题改的逆向,单纯题目可以说挺有意思,作为赛题而言非预期过多还不算就有点坑人了..

如果把exchange中改为单向赋值就能限定住交换参数的顺序了,不过这个有符号数的溢出还是有点尴尬的23333
另一方面如果能提前说明输入要求最短也还算勉强可以接受,我觉得把函数指针放到全局变量去避免被覆盖会好点儿~

期待有dalao能找到更多的非预期发出来交流~

Interesting Pointer.rar

8.71 KB, 下载次数: 5, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 9威望 +1 吾爱币 +20 热心值 +9 收起 理由
Hmily + 1 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yypE + 2 + 1
154675361 + 1 + 1 谢谢@Thanks!
Pizza + 2 + 1
小小小英雄啦 + 1 + 1 用心讨论,共获提升!
zhh4827 + 1 + 1 热心回复!
微若清风 + 1 + 1 谢谢@Thanks!
kingkiller + 1 + 1 用心讨论,共获提升!
糖果味 + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wangkai558 发表于 2018-7-23 09:50

谢谢楼主  多多交流 就可以进步  我跟着学习下  谢谢
月柏柏 发表于 2018-7-22 22:43
A羽飞 发表于 2018-7-22 22:44
zhuzhu421 发表于 2018-7-22 23:34
谢谢楼主  多多交流 就可以进步  我跟着学习下  谢谢
蔚蓝色 发表于 2018-7-23 07:42
emmmm看不懂
dazhuangzhuang 发表于 2018-7-23 09:15
没看懂干什么用
风的季节oil 发表于 2018-7-23 09:41
硬是看不懂啊,尴尬了......
linclon 发表于 2018-7-23 10:17
哦,不错不错,学习一下思路
头像被屏蔽
a1844390 发表于 2018-7-23 10:48
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-26 18:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表