练习IDA两年半

打开尘封已久的bugku,从题目中练习使用,现在都已经是新版本了 orz

入门逆向

运行baby.exe

将解压后的baby.exe拖到IDA里面

主函数中找到mov指令 可以看到这里就是flag

flag{Re_1s_S0_C0OL}

signin

下载附件

解压之后是sign_in.apk ,Android逆向我不会啊orz
丢到AndroidKiller 里面去
可以看到这里有一个checkpassword方法

不过我不知道怎么把这个直接跳过 估计是需要登录的时候直接绕过这个方法然后重打包
看到评论里面有的人用的是GDK https://github.com/charles2gan/GDA-android-reversing-Tool

GDA,一款用C++实现的强大的Dalvik字节码反编译器,具有分析速度快、内存磁盘消耗低等优点,对apk、dex、odex、oat、jar、class、aar文件的反编译能力更强。

GDK打开之后 牛逼啊

登录验证逻辑如下

private String getFlag(){
return this.getBaseContext().getString(0x7f0b0020);
}
private void showMsgToast(String p0){
Toast.makeText(this, p0, 1).show();
}
public void checkPassword(String p0){
if (p0.equals(new String(Base64.decode(this.getFlag().reverse(), 0)))) {
this.showMsgToast("Congratulations !");
}else {
this.showMsgToast("Try again.");
}
return;
}

接下来去找这个0x7f0b0020对应的值是多少
转换成十进制为

去找2131427360 这玩意,不过我直接搜索这个值找不到
手动查toString 看到在这里

所以这个值对应的是toString
GDK用起来卡卡的
toString 的值为 991YiZWOz81ZhFjZfJXdwk3X1k2XzIXZIt3ZhxmZ

按照规则 把字符串逆序 ZmxhZ3tIZXIzX2k1X3kwdXJfZjFhZ18zOWZiY199
然后base64解密,得到flag
flag{Her3_i5_y0ur_f1ag_39fbc_}

Easy_Re


额要是我知道我还运行干啥
我理解这里应该是会有一个比较操作 逆向的时候在比较操作的时候看flag值
IDA打开之后F5查看伪代码

输入的内容存储到v7变量中 然后跟v5进行对比,对比结果存储到v3中

scanf("%s", v7);
v3 = strcmp(v5.m128i_i8, v7);

所以真实的flag就在v5中,赋值操作在

v5 = _mm_loadu_si128((const __m128i *)&xmmword_413E34);

真实值在 xmmword_413E34,点击跟进

按 a 转译

获取flag

游戏过关

运行exe,看起来这个游戏好难

n是灯的序列号,m是灯的状态
如果第N个灯的m为1,则它点亮,否则它熄灭
起初所有的灯都关上了
现在你可以输入n来改变它的状态
但你应该注意一件事,如果你改变第N个灯的状态,第(N-1)个和第(N+1)个的状态也会改变
当所有灯亮起时,flag将出现
现在,输入n

乱输一通

获得flag zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
丢到IDA里面检查一下,这次的文件比较多 搜索flag字符串 alt+t

看到输出flag的界面

汇编代码如下

F5转换为C代码,去除掉一些干扰代码

