171022 逆向-Xp0intCTF(Re)
来源:互联网 发布:解决80端口被占用 编辑:程序博客网 时间:2024/06/07 22:54
1625-5 王子昂 总结《2017年10月22日》 【连续第387天总结】
A. Xpoint-暨南大学校赛
B.
今天有点晚了╮(╯_╰)╭推迟到零点结束,最后正好赶着把盲水印给搞定了
明天还有课,今天就先把Re的WP写好吧~明天有空的话写下misc的~
这次做题都忘了先查壳,还好一个壳都没有233
3倍
exe直接拖入IDA反编译
找不到入口点和关键函数,直接Shift+f12查找字符串
一眼就看到了Yes和No,双击进入IDA View
然后选中字符串,按x查看交叉引用,向上溯源到调用的地方:
再次双击,就来到了关键函数:
结构非常简单,就是接收int类型的输入,要求乘3后等于0x05C3F6EA
不过怎么说它也是个题目,要是真的一除就出来了也太简单了不是~
计算器计算一下,发现无法整除3
这个套路正好前两天在Reversing.kr上做过,轻车熟路
无法整除3怎么办?
说明真正得数不是0x05C3F6EA, 而是有部分值被溢出抛弃了
3*v5>2**64,溢出部分就没有记录了
那么穷举抛弃部分即可
python3脚本:
i = 1while(1): p = i*0x100000000 + 0x5C3F6EA if(p%3 == 0): break else: i += 1print(p//3)
瞬间得到输出,提交给程序确认可以返回Yes
题目还提示要以字母形式输出,那么整数转字符用什么方法?当然是hex啦:
在原来的脚本上添加
print(bytes.fromhex(hex(p//3)[2:]))
即可
combo
下下来发现是个APK
拖入APK改之理或者AndroidKiller之类的反编译工具
在MainActivity中就能看到JAVA源码了:
函数很简单,Click事件要求点击201710次
当满足条件的时候将showFlag控件的文本改为2131099682
很明显这并不是flag,而是一个资源的id
这个类中没有相关的说明,我们再去别的类找找
然后在R.Class中查找到了对应的内容(逆向要善用Ctrl+F哦)
看到了变量名是galf,就是flag的逆序嘛,那么很明显关键的内容还藏着呢,接着找~
Class里看完了没有找到东西,我们去APK的整个资源里找一下呗
看,这样就搜索到了~
这种简单的方法仅针对字符串全部明码(硬编码)存放在数据中的
除此以外还可以动态调试APK,修改计数变量的值,令它直接改为201710就能显示flag了,相关过程我之前的总结有写过,就不再赘述了~
还有一种方法,就是直接修改源码,重新生成APK来运行
注意不能修改java源码哦,只能修改Android的汇编-Smali代码:
if(clkAcount==201710)的对应代码在这里
if-ne表示v0和v1不等的话就跳到cond_2处
v1在上一行进行了定义,v0在更上一行,可以看到就是clkAcount变量
爆破这行,将if-ne改为if-eq, 将v0改为v1等等方法都行,只要让它恒成立就OK了
保存后重新编译生成APK,安装运行,轻轻一点即可:
xor
这题就是最简单的入门题了
拖入IDA反编译,跟之前一样查找字符串-查看交叉引用
可以看出,Str1是接收输入的变量,之后与Str2进行比对,相同即通过
Str2来自于sub_411253的修改:
很简单,a1就是Str2的指针,相当于Str2[i] = i ^ data[i];
data是一个硬编码的数组,通过IDC脚本Dump出来脚本生成一下即可:
python3脚本:
d = [102, 109, 99, 100, 127, 99, 55, 117, 123, 125, 85, 120, 120, 104, 55, 46, 49, 108]for i in range(18): print(chr(i ^ d[i]), end='')
密码生成器
这题稍微有点复杂了~
提示说是依靠时间生成的密码,只有一个不完整的源码
解压出来发现没有exe后缀名,用记事本/十六进制查看器打开发现文件头标识是ELF
说明是Linux下的可执行文件哦
先拖入IDA反编译吧
这次源码直接就在main函数中乖乖等我们看了呢
time.h相关的函数百度查一下就能得到说明
循环生成密码,可以看出来v8不断被赋值,应该就是密码了
所以说缺少的部分就是不打印了嘛╮(╯_╰)╭
注意这题有一个关键攻击点就是随机函数rand()
它其实是伪随机函数,程序依靠一个算法以srand(seed)的seed来建立一个序列,每次rand都会从中读出一个数字
换句话说,只要seed相同,rand读出的数字也会是完全相同的
这也是提示说密码生成来自时间的原因啦
具体算法不用太关心,直接复制粘贴到C++编译器里就行咯
为什么要用C++编译器而不用Python呢?
因为涉及随机数发生器,乱搞环境会出问题的呀!
(才不是因为我懒得把IDA的C++生成代码转成Python代码了呢~)
注意Byte*(i + 0x804A030)实际上就是指针+下标的数组访问法
因此byte_0x804A030数组还是要Dump出来,复制过去滴
#include <stdio.h>#include <stdlib.h>#include <time.h>//2017年10月13日22时08分57秒//linux的随机数序列不同,必须在linux下运行void main(){ time_t p; struct tm* t;//时间结构体指针 int i; int data[12]={33, 167, 153, 80, 119, 18, 35, 57, 97, 2, 160, 72};// 复制过来的数组 char v8[20]={0}; printf("%s\n", v8); p = time(NULL);//得到现在时间 //printf("%d\n",p); t = localtime(&p);//将时间转换成结构体 t->tm_year = 2017 - 1900;//按照提示中所给的时间写入 t->tm_mon = 10 - 1; t->tm_mday = 13; t->tm_hour = 22; t->tm_min = 8; t->tm_sec = 57; p = mktime(t);//将结构体转换回秒数 printf("%d\n",p); srand(p);//初始化随机数发生器 for ( i = 0; i <= 11; ++i ) { for ( (v8[i]) = rand() % 80 + data[i]; (v8[i]) <= 64; (v8[i]) += 26 ) { ; } while ( (v8[i]) > 122 ) (v8[i]) -= 26; if ( (v8[i]) > 90 && (v8[i]) <= 96 ) (v8[i]) -= 43; } printf("%s\n", v8);//输出密码 system("pause");}
代码运行好了以后生成的密码我怎么提交都不对,检查来检查去也没找到问题
最后想起来源程序是ELF格式的,可能在Linux环境下有所不同?
源码复制到虚拟机中gcc编译好了一运行,嘿,密码还真不一样~
提交,完成
so fun从提示来看应该是加壳了
我上次接触安卓加壳还是做前年的国赛的时候了……早就忘光啦,过两天有空再搞吧~
总体来说这次的难度适中,re300和re250稍微有些难度但还挺好玩儿的~
win下的re做起来渐渐也得心应手了呢
(ELF和Android的就要命了)
C. 明日计划
reversing.kr
- 171022 逆向-Xp0intCTF(Re)
- 171021 逆向-Xp0intCTF(re300)
- 171023 逆向-BDCTF(Re)
- 171104 逆向-上海CTF(Re)
- 171125 逆向-湖湘杯RE
- 170920 逆向-CTF练习平台(RE-love)
- 171008 逆向-实验吧ctf(300re-bin)
- 171009 逆向-实验吧ctf(250re-apk)
- Xp0intCTF 2017 writeup
- 南邮CTF逆向题第一道Hello,RE!解题思路
- 正则表达式(RE)
- RE
- re
- re
- RE
- re
- re
- re
- 内存计算-SPARK
- mysql 外键
- shell脚本中执行python脚本并接收其返回值的例子
- [BZOJ4166]月宫的符卡序列-Manacher算法-Hash表
- RSA加密算法
- 171022 逆向-Xp0intCTF(Re)
- 用for循环实现在控制台打印一个矩形
- 企业实战之Spring拦截器《统一参数校验》
- 【未完成】线性微分方程与常数变易法
- 冒泡和选择排序的理解
- OpenShift Origin v3.7 安装-手工部署All-In-One Server
- 简单的外键链接
- 面试系列:无序的子数
- LeetCode:Task Scheduler