CTF安卓逆向练习第一弹

CTF安卓逆向练习第一弹–用户名与密码获取

写在前面的话:终于开始写博客了,记录自己逆向学习的一些过程,因为太小白了,所以权当抛砖引玉,供初学者参考。可能会有些错误,欢迎指出。

本篇从ctf逆向的一道题入手,主要练习so调试相关技术,以及断点下法思路,动态调试等。题目来源是ctf2016年逆向的第一题(第一题简单嘛),apk包:re1-e7e4ad1a.apk,网上好多资源就自己去找吧。

整体概述及大概思路

首先把apk在安卓模拟器中运行出来,看一下这个apk大概是做什么的,需要我们做什么。

模拟器中主界面

从这个app的主界面上可以看出这个app的功能就是输入编号和密码,然后点击sign按钮,实现注册成功。所以我们需要做的事情就是找出编号和密码(flag)。
那么遇到这样的问题,一般情况编号(也就是用户名)是写在java层的,然后加密算法也是写到java层的,而最关键的密码则很有可能是写在native层中的。果然,查看一下这个apk的结构,果然看到了so文件,说明这里用到了native的一些东西,这就需要我们不仅要会分析java层还需要会分析native层的一些东西,这里用到了jeb进行java层的分析,还有ida进行native层的分析及动态调试。

java层分析与编号/用户名查找

首先打开jeb,把apk拖进去,分析java代码及apk逻辑结构
整体逻辑

整体结构还是比较简单的,当然也是比较利于分析的,点开Seclreg,发现onCreat
这里写图片描述

说明这是程序的入口,q键查看java代码,发现两个按钮,刚好一个是sign的按钮,一个是exit按钮。
这里写图片描述
点开b,刚好能看到一行注册成功的判断语句
这里写图片描述
该判断语句如下

if((Seclreg.get_username(this.a).equals(this.a.getResources().getString(2131034119))) && (Seclreg.f(this.a).getpl(Seclreg.e(this.a), Seclreg.d(this.a))))

可以看出在&&的前半句是用来判断编号的,后面是用来判断密码的。
先看前半段,有个getString的id号是2131034119,转化为16进制是7f050007,在public.xml文件中,找到id号为7f050007的字段,刚好是username,然后看到它的类型是strings,那么到strings.xml文件中继续查找,对应的字段是secl-007,至此,我们已经把编号找到了。当然有些比较方便的技巧是直接ctrl+F,直接找username的字段,一般都是有的。
这里写图片描述
这里写图片描述
因为本文的apk代码比较少,所以可以每个类都分析一下,比如a类中是对密钥加密的算法,其中代码清楚的显示了使用了des进行加密,同时密钥在strings.xml中也能找到(这个密钥是对密码进行加密时用的)。
这里写图片描述
接下来再分析一下之前if判断语句的后半部分,这里用到了getpl,然后发现这个getpl刚好有native,这就说明此时需要对so文件进行分析。接下来使用ida对so文件进行分析。
这里写图片描述
小tip:因为混淆的原因,我们看到的类都是a、b等不便于分析与记忆的类,当我们进行分析的时候,分析出来某个类的时候,可以按n键,对这个类进行重新命名,命名我们自己熟悉与常用的英文名称,这样面对大型程序的时候就可以很好的阅读

IDA进行静态分析

上面提到so文件,那么就要对so文件进行分析,使用ida进行分析,可以先进行静态分析,把逻辑结构弄清楚之后就可以找到下断点的地方,再进行动态分析。那么,先把ida打开把,把so文件拖进去。可以在exports窗口中直接找到我们需要的函数getpl(一般都是java_com开头),也可以在左侧Function window窗口,用ctrl+F建,进行快速查找。
这里写图片描述
然后定位到代码处,空格键,查看代码逻辑,或F5键,查看伪C代码。查看代码,从下网上看,发现getpl这个函数是关键函数。这里有个小tip,好多时候我们看到有v4+676这样的代码,这个时候选中,点击y键,替换名字为JNIEnv*,此时可以发现,这个变成了我们可以理解,方便阅读的形式。同理,这里的n键与jeb中的功能一样,可以将难以阅读的函数或变量换成我们自己便于理解的词语。
这里写图片描述这里写图片描述
然后确定getpl函数为关键函数之后,双击getpl,跳入getpl函数的代码中。很长的一段代码,因为我们只是做逆向,目的只是为了获取flag,因此没有必要从头阅读详细分析整个程序,因此从后往前阅读,找到关键点即可,没有必要全部读懂。(因为我自己也不会啊)然后果然发现了关键的判断地方,这里有两个关键的地方,一个是if(v11 ==39),也就是说这个密码长度要39位。但是我们实际输入不了那么多,所以这里要把这个判断语句改一下,改成相反的效果,这样程序走流程的时候刚好能走到这个分支,进而执行下面的语句。再然后就是一个j_j_strncmp的一个比较函数,这里一分析,发现s2是我们自己输入的密码,而这个p1刚好就是我们需要进行比较的,也就是要找的flag。
这里写图片描述
那么下面就需要做两个步骤了,一个是把这个判断长度等于39的语句改成相反效果,从而使程序走这个分支,还有一步就是获取下面比较语句中的p1的值,从而找到flag。下面我们把这个伪c代码切换到arm汇编语句中再仔细研究一下(可以通过空格键切换逻辑图定位到关键代码中)。
这里写图片描述
关键代码就在这几句中,其中BNE就是判断跳转代码,通过查找资料可知,BNE对应的相反逻辑是BEQ,BNE对应的hex机器码是D1,而BEQ对应的hex机器码是D0,因此只要找到BNE代码的位置,将dex代码改成D0即可,此时可以点击Hex View界面进行查看,点击F2按钮进行更改,再点击F2按钮保存,这里的F2更改保存只是临时的,并不能保存在磁盘中。
小tip:j_j_strlen是获取长度函数,j_j_strncmp是比较函数

