首页 > 其他分享 >BUGKU逆向reverse 1-8题

BUGKU逆向reverse 1-8题

时间:2023-08-21 21:44:39浏览次数:41  
标签:逆向 BUGKU reverse 16 32 flag v2 v5 65

练习IDA两年半

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

入门逆向

运行baby.exe
image.png
将解压后的baby.exe拖到IDA里面
image.png
主函数中找到mov指令 可以看到这里就是flag
image.png
flag{Re_1s_S0_C0OL}

signin

下载附件
image.png
解压之后是sign_in.apk ,Android逆向我不会啊orz
丢到AndroidKiller 里面去
可以看到这里有一个checkpassword方法
image.png
不过我不知道怎么把这个直接跳过 估计是需要登录的时候直接绕过这个方法然后重打包
看到评论里面有的人用的是GDK https://github.com/charles2gan/GDA-android-reversing-Tool

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

GDK打开之后 牛逼啊
image.png
登录验证逻辑如下

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对应的值是多少
转换成十进制为
image.png
去找2131427360 这玩意,不过我直接搜索这个值找不到
手动查toString 看到在这里
image.png
所以这个值对应的是toString
GDK用起来卡卡的
toString 的值为 991YiZWOz81ZhFjZfJXdwk3X1k2XzIXZIt3ZhxmZ
image.png
按照规则 把字符串逆序 ZmxhZ3tIZXIzX2k1X3kwdXJfZjFhZ18zOWZiY199
然后base64解密,得到flag
flag{Her3_i5_y0ur_f1ag_39fbc_}
image.png

Easy_Re

image.png
额要是我知道我还运行干啥
我理解这里应该是会有一个比较操作 逆向的时候在比较操作的时候看flag值
IDA打开之后F5查看伪代码
image.png
输入的内容存储到v7变量中 然后跟v5进行对比,对比结果存储到v3中

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

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

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

真实值在 xmmword_413E34,点击跟进
image.png
按 a 转译
image.png
获取flag

游戏过关

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

乱输一通
image.png
获得flag zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
丢到IDA里面检查一下,这次的文件比较多 搜索flag字符串 alt+t
image.png
看到输出flag的界面
image.png
汇编代码如下
image.png
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的长度不一致
image.png
v2的长度就是22,这样的话最后得到的结果是
image.png
少了一部分的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)

结果如下
image.png

