最近在做XCTF新手区的题目,发现了这个Ph0ne1x-100这道题十分的有意思,这道题的难度不高,但是十分适合新手,它的解题思路多种多样,不仅可以动态分析,还可以静态分析,包括Hook,改源码等技巧。
经过最近的研究,我通过这道题也研究出五种解法,其中有一些方法的思想相同,只是角度和难度不同,希望可以给大家提供一些思路。

  • 老规矩,安装上去看一下,有一个输入flag的窗口,登录显示Fail:

  • 再扔到JEB中打开,这个APK有SO库,主要类就是MainActivity,BuildConfig里面Debug为false,MainActvity中加载了库phcm,接下来是两个类库中的关键函数encrypt和getFlag,MainActvity中有一个getSecret函数通过调用那两个native函数完成加密:

  • 分析一下MainActivity中的getSecret函数,这个函数参与运算的外来参数只有一个传入参数,这就意味着如果我们在放入getsecurity之前获得了flag,不经过getsecurity也能直接比较,那么这道题的主要逻辑就是:

    内置的字符串和函数通过setflag加工,生成加密密文。输入的flag通过encrypt进行加密生成密文,最后这两个密文是一致的,所以接下来我们就要先通过setflag进行加工,生成密文,再逆向encrpt加密生成flag。


  • 接下来看so库的文件:

    • getFlag如下,主要是getFlag没有输入,这就意味着这里面使用的是内置的参数进行的加密,看起来挺简单的,但是里面有一个unk_2784并没有被成功解析出来,但是v10又被用于接下来的计算,unk_2784内存处是一些无法理解的东西,这就导致了静态分析陷入了僵局:


  • 静态分析失败,接下来转为动态,既然v10进行复制的是内存的一段,我们就在动态运行时截取下来getflag的返回值这一段进行读取,再放入encrypt进行逆向分析,解析出需要我们输入的Flag

动态分析1,借用maketext输出:

  • 先找到MainActivity中调用getFlag的函数:

  • 拷贝到下方输出Failed的位置,覆盖掉原有的Failed。

  • 重新打包,运行,出现中间值:

  • encrypt如下,主要就是按位减一:

  • 编写程序按位加1得到源程序:
string ciphertext = "ek`fz@q2^x/t^fn0mF^6/^rb`qanqntfg^E`hq|";
for(int x=0; x < ciphertext.length(); x++){ciphertext[x] = ciphertext[x] + 1;
}
cout<<ciphertext;

动态分析二:

使用AndroidStudio进行分析:

  • 创建一个remote,对APK拆包出来的APK中的smali文件夹导入到项目中,并设置成resourceroot

  • 接下来在虚拟机上运行smali文件,并attach到进程:

  • 将断点打在MainActivity的getFlag之后,传入getsecret函数之后,单步跳入查看传入getsecret函数的string值:


动态分析三:

使用Frida框架对So库getFlag()进行So层Hook操作:

Hook代码:

import frida
import sysjscode = """
Java.perform(function(){Interceptor.attach(Module.findExportByName("libphcm.so","Java_com_ph0en1x_android_1crackme_MainActivity_getFlag"),{onEnter: function(args) {},onLeave: function(retval){var String_java = Java.use('java.lang.String');var args_4 = Java.cast(retval, String_java);send("getFlag()输出信息为:"+args_4);}});
});
"""
def printMessage(message,data):if message['type'] == 'send':print(' {0}'.format(message['payload']))else:print(message)process = frida.get_usb_device().attach('Android_crackme')
script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()

输出结果:

静态分析补充:

  • 刚刚遇到了无法解决的unk_2748,经过动态分析我们知道了这个每次都是不变的,那么我们可以直接将这40个按int型抄下来,再转化成char返回给v10,代码如下:
#include<iostream>
using namespace std;
#include<stdlib.h>int main(){int v2; // r0int v3; // r3char *v4; // ST04_4char v5; // ST08_1int v6; // r1int v8; // [sp+0h] [bp-68h]char v9[16];char v10[40];int v11[40] = {0x2E, 0x36, 0x42, 0x4C, 0x5F, 0xBF, 0xE0, 0x3A, 0xA8, 0xC3, 0x20, 0x63, 0x89, 0xB7, 0xC0, 0x1C, 0x1D, 0x44, 0xC2, 0x28, 0x7F, 0xED, 0x02, 0x0E, 0x5D, 0x66, 0x8F, 0x98,0xB5, 0xB7, 0xD0, 0x16, 0x4D, 0x83, 0xF8, 0xFB, 0x01, 0x43, 0x47, 0x00};strcpy(v9,"Hello Ph0en1x");//memcpy(v10, &v11, 40);//memcpy(v10, &v9, 40);for(int x=0; x<=40;x++){v10[x] = v11[x];}//cout<<strlen(v10);v8 = strlen(v9);v2 = strlen(v10) - 1;while ( v2 > 0 ){v3 = ((unsigned __int8)v10[v2]++ + 1) & 0xFF;v4 = &v10[v2 - 1];v5 = v3 - v10[v2 - 1];v6 = v2-- % v8;v4[1] = (v9[v6] ^ v5) - 1;}v10[0] = (v10[0] ^ 0x48) - 1;//至此获得了用于比较的字符数组v10,长度为40//接下来是反向处理string str(v10);//cout<<str;string ciphertext = "ek`fz@q2^x/t^fn0mF^6/^rb`qanqntfg^E`hq|";for(int x=0; x < ciphertext.length(); x++){ciphertext[x] = ciphertext[x] + 1;}cout<<ciphertext;}

动态分析4:

使用Frida对Java层函数getSecret()函数进行Hook操作:

import frida
import sysjscode = """
if(Java.available){Java.perform(function(){var MainActivity = Java.use("com.ph0en1x.android_crackme.MainActivity");//找到getSecret函数,将输入参数str返回即可MainActivity.getSecret.implementation=function(str){send("getFlag()输出信息为:"+str);return str;    }});}
"""
def printMessage(message,data):if message['type'] == 'send':print(' {0}'.format(message['payload']))else:print(message)process = frida.get_usb_device().attach('Android_crackme')
script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()

  • 输出:

**FLAG:**flag{Ar3_y0u_go1nG_70_scarborough_Fair

Ph0ne1x-100 解题思考相关推荐

  1. 解题思考F. 解方程(二分法解方程)

    题目描述 Problem Description 给定方程 8x^4 + 7x^3 + 2x^2 + 3x + 6 == Y,请计算x在[0,100]范围内的解. Input 输入数据首先是一个正整数 ...

  2. 解题思考G. 老鼠和猫的交易

    题目描述 Problem Description 小老鼠准备了M磅的猫粮,准备去和看守仓库的猫做交易,因为仓库里有小老鼠喜欢吃的五香豆. 仓库有N个房间: 第i个房间有J[i] 磅的五香豆,并且需要用 ...

  3. 跟波利亚学解题(rev#3)

    跟波利亚学解题(rev#3) By 刘未鹏(pongba) C++的罗浮宫(http://blog.csdn.net/pongba) TopLanguage(http://groups.google. ...

  4. 全国计算机等级考试题库二级C操作题100套(第63套)

    第63套: 给定程序中,函数fun的功能是:有N×N矩阵,根据给定的m(m<=N)值,将每行元素中的值均右移m个位置,左边置为0.例如,N=3,m=2,有下列矩阵 1 2 3 4 5 6 7 8 ...

  5. 【JAVA】力扣第197场周赛代码+解题思路

    目录 5460. 好数对的数目 解题锦囊 思路一:常规(未用解题锦囊) 代码 思路二:使用解题锦囊 5461. 仅含 1 的子串数 解题锦囊 代码 错误点 5211. 概率最大的路径 解题锦囊 代码 ...

  6. 中国快递“CSN项目+物流宝+快递100”…

    国际工商管理学院 内容摘要:快递行业从1979年引入中国至今已经过去了三十多年,随着中国经济的日益繁荣和电子商务的快速发展,各大快递公司也逐渐在服务业中崭露头角,成为消费者日常生活中不可或缺的角色.越 ...

  7. 广义斐波那契数列通项公式以及一些扩展的思考

    推导 定义数列 { A n } \{A_n\} {An​},对于 n ≥ 2 n\ge 2 n≥2 有 A n = a A n − 1 + b A n − 2 A_n=aA_{n-1}+bA_{n-2 ...

  8. 【Day24】 LeetCode算法题 (注释详细+解题思路)[43. 字符串相乘 ] [1800. 最大升序子数组和]

    刷题打卡,第 二十四 天 题目一.43. 字符串相乘 题目二.1800. 最大升序子数组和 题目一.43. 字符串相乘 原题链接:43. 字符串相乘 题目描述: 给定两个以字符串形式表示的非负整数 n ...

  9. LeetCode第176场周赛(Weekly Contest 176)解题报告

    又是一周掉分之旅,我发现,LeetCode周赛的数据好水,所以有的时候,实在没思路,先暴力解决试试(即使分析出时间复杂度会超时),比如第二题和第三题都可以暴力通过,GG思密达. 这周主要使用了数据结构 ...

最新文章

  1. html标签article,html标签中section与article 区别
  2. 想学python编程-想学Python编程?你真的适合吗?
  3. mysql data文件夹下的ibdata1 文件作用
  4. 带你了解超大规模数据中心究竟有何不同?
  5. pagefile.sys
  6. 唐骏给李开复泼冷水:创业不可复制
  7. 案例解析|从数据规划、业务分析到管理决策的数据治理方案
  8. Java基础 - 变量的定义和使用
  9. 从「蒸汽时代」到「高铁时代」,SUNMI DevOps 转型之路 | 原力计划
  10. 鼠标移入通过时间控制实现两个不同步的动画效果
  11. 如何const定义一个不可变数组
  12. WPF UI 框架 收集
  13. 一文系统搞懂协同推荐算法(二)
  14. Qt Creator 的下载与安装
  15. qt中toLocal8Bit和toUtf8()有什么区别
  16. win10专业版使用vmware安装虚拟机时“出现此主机支持Intel VT-x,但Intel VT-x处于禁用状态”。
  17. LINUX学习笔记:31个常用LINUX命令和相关解释
  18. R语言reshape2包-官方文档学习
  19. Unity的碰撞检测
  20. 如何推动共享电单车健康发展

热门文章

  1. SQL数据库完美恢复 SQL数据库损坏修复
  2. excel表格内容拆分_「职场百科书」—「实用小技巧」—(Excel表格拆分)
  3. excel表格拆分怎么做?
  4. NVIDIA JETSON XAVIER NX TX2 NANO 比较及与显卡算力对比
  5. 华为帐号“一号畅玩”体验,助力游戏用户增长
  6. 2023年品牌惊蛰节气海报赏析
  7. Docker之使用maven插件【Dockerfile方式】构建并推送镜像到私有仓库
  8. A. Equalize Prices Again(水题) Codeforces Round #590 (Div. 3)
  9. ui标注android ios,IOS+ANDROID的UI切图与标注方法
  10. Actor模式理解与使用