int sub_45E940()
{
int i; // [esp+D0h] [ebp-94h]
char v2[22]; // [esp+DCh] [ebp-88h] BYREF
char v3[32]; // [esp+F2h] [ebp-72h] BYREF
char v4[4]; // [esp+112h] [ebp-52h] BYREF
char v5[64]; // [esp+120h] [ebp-44h] sub_45A7BE("done!!! the flag is ");
v5[0] = 18;
v5[1] = 64;
v5[2] = 98;
v5[3] = 5;
v5[4] = 2;
v5[5] = 4;
v5[6] = 6;
v5[7] = 3;
v5[8] = 6;
v5[9] = 48;
v5[10] = 49;
v5[11] = 65;
v5[12] = 32;
v5[13] = 12;
v5[14] = 48;
v5[15] = 65;
v5[16] = 31;
v5[17] = 78;
v5[18] = 62;
v5[19] = 32;
v5[20] = 49;
v5[21] = 32;
v5[22] = 1;
v5[23] = 57;
v5[24] = 96;
v5[25] = 3;
v5[26] = 21;
v5[27] = 9;
v5[28] = 4;
v5[29] = 62;
v5[30] = 3;
v5[31] = 5;
v5[32] = 4;
v5[33] = 1;
v5[34] = 2;
v5[35] = 3;
v5[36] = 44;
v5[37] = 65;
v5[38] = 78;
v5[39] = 32;
v5[40] = 16;
v5[41] = 97;
v5[42] = 54;
v5[43] = 16;
v5[44] = 44;
v5[45] = 52;
v5[46] = 32;
v5[47] = 64;
v5[48] = 89;
v5[49] = 45;
v5[50] = 32;
v5[51] = 65;
v5[52] = 15;
v5[53] = 34;
v5[54] = 18;
v5[55] = 16;
v5[56] = 0; qmemcpy(v2, "{ ", 2);
v2[2] = 18;
v2[3] = 98;
v2[4] = 119;
v2[5] = 108;
v2[6] = 65;
v2[7] = 41;
v2[8] = 124;
v2[9] = 80;
v2[10] = 125;
v2[11] = 38;
v2[12] = 124;
v2[13] = 111;
v2[14] = 74;
v2[15] = 49;
v2[16] = 83;
v2[17] = 108;
v2[18] = 94;
v2[19] = 108;
v2[20] = 84;
v2[21] = 6; for ( i = 0; i < 56; ++i )
{
v2[i] ^= v5[i];
v2[i] ^= 0x13u;
}
return sub_45A7BE("%s\n");
}

这里有个问题啊,就是v2和v5的长度不一致

v2的长度就是22,这样的话最后得到的结果是

少了一部分的flag,但是v3和v4的长度加起来是 32+2=34,再加上前面的22就是56,所以我们应该把v2 v3 v4组在一起 为啥这里看不出来 我感觉这里的C语言代码是有点问题
更新python脚本

v2=[123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99,123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1,117,126,0]
v5=[18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,89,45,32,65,15,34,18,16,0]
flag=""
for i in range(len(v2)):
flag+=chr(v2[i]^v5[i]^0x13) print(flag)

结果如下

换一个方式 使用动态调试 也就是掏出OllyDbg
使用中文搜索引擎

选择智能搜索 然后就可以看到

双击进入

这部分的入栈位置在这里

上转至 006A7AB4

上转调用位置为 006AF66C

这里的几个汇编指令我觉得需要解释一下
可以看到每一个jnz前面都有cmp,也就是比较失败就跳转到 006AF671

如果所有的比较都成功则调用call 方法,调用006A7AB4地址的方法
这里的逻辑很显然就是这里判断灯亮灯灭的判断(IDA中看见

所以我们将这里的jmp地址修改为call地址 不管输入 1-8 的哪个数字都能拿到flag了


右键复制到可执行文件 选择

保存为 ConsoleApplication7.exe,然后运行一下,输入 1,获取flag

Easy_vb

运行之后随便点点 好像没啥用

OD打开智能搜索

树林的小秘密

下载之后我的OD载入不了64位的程序 只能IDA了
shift + F12 搜索flag

看起来是pyinstaller打包的

用对应的工具去恢复源码,工具在这,点进去就是下载
https://nchc.dl.sourceforge.net/project/pyinstallerextractor/dist/pyinstxtractor.py

把工具和待反编译的exe放到一个目录下,然后运行

python pyinstxtractor.py easy_reverse.exe


生成了 easy_reverse.exe_extracted 文件,可以看到反编译的结果为

这里这个没有后缀的就是之前打包的python文件对应的pyc文件
这个时候打开123已经可以拿到flag了,base64解密

Timer(阿里CTF)

又是一个APK
GDA打开 搜索flag

跳转查看,如下

JNI编程?这么上流

这个位置load 了 so文件

所以其实flag在这个里面

但是so文件逆向我更不会了,只能看代码逻辑
初始化onCreate方法

protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main);
Handler handler = new Handler();
Runnable runnable = new MainActivity$1(this, this.findViewById(0x7f0c0051), this.findViewById(0x7f0c0050), handler);
handler.postDelayed(runnable, 0);
}

