android6 frida,利用frida来解一些安卓题目

之前在github看了r0ysue大佬的frida系列教程,于是想来实践一下。

DDCTF2018-HelloBabyDex

这道题涉及到了APK的热修复,目前还没有怎么接触,之后得深入一下。

47f46bd8b12cadde1cfc0f91d95b7506.png

这道题在Mainactivity的onCreate函数中调用了Joseph函数,并把它的返回值拼接作为flag

String v9 = this.Joseph(1, 2);

super.onCreate(arg13);

this.setContentView(0x7F09001B); // layout:activity_main

this.runRobust();

SignCheck v10 = new SignCheck(this, this, "1B:D0:4A:9D:B5:A9:84:93:7E:79:27:9C:6C:C4:14:AB:DD:B0:75:7F");

v10.check();

Debug.isDebuggerConnected();

View v8 = this.findViewById(0x7F07003D); // id:input_text

EditText v8_1 = (EditText)v8;

View v7 = this.findViewById(0x7F070026); // id:check_btn

Button v7_1 = (Button)v7;

cn.chaitin.geektan.crackme.MainActivity.1 v0_3 = new View.OnClickListener() {

public static ChangeQuickRedirect changeQuickRedirect;

@Override // android.view.View$OnClickListener

public void onClick(View arg9) {

Object[] v0 = new Object[1];

v0[0] = arg9;

ChangeQuickRedirect v2 = cn.chaitin.geektan.crackme.MainActivity.1.changeQuickRedirect;

Class[] v5 = new Class[1];

Class v1 = View.class;

v5[0] = v1;

Class v6 = Void.TYPE;

boolean v0_1 = PatchProxy.isSupport(v0, this, v2, false, 18, v5, v6);

if(v0_1) {

Object[] v0_2 = new Object[1];

v0_2[0] = arg9;

ChangeQuickRedirect v2_1 = cn.chaitin.geektan.crackme.MainActivity.1.changeQuickRedirect;

Class[] v5_1 = new Class[1];

Class v1_1 = View.class;

v5_1[0] = v1_1;

Class v6_1 = Void.TYPE;

PatchProxy.accessDispatch(v0_2, this, v2_1, false, 18, v5_1, v6_1);

}

else {

EditText v0_3 = v8_1;

Editable v0_4 = v0_3.getText();

boolean v0_5 = TextUtils.isEmpty(v0_4);

if(v0_5) {

label_31:

MainActivity v0_12 = MainActivity.this;

Toast v0_13 = Toast.makeText(v0_12, "大佬莫急!再试试!", 0);

v0_13.show();

}

else {

EditText v0_6 = v8_1;

Editable v0_7 = v0_6.getText();

String v0_8 = v0_7.toString();

StringBuilder v1_2 = new StringBuilder();

StringBuilder v1_3 = v1_2.append("DDCTF{");

String v2_2 = v9;

StringBuilder v1_4 = v1_3.append(v2_2);

StringBuilder v1_5 = v1_4.append("}");

String v1_6 = v1_5.toString();

boolean v0_9 = v0_8.equals(v1_6);

if(!v0_9) {

goto label_31;

}

MainActivity v0_10 = MainActivity.this;

Toast v0_11 = Toast.makeText(v0_10, "恭喜大佬!密码正确!", 0);

v0_11.show();

}

}

}

};

v7_1.setOnClickListener(v0_3);

可以看到v9参与了之后的拼接以及equals操作,于是我们这里可以使用frida直接来进行hook

hook equals函数的话,可以直接出flag,hook Joseph函数的话,可以出flag中的字符串,拼接起来。

上脚本:

import frida, sys

source = """

Java.perform(function() {

var clazz = Java.use('cn.chaitin.geektan.crackme.MainActivity');

clazz.Joseph.implementation = function() {

var msg = clazz.Joseph.apply(this, arguments);

send(msg);

return msg;

}

var clazzz = Java.use('java.lang.String');

clazzz.equals.implementation = function() {

var msg = clazzz.equals.apply(this, arguments);

var ret = clazzz.valueOf.apply(this,arguments);

if(ret.indexOf("DDCTF")!=-1)

send(ret);

return msg;

}

});

"""

def on_message(message, data):

if message['type'] == 'send':

print("[*] {0}".format(message['payload']))

else:

print(message)

process = frida.get_usb_device().attach('cn.chaitin.geektan.crackme')

script = process.create_script(source)

script.on('message', on_message)

script.load()

sys.stdin.read()

53ff67da7428baae98f8585afe84d663.png

可以看到,Joseph函数只调用了一次,但输出了两次,这就是热补丁的结果。

hook equals函数后,再加以筛选,直接出flag!

RCTF2015(FlagSystem)

这道题看了奈沙夜影的wp,他是用xposed实现的,这里我使用了frida

引用大佬的分析过程,这里只给出frida实现。

https://blog.csdn.net/whklhhhh/article/details/89118707

上脚本:

#!/usr/bin/env python2

# -*- coding: utf-8 -*-

import frida , sys#select book_author,book_name from books_table

jscode = """

Java.perform(function () {

send("Hook start..");

var test = Java.use('com.example.mybackup.Test');

var k;

test.getSign.implementation = function () {

send("getSign Function implemented");

k = test.getSign.apply(this,arguments);

send("Password is : " + k);

return k;

}

var demo = Java.use('com.example.mybackup.BooksDB');

var db;

demo.getReadableDatabase.implementation = function (k) {

send("getReadableDatabase Function implemented");

db = this.getReadableDatabase(k);

if(db != null)

send('DB got');

var S = Java.use("java.lang.String");

var sql = S.$new("select book_author,book_name from books_table");

var cursor = db.rawQuery(sql,null);

if(cursor!=null)

send('cursor got');

/*cursor.getString(0);

while(cursor.moveToNext()) {

send("Result : " + cursor.getString(0));

}

Java.choose("net.sqlcipher.Cursor" , {

onMatch : function(instance){

console.log("Found instance: "+instance);

},

onComplete:function(){}

});*/

var class_cursor = Java.use("android.database.Cursor");

cursor = Java.cast(cursor,class_cursor);

while(cursor.moveToNext()) {

send("Result : " + cursor.getString(0));

}

return db;

}

demo.$init.implementation = function (a) {

send("$init Function implemented");

return this.$init(a);

}

});

"""

def on_message(message, data):

if message['type']=='send':

print("[*] {0}".format(message['payload']))

else:

print(message)

device = frida.get_usb_device()

pid = device.spawn(['com.example.mybackup'])

process = device.attach(pid)

script = process.create_script(jscode)

script.on("message", on_message)

script.load()

device.resume(pid)

sys.stdin.read()

这里说明一下与上一个frida脚本的区别,这道题需要拿到sqlite的db,所以需要hook getReadableDatabase这个函数,这个函数在构造函数中所以需要在APK刚运行时插桩,使用了spawn。

拿到db之后就容易了,再获取到cursor,读取数据库就好了。

这里还有一个坑点,由于这个apk使用了sqlcipher库,这个库中的cursor是经过包装的接口,真正的Cursor.moveToNext等函数在AbstractCursor中实现,这里直接拿到cursor的话,调用

cursor.moveToNext会报错,所以需要强制cast成android.database.Cursor这个类型才行。当时尝试了直接获取AbstractCursor的instance和获取cursor的instance都不可以。。

最终效果:

a21316ebde977000c64c589da56d9f53.png

不得不说,frida真的是神器。

来源:https://www.cnblogs.com/basstorm/p/12641393.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值