IDA动态调试

下面要进行动态调试,首先先把动态调试的服务开启,在虚拟机中启动IDA的server。

adb shell /data/local/tmp/android_server

小tip:有的时候开启IDAserver的时候如果出现报错,the process list of the remote machine is empty ,此时需要用root权限打开IDA的server

然后进行端口转发

adb forward tcp:23946 tcp:23946

开始动态调试,先在模拟器中运行app程序,因为程序要打开后才会将库等加载进去。然后打开IDA,将so文件拖进去,然后选中Debugger->Remote ARMLinux/Android debugger
这里写图片描述
点开Attach to process,按照id排列,选中要分析的app项目,然后进入动态调试,有的时候需要等一会儿,软件加载进去。
这里写图片描述
下面来确定下断点的位置,通过之前静态的分析,我们知道下断点实在so库中的getpl函数。如何找到这个函数的位置,我们要先找到so文件的库,然后再找到这个函数所在,因此点击ctrl+S,改界面显示所有链接库的位置,用search进行搜索,因为我们这个apk中so文件的名字就叫libplokm.so,因此用名称进行搜索即可,记录此时这个链接库的地址,在这里我的机器上是A518B000
这里写图片描述
确定了so的位置之后如何确定getpl函数的位置?此时我们再打开一个IDA,把so文件拖进去,查看getpl的地址,可以在左侧函数窗口中进行搜索(ctrl+F),一般都是java_com开头的,然后我们记录这个函数的静态地址7CEC。
这里写图片描述
然后我们就可以计算出这个函数在加载之后,动态的地址了,就是A518B000+7CEC=A5192CEC,此时点击G键,进行地址跳转操作,输入要跳转的地址,然后跳转到我们要下断点的地方,点击F2,下断点,此时该地址代码变红。
这里写图片描述
然后点击左上角的绿色三角按钮,开始动态调试
这里写图片描述
若想要程序走到断点处,需要将编号填写正确,因此在模拟器中填写之前分析好的正确的编号,然后随便填写密码,点击sign按钮,此时程序停止在断点处。
这里写图片描述
通过之前的分析,我们知道有一步是判断密码长度为39的,因此我们需要到这一步更改判断条件,点击空格键,查看代码整体结构,找到我们需要修改的地方。
这里写图片描述这里写图片描述
找到此时BNE判断语句的地址,A5192FEE,下断点,然后到下面HEX view中找到该地址所在地方并进行更改。选中要改的地址,然后View->Open subviews->Hex dump即可直接跳转到要更改的hex地方,然后F2键,实现更改和保存(再按一次实现保存),根据上面的分析,此时将D1改成D0
这里写图片描述
此时再看我们的arm汇编界面,发现指令已经更改,将此处下断点之后,点击绿色的三角按钮进行调试。
这里写图片描述
之后点击F8或者F7键进行单步调试,在hex view中右键,Synchronize with可以查看不同寄存器中的值,运行到我们之前分析的地方,走过这个分支之后,第一步把R0寄存器赋值就是我们要找的flag,进行查看时果然就是这样,可以在右面General reqisters寄存器地址中查看对应hex view中的值,也可以用刚刚说的右键的方式直接找的R0的存储值,hex view中清楚的显示了flag的值
这里写图片描述
至此,这道题已经解出,flag就是:

SSCTF{oty3eaP$g986iwhw32j%OJ)g0o7J.CG:}

真机调试

另,还有一种方法是用真机进行调试,只需要把AndroidManifest.xml文件中进行改写,添加android:debuggable=”true”的条件就行,这里网上都有一些教程的。

<application
                  android:icon="@drawable/ic_launcher"
                  android:label="@string/app_name" 
                  android:debuggable="true">