运行了这个方法

public void run(){
MainActivity$1 tthis$0;
this.this$0.t = System.currentTimeMillis();
this.this$0.now = (int)(this.this$0.t / 1000);
this.this$0.t = 1500 - (this.this$0.t % 1000);
this.val$tv2.setText("AliCTF");
if (((this.this$0.beg - this.this$0.now)) <= 0) {
this.val$tv1.setText("The flag is:");
this.val$tv2.setText("alictf{"+this.this$0.stringFromJNI2(this.this$0.k)+"}");
}
if (MainActivity.is2((this.this$0.beg - this.this$0.now))) {
tthis$0 = this.this$0;
tthis$0.k = tthis$0.k + 100;
}else {
tthis$0 = this.this$0;
tthis$0.k = tthis$0.k - 1;
}
this.val$tv1.setText("Time Remaining\(s\):"+(this.this$0.beg - this.this$0.now));
this.val$handler.postDelayed(this, this.this$0.t);
return;
}

OK 虽然看起来有点费劲
现在有四个参数

  • t
  • now
  • beg
  • k

now是当前时间戳
beg是启动APK的时候的时间,在

当然加了20万秒 所以如果破解不了的话就等着吧,虽然CTF比赛很快就要结束力
t 是一个取余时间值
k是计算的时间种子,最后会传到JNI方法里面去,所以我们如果直接改if语句是没用的,因为时间种子没有修改正确

所以这里我们有两个地方需要修改,一个是计算出正确的时间种子,一个是进入if语句,先从简单的进入if语句开始

把beg改成0就OK
不过好像GDK没有这个修改重打包的功能,使用AndroidKiller

把if-gtz修改为 if-lez,从判断大于零改为判断小于或等于零
接下来需要计算正确的K,抽离其中的关键因素
使用GDA反编译之后的代码看起来费劲,换成jd-gui
先使用dex2jar 把 classes.dex转换成 jd-gui可识别的jar包

然后使用jd-gui打开jar包,现在看起来就好多了

编写python脚本如下

now=0
beg=0+200000
k=0
def is2(n):
if n<=3:
if n > 1:
return True
return False
elif n%2==0 or n%3==0:
return False
else:
i=5
while i*i <= n:
if 0 == n%i or n%(i+2) == 0:
return False
i=i+6
return True while beg - now > 0:
if is2(beg-now):
k+=100
else:
k-=1
beg -= 1 print(k)

运行得到K值

k值为 1616384
修改代码 在这里直接把K强行赋值

回编译得到修改后的APK

连一下自己手机

adb install之后运行 就可以看到flag了

拿到flag

逆向入门

运行admin.exe???16位的应用程序

IDA打开感觉奇奇怪怪的,介素?

看起来类似010editer里面的格式,丢到wxmedit里面
一眼照片,这是逆向?服了

字符串丢到浏览器上 浏览器自动解码

扫码获取flag

OK现在逆向的前八题就做完了 再接再厉

END

建了一个微信的安全交流群,欢迎添加我微信备注进群,一起来聊天吹水哇,以及一个会发布安全相关内容的公众号,欢迎关注

加我拉你入群 黑糖安全公众号

