Getting started with mobile security

Posted by illzz on Fri, 04 Mar 2022 16:38:50 +0100

Getting started with mobile security

Writing Android programs

The xml interface is similar to the web interface. Layout is layout and wrap_content is a filled layout, indicating that it is full

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="user name" />

            <EditText
                android:id="@+id/editTextTextPersonName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:inputType="textPersonName"
                android:text="User" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="password" />

            <EditText
                android:id="@+id/editTextTextPassword"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:inputType="textPassword" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">


            <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="land" />

        </LinearLayout>

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Login button monitoring code

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
EditText Name;
EditText Pass;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Name = findViewById(R.id.editTextTextPersonName);
        Pass = findViewById(R.id.editTextTextPassword);
        Button Login = findViewById(R.id.button);
        Login.setOnClickListener(new View.OnClickListener() { //Monitor whether the button control is clicked. If it is clicked, the onClick function will be executed
            @Override
            public void onClick(View view) {
                check(Name.getText().toString().trim(), Pass.getText().toString().trim()); //Call the check function
            }
        });
    }
    public void check(String name,String pass) //The custom function check is used here to check whether the user name and password are hfdcxy and 1234
    {
        if(name.equals("hfdcxy")&&pass.equals("1234"))
        {
            Toast.makeText(MainActivity.this,"Login successful", Toast.LENGTH_SHORT).show();//Spring frame
        }
        else
            Toast.makeText(MainActivity.this,"Login failed", Toast.LENGTH_SHORT).show();//Spring frame
    }
}

Homework after class

Use Intent to pass data

login interface

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
EditText Name;
EditText Pass;
TextView test;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        test=findViewById(R.id.textView4);
        //test.setText("123");
        Name = findViewById(R.id.editTextTextPersonName);
        Pass = findViewById(R.id.editTextTextPassword);
        Button Login = findViewById(R.id.button);
        Login.setOnClickListener(new View.OnClickListener() { //Monitor whether the button control is clicked. If it is clicked, the onClick function will be executed
            @Override
            public void onClick(View view) {
                go_to();
            }
        });
    }
    public void go_to()
    {
        Intent intent=new Intent(MainActivity.this,MainActivity2.class);
        //intent = Intent(this,MineOrdersListActivity::class.java)
        intent.putExtra("show_name",Name.getText().toString());
        startActivity(intent);
    }
}

Jump interface

//import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity2 extends AppCompatActivity {
TextView Name1;
EditText Name2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        //final View rowView = inflater.inflate(R.layout.activity_main, null);
        Intent intent=getIntent();
        int i = intent.getIntExtra("show_name",0);
        String show_name=intent.getStringExtra("show_name");
        Name1=(TextView) findViewById(R.id.textView3);
       Name1.setText(show_name);
    }
}

Crack Android programs

(1)if-eqz vA, vB, :cond_**"   If vA be equal to vB Then jump to:cond_**
(2)if-nez vA, vB, :cond_**"   If vA Not equal to vB Then jump to:cond_**

Error encountered during back compilation. apktools version problem may also exist in the frame_work framework problem

https://blog.csdn.net/Andrio/article/details/103887045

Debugging smali code

Version andriod4 1.2. It is different from the normal debugging method. Record it

Android studio opens apk. At this time, all smali files appear, and a prompt needs to attach java source code

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-krm632ci-1618733777063)( https://raw.githubusercontent.com/p1aymaker/picture/master/20210122200619.png )]

Get java files with commands

jadx.bat -d java_source app.apk 

Then you can debug the breakpoint under the java file

After the mobile phone is connected, put it into the debugging state

adb shell pm list package
adb shell am start -D -n com.example.myapplication/com.example.myapplication.MainActivity 

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-l3auhye0-1618733777066)( https://raw.githubusercontent.com/p1aymaker/picture/master/20210122201928.png )]

Click here to start debugging java code

Insert log into smali code

log insert from int to string

 const-string v0, "\u8fd9\u4e2a\u503c\u662f"

  invoke-virtual {p0}, Lhfdcxy05/com/myapplication/MainActivity;->fun1()I

  move-result v1

    invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I

log insert of string type

    const-string v0, "\u8fd9\u4e2a\u503c\u662f"

    invoke-virtual {p0}, Lhfdcxy05/com/myapplication/MainActivity;->fun3()I

    move-result-object v1

    invoke-static {v0, v1}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I

Write the first so in Android

https://blog.csdn.net/luo_boke/article/details/107306531

Reference articles

Homework after class

package com.example.soprogram;

import androidx.appcompat.app.AppCompatActivity;
s
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        int a=10;
        int b=12;
        tv.setText(String.valueOf(add(a,b)));
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native int add(int a,int b);
}
#include <jni.h>
#include <string>

extern "C" JNIEXPORT jint JNICALL
Java_com_example_soprogram_MainActivity_add(
        JNIEnv* env,
        jobject /* this */,
        jint a,
        jint b
        ) {
    return a+b;
}

javac has replaced javah

To enter the java directory

javac -h . myJNI.java

IDA cracking so

First, use apktool to unpack

apktool d unpacks.

apktool_2.5.0.jar  b -o new.apk app-debug 

After packing, sign with Android killer

But it's a little strange that lib under armeabi-v7a directory is loaded

But my cpu is arm-v8..

1|equuleus:/ $ cat /proc/cpuinfo
Processor       : AArch64 Processor rev 12 (aarch64)
processor       : 0
BogoMIPS        : 38.40

IDA blasting signature verification

Signature verification: judge whether the program has been cracked by verifying whether the signature has changed

The external calling function in so can also be found in IDA, which can be used to locate the key points

Try importing JNI. Net by H to set the structure reinforcement so code readability

