-
-
[原创] 2019看雪CTF 晋级赛Q1 第一题
-
发表于: 2019-7-30 17:56 4440
-
拿到这个东西 ,打开看是有界面的程序
我们在输入框中输入一串字符 单击验证可以看到 弹出了messagebox
心中窃喜。猜想流程。Strcmp 输入的str 正确的str
成立 –》成功 不成立-》加油
是有字符串的
把程序拉入 ida
按照上面步骤 单击搜索,文本
在弹出的文本框中 输入加油 单击确定
来到
这个界面注意红色箭头 那一行 那里就是我们搜到的字符串。
我们 单击红色箭头 指向的 蓝色光标那里 就是 sub4017b0 那里是可以点击的
我们双击它 来到
这个函数。如果你的是显示的汇编代码没有图片 可以在ida里单击空格键 变为有图片
到这一步 验证了我们的猜想 这里应该是 strcmp 比对失败之后走的流程
我们把光标放到 箭头那里 会出现黄色框 注意不要双击
然后按下键盘上的x 键
会出现 这个界面 大概意思是那里调用了这个函数。
我们先选择第一个 点确定过去
可以看到这个流程图 看到这个流程图。 感觉到 dia 的好
用以上图片 看到 上面已经印证了我的猜想。 用strcmp 判断 str输入 和str正确
成功调用call cg 不成功调用sub_4017b0
我们把光标放在 call cg 这个函数上单击过去
果然没错 我很高兴
注意:这个call cg 是我自己改的名字 他来源的名字为sub_一串数组
返回上一步
来到这张流程图
这里应该就是我们分析的关键了 我们把光标放到 loc_401857这个方块里
按下F5
显示出伪代码 看到这里 大概看了一下。猜想 是把我们输入的值 判断赋值到buff里去
再和 KanXueCTF2019JustForhappy 进行比较
还出现一个数组 值为 abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ 62
关键:
这里分析很久。发现 while 判断了 输入的值必须小于62 且大于等于0
这里我踩坑了。
如果第一个值为 K 那么 在ASCII 表里为75 直接判断失败调用失败的代码了。
这里产生了两个问题。
第一 这是是不是我输入的值
第二 这里的值是哪里来的。
然后我仔细分析了 这段代码
得出结论 (1)是用A1 这个数组 。
(2)这里应该是核心 核心应该有几处。这里是核心之一
理顺思路。我必须向上去找A1的来源
切换到图片窗口 来到函数头部
单击这个地方 这个地方可能是 sub_一串数组 这样的名字。这里的名字是改的名
单击键盘上的x
显示出调用地方。 我们点击确定过去看
到了这里
我们在这里按下F5
来到这里一切都明白了。我们输入的数 得在这里做一次转换
那么分析明白这里 这题就解出来了。
我是感觉很兴奋的
马上上手分析这里。
以下为关键:
if 判断一个数是否落在 0-9之间
是 str【i】-48 减掉ASCII值 拿到数 存到 v5数组里 v5 数组最大 25
否进入下层 判断
判断 这个数 是否落在 a-z 之间
是 str【i】-87 拿走这个数 减掉ASCII值拿到数 存到 v5数组里 v5 数组最大 25
否进入下层 判断
判断这个数 是否落在 大A-大Z 之间
是【str】-29 拿走这个数 减掉ASCII值拿到数 存到 v5数组里 v5 数组最大 25
否 直接判断失败 进入函数sub_4017B0(); messagebox 输出错误 调用TerminateProcess 结束
----------------------------------------------------------------------------------------------
这里告诉我们 v5 数的范围为 0-9 10-35 36-61 也就是 我们输入的数转换之后得 v5 //此为重要依据
v5里数的范围为 0-61
------------------------------------------------------------------------------------------------
循环遇到\0 循环退出
call sub_4017f0 v5 作为参数传入
来到 int __cdecl sub_4017F0(int a1)
a1的来源终于知道了。
如图上函数 可以看见流程
是用 a1 去查 abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ 62 //这个数组
然后把值 写入临时buffer 在比对查出来的数 是否为 KanXueCTF2019JustForhappy
-------------------------------------------------------------------------------
拿出我们上面找到的范围表 v5 数的范围为 0-9 10-35 36-61 //凭据
------------------------------------------------------------------------------
(1)abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ
我们开始逆推 一个K 在数组中的位置为 19 落在 第二个判断 也就是
判断 这个数 是否落在 a-z 之间
是 str【i】-87 拿走这个数 减掉ASCII值拿到数 存到 v5数组里 v5 数组最大 25 //证据
否进入下层 判断 // 证据
-------------------------------------------------------------------------------
也就是 第一个数是字母 a-z 之间 转换之后的数必须为19 进行逆推 19+87 ==106 拿出ASCII码表 对照为 j
确定第一个数为j
(2)abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ
继续照上面步骤来
-------------------------------------------------------------------------------
拿出我们上面找到的范围表 v5 数的范围为 0-9 10-35 36-61 //凭据
------------------------------------------------------------------------------
第二个数 为a 在数组中的位置为 0 落在我们的凭据 第一个范围之间 0-9 拿出第一个判断的证据
-----------------------------------------------------------------------------------------
if 判断一个数是否落在 0-9之间 //证据
是 str【i】-48 减掉ASCII值 拿到数 存到 v5数组里 v5 数组最大 25 //证据
否进入下层 判断 //证据
-----------------------------------------------------------------------------------------
逆推 0+48==48 拿出ASCII码表 对照为 0
确定第二个数 为0
(3)abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ
继续第三个数 n 在数组中的位置为27 拿出凭据
-------------------------------------------------------------------------------
拿出我们上面找到的范围表 v5 数的范围为 0-9 10-35 36-61 //凭据
------------------------------------------------------------------------------
落在 第二个范围 10-35之间
拿出证据
判断 这个数 是否落在 a-z 之间 //证据
是 str【i】-87 拿走这个数 减掉ASCII值拿到数 存到 v5数组里 v5 数组最大 25 //证据
否进入下层 判断
逆推他== 27+87== 114 拿出ASCII码表 对照为r
到此三个数已经确定为 j0r 照此方法
(1)从KanXueCTF2019JustForhappy 以此取数
(2)从abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ 62 取得位置
(3)查找范围: 拿出我们上面找到的范围表 v5 数的范围为 0-9 10-35 36-61 //凭据
(4)查找逆向结果:
if 判断一个数是否落在 0-9之间
是 str【i】-48 减掉ASCII值 拿到数 存到 v5数组里 v5 数组最大 25
否进入下层 判断
判断 这个数 是否落在 a-z 之间
是 str【i】-87 拿走这个数 减掉ASCII值拿到数 存到 v5数组里 v5 数组最大 25
否进入下层 判断
判断这个数 是否落在 大A-大Z 之间
是【str】-29 拿走这个数 减掉ASCII值拿到数 存到 v5数组里 v5 数组最大 25
否 直接判断失败 进入函数sub_4017B0(); messagebox 输出错误 调用TerminateProcess 结束
(5)逆推结果+上 48||87||29
(6)查找拿出ASCII码表 对照
拿到正确答案 用以上步骤得到的答案为 j0rXI4bTeustBiIGHeCF70DDM
做完这题 感觉整个人精神气爽。能飞起来
第一次用dia+第一次做这种题
得到收获。我的思路可以驾驭这种题。关键是工具的熟练使用
不然再好的思路 再懂运行机制 不能用工具去实践我的想法也是不行的
通过这次 发现了ida的好 熟悉了ida 的操作。
想通过本文学到一点东西的。如果有看不懂的地方可以回复(步骤 或者流程) 我可以回答你 我也是第一做这种题
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课