BUGKU逆向reverse 1-8题的更多相关文章

  1. VK Cup 2016 - Round 1 (Div. 2 Edition) A. Bear and Reverse Radewoosh 水题

    A. Bear and Reverse Radewoosh 题目连接: http://www.codeforces.com/contest/658/problem/A Description Lima ...

  2. DDCTF2019逆向分析前俩题WriteUP

    DDCTF2019 笔者做了前俩道题.冷不丁过去一个月了.现在在此做一下WriteUp:题目链接: 1:题目1 2:题目2 reverse1:writeup: 1.程序打开后如下所示 2.查壳结果为U ...

  3. HDU 1062 Text Reverse(水题,字符串处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1062 解题报告:注意一行的末尾可能是空格,还有记得getchar()吃回车符. #include< ...

  4. codeforces 658A A. Bear and Reverse Radewoosh(水题)

    题目链接: A. Bear and Reverse Radewoosh time limit per test 2 seconds memory limit per test 256 megabyte ...

  5. HDU——1062Text Reverse(水题string::find系列+reverse)

    Text Reverse Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tot ...

  6. Bugku 逆向

    1.入门逆向 下载解压,在文件夹中打开命令行窗口执行一下:baby.exe 发现输出了一串字符,在将其放到IDA中然后是这样: 发现上面有一串输出和我们命令行窗口中的一样,但是下面为什么又多了一大溜东 ...

  7. bugku 逆向 take the maze

    看到如果判断正确之后 会生成一个png文件 直接用idc脚本生成: auto v,begin,end,dexbyte; v = fopen("flag.png", "wb ...

  8. bugku 逆向 love

    可以看到将输入先经过 sub_4110BE 这个函数进行加密 然后每一位加上下标本身 再和str2比较 正确就是right 点开加密函数: 关键语句就在这里 我们可以看到是算输入的字符按三个一组能分为 ...

  9. bugku的一道代码审计基础题:eval

    首先看到 include "flag.php",第一反应就应该是文件包含 直接先?hello=file:////etc, 然后啥也没 那就再检查一下代码,eval(var_dump ...

  10. 44个 Javascript 变态题解析 (上\下)

    第1题 ["1", "2", "3"].map(parseInt) 知识点: Array/map Number/parseInt JavaS ...

随机推荐

  1. 2021-12-10:64位的浮点数和64位的有符号整数,哪个能表示的数据个数多? A.整型多。 B.浮点型多。 C.与平台有关。 D.一样多。 来自qq群。

    2021-12-10:64位的浮点数和64位的有符号整数,哪个能表示的数据个数多? A.整型多. B.浮点型多. C.与平台有关. D.一样多. 来自qq群. 答案2021-12-10: 答案选A. ...

  2. 基于DevExpress的GridControl实现的一些界面处理功能

    DevExpress的GridControl控件能够提供很多强大的操作,其视图GridView能够通过各种设置,呈现出多种复杂的界面效果,本篇随笔探讨一些常见的GridControl控件及其GridV ...

  3. vue全家桶进阶之路11:计算属性

    Vue2 中的计算属性是指在组件中声明的计算属性,它们的值是根据其他数据计算得出的,并且会根据依赖数据的变化而自动更新.计算属性可以在模板中使用,与普通属性一样使用,但是它们具有以下优点: 缓存:计算 ...

  4. Python-查询所有python版本

    C:\Users\liujun>where pythonD:\Python\Python310\python.exeD:\Python\Python38\python.exeC:\Users\l ...

  5. odoo部署安全性问题

    本文档描述在生产中或在面向Internet的服务器上设置Odoo的基本步骤.它是在安装之后进行的,对于没有在internet上公开的开发系统来说,它通常不是必需的.警告如果您正在设置公共服务器,请务必 ...

  6. 实用的windows快捷键

    Alt+F4 关闭窗口 win+D 显示桌面 win+Tab 切换窗口 Alt+Tab 应用之间的切换 win+E 打开我的电脑 Ctrl+Shift+Esc 打开任务管理器 Home 回到行首 En ...

  7. React组件三大属性state,props,refs

    1. React组件定义 1.1 函数组件(Function Components) 函数组件是一种简单的定义组件的方式,通过一个JavaScript函数来定义组件.函数接收一个props对象作为参数 ...

  8. 探秘高逼格艺术二维码的制作过程-AI绘画文生图

    前几天看到几个逼格比较高的二维码,然后自己动手做了一下,给大家看看效果: 1.文生图(狮子): 2.文生图(城市): 下边将开始介绍怎么做的,有兴趣的可以继续读一读. 这里使用的AI绘图工具是Stab ...

  9. Win10激活步骤、密钥key

    统安装完毕后,首先以Win+R打开CMD命令行窗口,按下Win+X,选择命令提示符(管理员). Win10企业版 用户举例请依次输入: slmgr /ipk NPPR9-FWDCX-D2C8J-H87 ...

  10. Windows 交叉编译之 make

    以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/w8YV_TUb4QwsgChu3AspHg Make 是什么 Mak ...