用真机调试的一个好处就是在ida静态分析之后,可以直接下断点,然后动态调试起来就不用再重新下断点找地址了。
不知道为啥我这里静态调试下好的断点,在动态调试中都没了,还要重新找地方,重新下断点。估计是配置或者是因为虚拟机调试的原因吧。

至此安卓逆向练习第一弹结束,写的有点繁琐,把一些小的步骤也都写上去了,因为刚开始学,所以有些步骤不是很熟练,就把每一步的操作都记录下来了,以后熟练了会好很多,当然最重要的还是要注重这个分析程序的思路和方法吧。另:感谢凯哥的技术支持和对小白的耐心讲解:-)

<think>好的,我现在需要帮助用户解决CTF Web红包题第一的解题思路。根据用户提供的引用内容,我需要先仔细分析已有的信息,看看能不能找到相关的线索。 首先,用户提到了三个引用,其中引用[1]是关于CTFshow的Web刷题记录,里面提到了第一个?>是为了闭合前面的PHP代码,以及匹配/tmp/php??????的路径。引用[2]是第二的题解,可能和第一有相似之处,但暂时先看引用[1]和引用[3]。引用[3]提到在ctfshow()函数中有一个向服务器发送请求的代码,特别是POST到check.php,并且使用了php://input。这可能涉及到PHP流包装器的利用,比如数据输入或文件包含。 用户的问题是关于第一的解题思路,所以我需要推测可能的解题方向。可能涉及到的知识点包括PHP代码闭合、文件上传、路径匹配、参数注入或利用PHP伪协议等。比如,引用[1]中提到的闭合PHP代码可能涉及到利用不严谨的文件包含,通过构造特定的输入来执行任意代码。比如,用户上传的文件可能被存储在/tmp目录下,文件名类似phpXXXXXX,这时候需要利用竞争条件或者文件名猜测来执行上传的脚本。 另外,引用[3]中的check.php页面可能存在参数注入,比如通过token参数传递恶意值,或者利用php://input来传递POST数据执行命令。例如,可能存在反序列化漏洞,或者通过传递PHP代码到服务器端执行。 可能的解题步骤包括: 1. 分析题目提供的Web应用,寻找可能的文件上传点或参数输入点。 2. 尝试上传PHP文件,利用临时文件路径的匹配(如/tmp/phpXXXXXX)来执行代码。 3. 使用PHP伪协议如php://input读取POST数据,结合check.php的接口进行命令注入。 4. 闭合前面的PHP代码,例如通过构造特定的输入使得原本的代码结构被破坏,从而插入恶意代码。 需要验证这些思路是否正确,比如尝试上传一个包含<?php system($_GET['cmd']); ?>的文件,然后通过访问临时文件路径来执行命令。或者通过check.php的POST请求,传递php://input的数据来执行系统命令。 另外,可能涉及到参数污染,比如在URL中注入参数,如token参数后拼接其他参数,或者利用PHP的某些特性绕过过滤。例如,使用?p=php://filter/convert.base64-encode/resource=index.php来读取源码。 可能需要注意的陷阱包括文件上传后的名字不可预测,需要结合竞争条件,或者利用session文件等已知路径。或者题目中存在某些过滤函数,需要绕过,比如禁用某些关键字,这时候需要编码或替换字符。 总结来说,可能的解题步骤是:找到文件上传或参数注入点,利用PHP代码闭合或伪协议执行任意代码,读取或执行命令获取flag。</think>### CTF Web 红包题 第一 解题思路分析 根据提供的引用信息,该题目可能涉及PHP代码闭合、文件路径匹配和PHP伪协议利用。以下是分步解析思路: 1. **PHP代码闭合分析** 引用[1]提到`第一个?>`用于闭合前面的PHP代码。这表明题目可能通过构造特殊输入截断原有代码逻辑。例如: ```php <?php include($_GET['p']); ?> ``` 若参数`p`传入内容为`/tmp/phpXXXXXX`(临时文件路径),并包含`?>`闭合标签,后续内容可能被当作HTML执行,实现代码注入[^1]。 2. **临时文件路径匹配** 上传文件时,PHP会将文件暂存为`/tmp/phpXXXXXX`格式。通过构造包含恶意代码的文件(如`<?php system($_GET['cmd']); ?>`),利用路径匹配规则尝试访问临时文件,例如: ```bash GET /?p=/tmp/phpabc123&cmd=cat+/flag ``` 3. **PHP伪协议利用** 引用[3]中`check.php`的请求使用了`php://input`,表明可能通过输入流传递数据。尝试通过POST请求传递PHP代码: ```http POST /check.php?token=abc&php://input HTTP/1.1 ... <?php system("ls /"); ?> ``` 4. **代码验证与绕过** 若存在过滤,可使用编码或拼接绕过: ```php <?= `c\at /fla*`; ?> ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值