【愚公系列】2021年12月 攻防世界-简单题-MOBILE-010(easy-dex)
文章目录
- 前言
- 一、easy-dex
- 二、使用步骤
- 1.dex和odex文件结构
- 2.jadx分析apk
- 3.IDA
- 4.jadx打开easy-dex.dex
- 总结
前言
APK解包后是没有dex文件的,运行代码使用了NativeActivity的方法封装到了libnative.so 这个文件中。APK实际包含了2个APP,这2个APP的包名一致。一个存放在libnative.so文件中,另一个是解压后的dex文件。APK安装后,的功能是摇晃收集达到一定次数(10秒100次,肯定做不到)然后解压一个dex文件到特定的目录下。flag在通过分析释放出来dex文件得出。
这里得到flag涉及了几个步骤:
- 得到释放的dex文件
- 将dex文件合成新的APK动态调试(非必须)
- 静态分析dex文件
- 编写解密算法求出flag
提示:以下是本篇文章正文内容,下面案例可供参考
一、easy-dex
题目链接:https://adworld.xctf.org.cn/task/task_list?type=mobile&number=6&grade=0&page=1
二、使用步骤
1.dex和odex文件结构
dex文件结构
文件头固定:64 65 78 0A 30 33 35 00
odex是dex的优化,结构如下:
文件头固定:64 65 79 0A 30 33 36 00
2.jadx分析apk
可以看一下AndroidManifest
可以看到这个是个纯C/C++写的,没有Java代码,是个NativeActivity。
但是后面又有个MainActivity,所以可能是运行so之后就会放出来一个dex。
NativeActivity的启动函数是android_main,进入so中查看android_main
3.IDA
源码分析
int __fastcall android_main(_DWORD *a1)
{void *v2; // r5char *v3; // r10int v4; // r2int v5; // r1time_t v6; // r8int *v7; // r0int v8; // r3int v9; // r6int v10; // r4float v11; // s0int v12; // r0int v13; // r5int v14; // r5int v15; // r3void *v16; // r0int v17; // r2int v18; // r1char *v19; // r3time_t v20; // r5int v21; // r8Bytef *dest; // [sp+8h] [bp-158h]int v24; // [sp+10h] [bp-150h] BYREFchar v25[4]; // [sp+14h] [bp-14Ch] BYREFint v26[13]; // [sp+18h] [bp-148h] BYREFuLongf destLen; // [sp+4Ch] [bp-114h] BYREFchar v28[8]; // [sp+50h] [bp-110h] BYREFint v29; // [sp+58h] [bp-108h]float v30; // [sp+70h] [bp-F0h]char name[4]; // [sp+B8h] [bp-A8h] BYREFint v32; // [sp+BCh] [bp-A4h]int v33; // [sp+C0h] [bp-A0h]int v34; // [sp+C4h] [bp-9Ch]int v35; // [sp+C8h] [bp-98h]int v36; // [sp+CCh] [bp-94h]int v37; // [sp+D0h] [bp-90h]int v38; // [sp+D4h] [bp-8Ch]int v39; // [sp+D8h] [bp-88h]int v40; // [sp+DCh] [bp-84h]int v41; // [sp+E0h] [bp-80h]__int16 v42; // [sp+E4h] [bp-7Ch]char v43; // [sp+E6h] [bp-7Ah]char filename[4]; // [sp+E8h] [bp-78h] BYREFint v45; // [sp+ECh] [bp-74h]int v46; // [sp+F0h] [bp-70h]int v47; // [sp+F4h] [bp-6Ch]int v48; // [sp+F8h] [bp-68h]int v49; // [sp+FCh] [bp-64h]int v50; // [sp+100h] [bp-60h]int v51; // [sp+104h] [bp-5Ch]int v52; // [sp+108h] [bp-58h]int v53; // [sp+10Ch] [bp-54h]int v54; // [sp+110h] [bp-50h]int v55; // [sp+114h] [bp-4Ch]int v56; // [sp+118h] [bp-48h]char v57; // [sp+11Ch] [bp-44h]int v58; // [sp+124h] [bp-3Ch]destLen = 0x100000;dest = (Bytef *)malloc(0x100000u);v2 = off_43A18;v3 = (char *)malloc((size_t)off_43A18);qmemcpy(v3, &unk_7004, (size_t)v2);*(_DWORD *)filename = -1651995345;v45 = -2003974520;v46 = -1966700387;v47 = -2000190330;v48 = -2071422265;v49 = -947092071;v50 = -1920499569;v51 = -1936879484;v52 = -2138061167;v53 = -962950011;v54 = -1702328950;v55 = -946172774;v56 = -376337267;v57 = 0;*(_DWORD *)name = -1651995194;v32 = -2003974520;v33 = -1966700387;v34 = -2000190330;v35 = -2071422265;v36 = -947092071;v37 = -1920499569;v38 = -1936879484;v39 = -2138061167;v40 = -962950011;v41 = -1853059706;v43 = 0;v4 = 1;v42 = -5690;dofilename[v4++] ^= 0xE9u;while ( v4 != 53 );v5 = 1;name[0] = 47;doname[v5++] ^= 0xE9u;while ( v5 != 47 );j_app_dummy();memset(v26, 0, sizeof(v26));*a1 = v26;a1[1] = sub_29B8;a1[2] = sub_2B90;v26[0] = (int)a1;v26[1] = ASensorManager_getInstance();v26[2] = ASensorManager_getDefaultSensor(v26[1], 1);v6 = 0;v26[3] = ASensorManager_createEventQueue(v26[1], a1[7], 3, 0, 0);v7 = (int *)a1[5];if ( v7 ){v8 = v7[1];v9 = v7[2];v26[10] = *v7;v26[11] = v8;v26[12] = v9;}_android_log_print(4, "FindMyDex", "Can you shake your phone 100 times in 10 seconds?");v10 = 0;do{while ( 1 ){v12 = 0;if ( !v26[4] )v12 = -1;v13 = ALooper_pollAll(v12, 0, v25, &v24);if ( v13 >= 0 )break;if ( v26[4] ){v11 = *(float *)&v26[10] + 0.01;if ( (float)(*(float *)&v26[10] + 0.01) > 1.0 )v11 = 0.0;*(float *)&v26[10] = v11;sub_2C14(v26);}}if ( v24 )(*(void (__fastcall **)(_DWORD *))(v24 + 8))(a1);if ( v13 == 3 && v26[2] ){while ( 1 ){do{if ( ASensorEventQueue_getEvents(v26[3], v28, 1) < 1 )goto LABEL_51;}while ( v29 != 1 );if ( (v10 & 1) != 0 ){if ( v30 >= -15.0 ){LABEL_30:v14 = v10;goto LABEL_31;}if ( v10 == 1 )v6 = time(0);v14 = v10 + 1;}else{if ( v30 <= 15.0 )goto LABEL_30;v14 = v10 + 1;if ( v10 >= 0 )_android_log_print(4, "FindMyDex", "Oh yeah~ You Got it~ %d times to go~", 99 - v10);}
LABEL_31:v10 = v14;if ( (unsigned int)(v14 - 1) <= 0x58 ){v10 = v14;v15 = v14 / 10;if ( v14 % 10 == 9 ){v16 = off_43A18;v17 = (int)off_43A18 / 10;v18 = (v15 + 1) * ((int)off_43A18 / 10);if ( (int)off_43A18 / 10 * v15 < v18 ){v19 = &v3[v17 * v15];do{--v17;*v19++ ^= v14;}while ( v17 );}if ( v14 == 89 ){while ( v18 < (int)v16 )v3[v18++] ^= 0x59u;}v10 = v14 + 1;}}if ( v14 == 100 ){if ( (int)(time(0) - v6) > 9 ){_android_log_print(4, "FindMyDex", "OH~ You are too slow. Please try again");qmemcpy(v3, &unk_7004, (size_t)off_43A18);v10 = 0;}else{v20 = v6;if ( uncompress(dest, &destLen, (const Bytef *)v3, (uLong)off_43A18) )_android_log_print(5, "FindMyDex", "Dangerous operation detected.");v21 = open(filename, 577, 511);if ( !v21 )_android_log_print(5, "FindMyDex", "Something wrong with the permission.");write(v21, dest, destLen);close(v21);free(dest);free(v3);if ( access(name, 0) && mkdir(name, 0x1FFu) )_android_log_print(5, "FindMyDex", "Something wrong with the permission..");sub_2368(a1);remove(filename);_android_log_print(4, "FindMyDex", "Congratulations!! You made it!");sub_2250(a1);v10 = 0x80000000;v6 = v20;}}}}
LABEL_51:;}while ( !a1[15] );sub_2BDA(v26);return _stack_chk_guard - v58;
}
要求10秒内晃动100次,并逐渐解密dex文件,解密算法使用异或操作。加密的dex文件存放位置:
qmemcpy(v3, &unk_7004, (size_t)v2);//v2为3CA10
地址:0x7004 大小:3CA10
加密算法是将这部分内容分为10分,并且分别和9、19、29、39、49、59、69、79、89
进行异或。如下:
数据范围 | 异或值 |
---|---|
(0, 24833) | 9 |
(24833, 49666) | 19 |
(49666, 74499) | 29 |
(74499, 99332) | 39 |
(99332, 124165) | 49 |
(124165, 148998) | 59 |
(148998, 173831) | 69 |
(173831, 198664) | 79 |
(198664, 223497) | 89 |
(223497, 248336) | 89 |
IDA pro中直接运行python脚本得到dex文件,代码如下:
dump地址文件
import idaapi
addr = 0x7004
size = 0x3CA10with open('C:/Users/Happy/Desktop/题目/dump', 'wb') as f:f.write(idaapi.get_bytes(addr,size))print('dump finished')
python解密
import zlibwith open('dump', 'rb') as f:data1 = f.read()data = list(data1)v14 = 0while True:if (v14 - 1) <= 0x58:v15 = v14 // 10if v14 % 10 == 9:v16 = 0x3CA10v17 = 0x3CA10 // 10v18 = (v15 + 1) * (0x3CA10 // 10)if 0x3CA10 // 10 * v15 < v18:v19 = v17 * v15v17 -= 1data[v19] ^= v14v19 += 1while v17:v17 -= 1data[v19] ^= v14v19 += 1if v14 == 89:while v18 < v16:data[v18] ^= 0x59v18 += 1else:breakv14 += 1filebytes = bytes(data)
with open('easy-dex.dex', 'wb') as w:w.write(zlib.decompress(filebytes))
print('decrypt finished')
运行脚本文件得到easy-dex.dex文件
4.jadx打开easy-dex.dex
package com.a.sample.findmydex;import android.os.Bundle;
import android.support.v7.a.u;
import android.widget.Button;
import android.widget.EditText;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;/* loaded from: C:\Users\Happy\Desktop\题目\easy-dex.dex */
public class MainActivity extends u {private static byte[] m = {-120, 77, -14, -38, 17, 5, -42, 44, -32, 109, 85, 31, 24, -91, -112, -83, 64, -83, Byte.MIN_VALUE, 84, 5, -94, -98, -30, 18, 70, -26, 71, 5, -99, -62, -58, 117, 29, -44, 6, 112, -4, 81, 84, 9, 22, -51, 95, -34, 12, 47, 77};/* JADX INFO: Access modifiers changed from: private */public static byte[] b(String str, String str2) {try {BufferedInputStream bufferedInputStream = new BufferedInputStream(new ByteArrayInputStream(str.getBytes()));ArrayList arrayList = new ArrayList();Object a = b.a(str2.getBytes());for (byte[] bArr = new byte[16]; bufferedInputStream.read(bArr, 0, 16) != -1; bArr = new byte[16]) {arrayList.add(b.a(bArr, 0, a));}ByteBuffer allocate = ByteBuffer.allocate(arrayList.size() * 16);for (Object obj : arrayList.toArray()) {allocate.put((byte[]) obj);}return allocate.array();} catch (Exception e) {return new byte[1];}}/* JADX INFO: Access modifiers changed from: protected */@Override // android.support.v7.a.u, android.support.v4.a.v, android.support.v4.a.p, android.app.Activitypublic void onCreate(Bundle bundle) {super.onCreate(bundle);setContentView(2130968602);((Button) findViewById(2131427413)).setOnClickListener(new a(this, (EditText) findViewById(2131427412), this));}
}
在资源文件中找到:twofish
python还原加密字符串
import base64
m = [-120, 77, -14, -38, 17, 5, -42, 44, -32, 109, 85, 31, 24, -91, -112, -83,
64, -83, -128, 84, 5, -94, -98, -30, 18, 70, -26, 71, 5, -99, -62, -58, 117, 29,
-44, 6, 112, -4, 81, 84, 9, 22, -51, 95, -34, 12, 47, 77]
data = []
for i in m:data.append(i&0xFF)
print(base64.b64encode(bytes(data)))
加密字符串:iE3y2hEF1izgbVUfGKWQrUCtgFQFop7iEkbmRwWdwsZ1HdQGcPxRVAkWzV/eDC9N
加密密钥:I have a male fish and a female fish.
在线解密网址:http://tool.chacuo.net/crypttwofish
得到flag:qwb{TH3y_Io<e_EACh_OTh3r_FOrEUER}
总结
- ida
- jadx
- 异或
- base64
- dex
【愚公系列】2021年12月 攻防世界-简单题-MOBILE-010(easy-dex)相关推荐
- 【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-010(转轮机加密)
文章目录 前言 一.转轮机加密 二.使用步骤 1.下载附件 2.脚本解密 总结 前言 题目描述:你俩继续往前走,来到了前面的下一个关卡,这个铺面墙上写了好多奇奇怪怪的 英文字母,排列的的整整齐齐,店面 ...
- 【愚公系列】2021年12月 攻防世界-简单题-REVERSE-005(game)
文章目录 一.game 二.使用步骤 1.IDA静态分析 2.OD动态分析 总结 一.game 题目链接:https://adworld.xctf.org.cn/task/task_list?type ...
- 【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-002(Caesar)
文章目录 前言 一.Caesar 二.使用步骤 1.下载附件 2.凯撒密码 总结 前言 题目描述:你成功的解出了来了灯谜,小鱼一脸的意想不到"没想到你懂得这么多啊!" 你心里面有点 ...
- 【愚公系列】2021年12月 攻防世界-简单题-MOBILE-002(app1)
文章目录 一.app1 二.答题步骤 1.运行app 2.jadx反编译apk文件 总结 一.app1 题目链接:https://adworld.xctf.org.cn/task/task_list? ...
- 【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-003(Morse)
文章目录 前言 一.Morse 二.使用步骤 1.下载附件 2.莫尔斯电码 总结 前言 题目描述:小鱼得意的瞟了你一眼,神神气气的拿走了答对谜语的奖励,你心里暗暗较劲 想着下一个谜题一定要比小鱼更快的 ...
- 【愚公系列】2021年12月 攻防世界-简单题-REVERSE-001(Hello, CTF)
文章目录 一.Hello, CTF 二.使用步骤 1.IDA 总结 一.Hello, CTF 题目链接:https://adworld.xctf.org.cn/task/task_list?type= ...
- 【愚公系列】2021年12月 攻防世界-简单题-WEB-004(cookie)
文章目录 一.cookie 二.使用步骤 1.点击获取在线场景 2.查看cookie 总结 1.概念 2.机制 3.修改或者删除cookie 一.cookie 题目链接:https://adworld ...
- 【愚公系列】2021年12月 攻防世界-进阶题-MISC-063(saleae)
文章目录 一.saleae 二.答题步骤 1.logicdata 总结 一.saleae 题目链接:https://adworld.xctf.org.cn/task/task_list?type=mi ...
- 【愚公系列】2021年12月 攻防世界-进阶题-MISC-074(latlong)
文章目录 一.latlong 二.答题步骤 1.file 2.AX.25 3.sox 4.multimon-ng 总结 一.latlong 题目链接:https://adworld.xctf.org. ...
最新文章
- html中表格的页眉页脚,有一个标准的页眉页脚布局HTML网页,而无需使用table标签...
- Robert算子的运用
- CVE-2016-10229分析
- 深入理解ajax系列第一篇——XHR对象
- 启明云端分享:产品应用上,怎么选型ESP-12F\ESP-12E\ESP-12S\ESP-07S这四个模块
- ftpClient的连接超时设置(setConnectTimeout,setSoTimeout)
- Angular Component UI单元测试的隔离策略
- 【数据库原理及应用】经典题库附答案(14章全)——第九章:数据库安全性
- JVMTI标记如何影响GC暂停
- ueditor添加下拉事件_Excel中最智能的三级下拉菜单!
- jquery选择器小知识点们
- 怎样做网站,需要考虑的几个seo因素
- 数据分析实战100例(基于SQLPandas)_探索Chipotle快餐数据
- 惠普linux打印驱动怎么安装驱动程序,hp打印机驱动怎么安装 惠普打印机驱动程序安装方法【详解】...
- PackageInstaller 5.0源码分析静默安装与静默卸载
- FPGA经典设计思想
- ORA-20011: Approximate NDV failed: ORA-29913: error in executing ODCIEXTTABLEOPEN callout
- 超好用的jQuery插件
- 你对Java集合了解多少?
- 网络编程中的基本概念