Happy Android Security
  • 前言
  • CTF
    • 2014 NAGA&PIOWIND APP应用攻防竞赛 Crackme01
    • 2014 NAGA&PIOWIND APP应用攻防竞赛 Crackme02
    • 2014 NAGA&PIOWIND APP应用攻防竞赛 Crackme03
    • 2014 NAGA&PIOWIND APP应用攻防竞赛 Crackme04
    • 2015 0CTF Vezel 100
    • 2015 0CTF Simple 150
    • 2015 XCTF&RCTF Flag System 100
    • 2015 XCTF&RCTF Where 300
    • 2015 海峡两岸CTF 一个APK逆向试试吧
    • 2016 LCTF EASY 100
    • 2016 AliCTF Timer 50
    • 2016 AliCTF Loop And Loop 100
    • 2016 ZCTF Android1 200
    • 2016 LCTF EASY EASY 200
    • 2017 ISCC 全国大学生信息安全与对抗技术竞赛 简单到不行
    • 2017 SSCTF 加密勒索软件 100
    • 2017 SSCTF Login 200
    • 2017 XCTF&NJCTF Easy Crack 100
    • 2017 XCTF&NJCTF Safe Box 100
    • 2017 XCTF&NJCTF Little Rotator Game 200
    • 2017 陕西省网络安全大赛 拯救鲁班七号 100
    • 2017 陕西省网络安全大赛 The Marauders Map 150
    • 2017 陕西省网络安全大赛 人民的名义 抓捕赵德汉1 200
    • 2017 陕西省网络安全大赛 人民的名义 抓捕赵德汉2 200
    • 2017 陕西省网络安全大赛 取证密码 200
  • 应用侧安全
    • 任意私有组件启动漏洞的利用
    • [ByteDance] [TikTok] NotificationBroadcastReceiver导出存在任意私有组件启动结合FileProvider机制与FbSoLoader框架导致本地代码执行漏洞
    • [ByteDance] [TikTok] DetailActivity导出存在任意私有组件启动结合FileProvider机制与FbSoLoader框架导致本地代码执行漏洞
    • [ByteDance] [TikTok] WallPaperDataProvider导出存在任意私有文件读取漏洞
    • [Adobe] [Acrobat Reader] AdobeReader处理DeepLink时未正确进行合法性校验导致下载PDF文件过程出现路径穿越可造成远程代码执行
    • [CVE-2019-16253] [Samsung] [SMT] SamsungTTSService导出存在任意私有组件调用提权漏洞
    • [CVE-2021-25390] [Samsung] [Photo Table] PermissionsRequestActivity存在任意私有组件启动漏洞可获取ContentProvider数据
    • [CVE-2021-25391] [Samsung] [Secure Folder] KnoxSettingCheckLockTypeActivity泄露Intent可获取ContentProvider数据
    • [CVE-2021-25397] [Samsung] [TelephonyUI] PhotoringReceiver导出存在任意文件写漏洞结合动态库加载行为可实现本地任意代码执行
    • [CVE-2021-25410] [Samsung] [CallBGProvider] CallBGProvider的调用权限定义为Normal可实现任意私有文件读取
    • [CVE-2021-25413] [Samsung] [Contacts] SetProfilePhotoActivity导出存在任意私有组件启动漏洞可获取ContentProvider数据
    • [CVE-2021-25414] [Samsung] [Contacts] SetProfilePhotoActivity导出存在任意私有文件读写漏洞
    • [CVE-2021-25440] [Samsung] [FactoryCameraFB] CameraTestActivity导出存在文件读写权限泄露漏洞
    • [CVE-2022-22292] [Samsung] [Telecom] 动态注册BroadcastReceiver默认导出存在任意私有组件启动漏洞
  • 系统侧安全
    • REDMI 5 Plus Second Space Password Bypass
    • 【蓝牙】CVE-2017-13258 CVE-2017-13260 CVE-2017-13261 CVE-2017-13262信息泄露
    • 【蓝牙】CVE-2018-9357 BNEP_Write越界写导致RCE
    • 【蓝牙】CVE-2018-9358 信息泄露
    • 【蓝牙】CVE-2018-9359 process_l2cap_cmd_L2CAP_CMD_INFO_REQ未判断缓冲区边界造成信息泄露
    • 【蓝牙】CVE-2018-9360 process_l2cap_cmd_L2CAP_CMD_CONN_REQ未判断缓冲区边界造成信息泄露
    • 【蓝牙】CVE-2018-9361 process_l2cap_cmd_L2CAP_CMD_DISC_REQ未判断缓冲区边界造成信息泄露
    • 【蓝牙】CVE-2018-9365 smp_sm_event数组越界访问导致RCE
    • 【蓝牙】CVE-2018-9381 gatts_process_read_by_type_req未初始化栈变量导致信息泄露
    • 【NFC】CVE-2018-9584 nfc_ncif_set_config_status未检测长度越界读写
    • 【NFC】CVE-2018-9585_nfc_ncif_proc_get_routing未检测长度越界读写
    • 【蓝牙】CVE-2019-2209 未检测PIN码长度导致越界读造成信息泄露
    • 【NFC】CVE-2019-9358 ce_t3t_data_cback越界读写
  • 内核驱动侧安全