BNE: Data jump instruction, in flag register Z When the flag bit is not equal to zero, Jump to BNE Rear label xx D1
BEQ: Data jump instruction, in flag register Z When the flag bit is equal to zero, Jump to BEQ Rear label xx D0

xx = phase difference instruction * 2 + 4

IDA dynamic cracking verification login

AndroidManifest.xml viewer entry here android:debuggable="true" means this apk can be debugged dynamically

First, andriod_server push to mobile phone / data/local/tmp

After port forwarding, start debugging. It is found that only the system/bin/sh file exists because the real machine does not have root permission

You need to connect with nocturnal simulator, but the architecture of nocturnal simulator is x86, so Android is required_ x86_ Server, and IDA attach should select Remote Linux Debugger

First connect the night God simulator

adb connect 127.0.0.1:62001

Close Android_ server

kill -9 pid

Port forwarding

adb forward tcp:23946 tcp:23946

Static analysis and debugging

dalvik It is compiled at execution time+Running, fast installation, slow application startup, small application space
ART It is compiled at the time of installation and can be run directly at the time of execution. The installation is slow, the application is opened quickly and takes up a lot of space
fd File descriptor
  • Port 23946 detection
  • Process traversal detection
  • The parent process detects whether it contains zygote
  • Self process name detection, whether it is com Format of XXX
  • The number of threads is detected. Generally, there are more than a dozen threads. If you load one by yourself
  • /proc/pid/fd / number of detection files
  • Signal processing mechanism, IDA will intercept the signal
  • tracepid: debug the pid of the process
  • Built in API anti debugging
  • ptrace itself to see if it is successful
  • hash detection
  • BKPT instruction query
  • Read the status or stat of the process to detect the tracepid. The tracepid field is the pid of the tracking process Tracepid is not 0 in debugging state
  • One step debugging trap is a bit like Debugger Blocker under Windows
  • Flower instruction
  • Time difference detection
  • Process information query
First:
/proc/pid/status
/proc/pid/task/pid/status
TracerPid Not 0
statue Write in field t(tracing stop)
Second:
/proc/pid/stat
/proc/pid/task/pid/stat
 The second field is t(T)
Third:
/proc/pid/wchan
/proc/pid/task/pid/wchan
ptrace_stop
  • You can monitor the opening or accessing events of mem or pagemap through Inotify series APIs, and end the process once the time occurs to prevent dump.

The key function name was not found, possibly due to JNI_OnLoad to dynamically register

Find JNI_OnLoad function, import header file structure

At this point, you can see that the anti debugging is the anti debugging of traversal process

Dynamic registration function in data. rel. ro. In local section

Found a port detection debugged

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (IMG uoubinfb-1618733777075)( https://raw.githubusercontent.com/p1aymaker/picture/master/20210128025853.png )]

Look again init_array creates a thread with the following functions

It is also a de debugging

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-srlcgb5q-1618733777076)( https://raw.githubusercontent.com/p1aymaker/picture/master/20210128030158.png )]

xpose module

reference resources:

https://www.kancloud.cn/a6260362/study-android-and-web/1646986

Hook with different versions

Android 4.0.3-4.4: Dalvik
Android 5.0 above: ART

One of them stepped on a pit. There was a problem with the load mouse, resulting in the Hook failure

https://blog.csdn.net/OneT1me/article/details/93968206

You need to comment out the things in gradle

  // implementation files('libs\\api-82.jar')
    compileOnly 'de.robv.android.xposed:api:82'
    compileOnly 'de.robv.android.xposed:api:82:sources'
  • Compiled by: javac HelloWorld java
  • Packaging: all class files in a package are packaged into a jar file

conpileonly: only valid at compile time and will not participate in packaging

implementation: the dependent library will participate in compilation and packaging. The dependent library will not be passed, but will only take effect in the current module

public class HookMain implements IXposedHookLoadPackage {
    public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
         //Fixed format
        findAndHookMethod(
                "android.telephony.TelephonyManager",  //Package name + class name to hook
                lpparam.classLoader,                   //classLoader fixed
                "getDeviceId",                         //Method name to hook
                                                       //If there are no method parameters, do not fill them in
                new XC_MethodHook() {
                    @Override
                    //Execute before method execution
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    }
                    //After the method is executed, the return value of the modified method must be changed after the method is executed
                    protected void afterHookedMethod(MethodHookParam param)
                            throws Throwable {
                        param.setResult("355888888888888");
 
                    }
                }
        );
 
 
    }
}

Generally, the program is run first, and then the Xposed module is loaded

Play Hook

import android.content.Context;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import de.robv.android.xposed.XposedHelpers;

public class HookMain implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        // XposedBridge.log("=========Loaded app: " + lpparam.packageName);
        if (lpparam.packageName.equals("com.jimmy.beauty.pick")) {
            XposedHelpers.findAndHookMethod("com.jimmy.beauty.pick.Util", lpparam.classLoader, "getMoney",
                    Context.class,
                    XC_MethodReplacement.returnConstant(100));
        }
    }
}

Xposed principle

The parent process of Android process - Zygote (incubation) process. The startup configuration of this process is in / init RC script, and the corresponding executable file of Zygote process is / system/bin/app_process

It is an app implemented by itself_ Process replaces the app originally provided by the system_ Process * *, load an additional jar package, and then import from the original com android. internal. osZygoteInit. Main () was replaced by de.robv android. xposed. XposedBridge. main()

testing

https://tech.meituan.com/2018/02/02/android-anti-hooking.html

  • The API of PackageManager is used to traverse the installation of apps in the system to identify whether there are software packages related to Xposed Installer installed
  • The self-made exception reads the stack to detect whether there is an Xposed calling method
  • Did the java method become a Native JNI method
  • XposedHelper
  • "/ proc/self/maps" detection