换一个方式 使用动态调试 也就是掏出OllyDbg
使用中文搜索引擎
image.png
选择智能搜索 然后就可以看到
image.png
双击进入
image.png
这部分的入栈位置在这里
image.png
上转至 006A7AB4
image.png
上转调用位置为 006AF66C
image.png
这里的几个汇编指令我觉得需要解释一下
可以看到每一个jnz前面都有cmp,也就是比较失败就跳转到 006AF671
image.png
如果所有的比较都成功则调用call 方法,调用006A7AB4地址的方法
这里的逻辑很显然就是这里判断灯亮灯灭的判断(IDA中看见
image.png
所以我们将这里的jmp地址修改为call地址 不管输入 1-8 的哪个数字都能拿到flag了
image.png
image.png
右键复制到可执行文件 选择
image.png
保存为 ConsoleApplication7.exe,然后运行一下,输入 1,获取flag
image.png

Easy_vb

运行之后随便点点 好像没啥用
image.png
OD打开智能搜索
image.png

树林的小秘密

下载之后我的OD载入不了64位的程序 只能IDA了
shift + F12 搜索flag
image.png
看起来是pyinstaller打包的
image.png
用对应的工具去恢复源码,工具在这,点进去就是下载
https://nchc.dl.sourceforge.net/project/pyinstallerextractor/dist/pyinstxtractor.py

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

python pyinstxtractor.py easy_reverse.exe

image.png
生成了 easy_reverse.exe_extracted 文件,可以看到反编译的结果为
image.png
这里这个没有后缀的就是之前打包的python文件对应的pyc文件
这个时候打开123已经可以拿到flag了,base64解密
image.png
image.png

Timer(阿里CTF)

又是一个APK
GDA打开 搜索flag
image.png
跳转查看,如下
image.png
JNI编程?这么上流
image.png
这个位置load 了 so文件
image.png
所以其实flag在这个里面
image.png
但是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的时候的时间,在
image.png
当然加了20万秒 所以如果破解不了的话就等着吧,虽然CTF比赛很快就要结束力
t 是一个取余时间值
k是计算的时间种子,最后会传到JNI方法里面去,所以我们如果直接改if语句是没用的,因为时间种子没有修改正确

所以这里我们有两个地方需要修改,一个是计算出正确的时间种子,一个是进入if语句,先从简单的进入if语句开始
image.png
把beg改成0就OK
不过好像GDK没有这个修改重打包的功能,使用AndroidKiller
image.png
把if-gtz修改为 if-lez,从判断大于零改为判断小于或等于零
接下来需要计算正确的K,抽离其中的关键因素
使用GDA反编译之后的代码看起来费劲,换成jd-gui
先使用dex2jar 把 classes.dex转换成 jd-gui可识别的jar包
image.png
然后使用jd-gui打开jar包,现在看起来就好多了
image.png
编写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值
image.png
k值为 1616384
修改代码 在这里直接把K强行赋值
image.png
回编译得到修改后的APK
image.png
连一下自己手机
image.png
adb install之后运行 就可以看到flag了
a28b2a12db6814e473c870ace256c42.jpg
拿到flag

逆向入门

运行admin.exe???16位的应用程序
image.png
IDA打开感觉奇奇怪怪的,介素?
image.png
看起来类似010editer里面的格式,丢到wxmedit里面
一眼照片,这是逆向?服了
image.png
字符串丢到浏览器上 浏览器自动解码
image.png
扫码获取flag

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

END

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

标签:逆向,BUGKU,reverse,16,32,flag,v2,v5,65
From: https://www.cnblogs.com/Cl0ud/p/17647167.html

相关文章

  • 逆向 | 简单调试器检测&调试器进程检测、虚拟机进程检测、启动路径检测、计算机名检测
    逆向|简单调试器进程检测、虚拟机进程检测、启动路径检测、计算机名检测写在自己书里的代码,丢一份到blog。简单调试器检测:#include<stdio.h>#include<windows.h>//定义枚举值constintProcessDebugPort=0x7;constintProcessDebugObjectHandle=0x1e;constint......
  • 【安卓】安卓逆向-初识0x0
    环境搭建面具(magisk)介绍Magisk是一套用于定制Android的开源软件,支持高于Android5.0的设备关于面具有如下的优点:MagiskSU:为应用程序提供root访问权限Maisk模块:通过安装模块修改只读分区MagiskHide:从根目录/系统完整性隐藏面具(防止一些软件的检查)MagiskBoot:目前最完......
  • 逆向
    逆向实战演示使用工具:1.exeinfo:简单的查壳软件2.IDA:IDA是一款交互式反汇编工具,其功能十分强大,支持多操作系统、多处理器下的二进制程序的反汇编分析,并且可以和使用者进行交互来提升处理效率。3.CheatEngine(ce):CheatEngine一款内存修改软件,功能十分强大,可以轻......
  • 【web_逆向11】JS处理RSA加密
    JS中RSA加密有两套逻辑1、网易的那种.->加密的结果每一次都是一样的;这种没有办法使用python来完成setMaxDigits()RSAKeyPair()encryptedString()2、某网校的rsa加密->加密的结果每一次都是不一样的;和python的Crypto是相通的.而用js完成超级简单.newJSEncrypts......
  • 【web_逆向10】非对称加密之RSA
    非对称加密非对称加密.加密和解密的秘钥不是同一个秘钥.这里需要两把钥匙.一个公钥,一个私钥.公钥发送给客户端.发送端用公钥对数据进行加密.再发送给接收端,接收端使用私钥来对数据解密.由于私钥只存放在接受端这边.所以即使数据被截获了.也是无法进行解密的.常见......
  • 基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护
    基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护传输数据-编码型&加密型等传输格式-常规&JSON&XML等密码存储-Web&系统&三方应用代码混淆-源代码加密&逆向保护加密:1.常见加密编码进制等算法解......
  • reverse_re3
    main函数点击重要函数对if里面的数字按r键,使其从ASCII码转为字符发现wasd四个关键的移动方向键,判断为迷宫问题判断应该是要次数为2,即次数++3(从0开始计数)次才会有flag点进一开始先进入的函数函数出现两个循环,应该是迷宫的大小点进数组dword_202AB0发现没什么......
  • 【web_逆向09】AES加密逆向实战
    目标网站话不多说,直接干:https://www.XXXX.com/rank_m/c7/,可以联系本人微信号:wxid_ps0bm4kbsl0t22寻找加密入口查看接口数据,发现入参、出参都是经过加密的,需要加密、解密查看Initiator中,发现promise。异步通过interceptors搜索,往回找不一定能找到,可以考虑正向搜索注......
  • 【刷题笔记】25. Reverse Nodes in k-Group
    题目Givenalinkedlist,reversethenodesofalinkedlistkatatimeandreturnitsmodifiedlist.kisapositiveintegerandislessthanorequaltothelengthofthelinkedlist.Ifthenumberofnodesisnotamultipleofkthenleft-outnodesint......
  • ue5游戏逆向之寻找GWorld,GName和GUObjectArray
    对于ue4而言,符号如果暴露出来的可以直接通过导出表寻找GWorld,GUObjectArray。ue4.23版本以前的通过GNames函数,ue4.23版本及其以后的通过FNamePool::FNamePool构造函数寻找GName。对于未暴露符号的寻找方法和ue5未暴露符号的三件套找法一样。寻找GWorld查看UE5.1源码,GWorld定义在......