Powered by GitBook
On this page
  1. CTF

2016 AliCTF Loop And Loop 100

Previous2016 AliCTF Timer 50Next2016 ZCTF Android1 200

Last updated 2 years ago

2016年阿里CTF的第二道Mobile题,分值100

Jadx打开,发现关键的代码在这里

check()函数的定义

public int check(int input, int s) {
    return chec(input, s);
}

chec()函数为native函数

public native int chec(int i, int i2);

IDA载入对应so,修复一些类型并且重命名一些变量

逻辑很简单,我们输入数据,然后通过check()各种调用,在native中判断第二个参数,第二个参数传入的是99,并且获取了Java层的三个函数check1(),check2(),check3()的MethodID

接下来进行判断,通过Num_99的值调用不同的check*()函数

if ( Num_99 - 1 <= 0 )
    result = vInput;
else
    result = _JNIEnv::CallIntMethod(vEnv, jobject, (int)*(&jMethodID_check1 + 2 * Num_99 % 3), vInput);

我们回过头看Java层的三个check*()函数,它们其实这只是做了加加减减的操作而已,然后再回头调用naive层的chec(),或者说,这其实就是个等差数列的求和

check1()

public int check1(int input, int s) {
    int t = input;
    for (int i = 1; i < 100; i++) {
        t += i;
    }
    return chec(t, s);
}

check2()

public int check2(int input, int s) {
    int t = input;
    int i;
    if (s % 2 == 0) {
        for (i = 1; i < 1000; i++) {
            t += i;
        }
        return chec(t, s);
    }
    for (i = 1; i < 1000; i++) {
        t -= i;
    }
    return chec(t, s);
}

check3()

public int check3(int input, int s) {
    int t = input;
    for (int i = 1; i < 10000; i++) {
        t += i;
    }
    return chec(t, s);
}

有一点奇怪的是,在所有代码中,我们并没有发现Num_99参数的对应操作,比如减1,减2等,如果这个参数不变化,递归过程就要爆栈了

再次回过头看native代码,这个函数调用了check*(),但是每个check*()函数都是有2个参数的,加上默认的3个应该是5个,但是这里只是显示了四个

int __fastcall _JNIEnv::CallIntMethod(JNIEnv *env, jobject jobject, int a3, int a4)
{
    int varg_r3; // [sp+14h] [bp-4h]@1

    varg_r3 = a4;
    return (*env)->CallIntMethodV(env, jobject, (jmethodID)a3, (int **__attribute__((__org_typedef(va_list))) )&varg_r3);
}

我们知道,ARM传递参数会使用R0-R3,如果多的参数则使用栈传递,那么这里第5个参数是必然要使用栈传递了,我们观察最后一个压栈操作即可,最后一个压栈的操作是对R6寄存器进行处理,先减1,然后判断小于等于0,最后压栈进行参数传递,有一点要注意的是,R3是第三个参数,这个参数保存在栈中,为减1前的数据

也就是说,在2 * Num_99 % 3的时候,还未减一,而传递的参数为Num_99 - 1

相当于

result = _JNIEnv::CallIntMethod(vEnv, jobject, (int)*(&jMethodID_check1 + 2 * Num_99 % 3), vInput, Num99 - 1);

那么接下来就看高中数列学的好不好了

package test;

import java.awt.geom.Ellipse2D;

public class Main {
	
	public static void main(String[] args) throws Exception{
		int output = 1835996258;
		for(int i = 2; i <= 99; i++) {
			if((2 * i % 3) == 0) {
				output = check1(output, i - 1);
			} else if((2 * i % 3) == 1) {
				output = check2(output, i - 1);
			} else {
				output = check3(output, i - 1);
			}
		}
		System.out.println(Integer.toString(output));
	}

    public static int check1(int input, int s) {
        int t = input;
        for (int i = 1; i < 100; i++) {
            t -= i;
        }
        return t;
    }

    public static int check2(int input, int s) {
        int t = input;
        int i;
        if (s % 2 == 0) {
            for (i = 1; i < 1000; i++) {
                t -= i;
            }
            return t;
        }
        for (i = 1; i < 1000; i++) {
            t += i;
        }
        return t;
    }

    public static int check3(int input, int s) {
        int t = input;
        for (int i = 1; i < 10000; i++) {
            t -= i;
        }
        return t;
    }
}

我知道等差数列可以求和,我懒

输出

236492408

在APP中输入这串数字

flag:alictf{Jan6N100p3r}