How to hook and patch Android Apps Using Cydia Substrate – VulnerApp

บทนำ (Overview)

บทความนี้จะกล่าวถึงวิธีการ “Bypass” หน้า “login” โดยใช้วิธีการปรับเปลี่ยนค่า “return” ของ “function” ที่เกี่ยวข้องกับ “login” โดยจำเป็นต้องใช้วิธีการเรียกว่าการ “Hook Method/Functions” แต่การจะทำได้นั้นจำเป็นต้องมี “Framework” ช่วยซึ่งเราเรียกมันว่า “Cydia Substrate”

สรุปหลักการคร่าว ๆ คือ เราจะต้องการต้องหา “method” ที่ต้องการเปลี่ยนค่า “return” ซึ่งสามารถทราบได้จากการทำ “Reverse engineering” จากนั้นทำการเขียน “code” เพื่อเปลี่ยนค่าดังกล่าว เมื่อเสร็จสิ้น ใช้งาน code ที่เราเขียนมาเพื่อ “modify code” ตอน “run-time” และ “restart” สุดท้ายทดสอบโปรแกรมที่เป็นช่องโหว่ 

ขั้นตอน (Steps)

Emulator

  1. ติดตั้ง “Emulator” จากการทดสอบพบว่า “Droid4x” บน “Mac” และ Droidx4 version เก่า ๆ บน “Windows” สามารถติดตั้ง “Cydia Substrate” ใช้งานได้ (ติดตามวิธีติดตั้ง “Droid4x” ได้ที่บทความ How to install droid4x)

Cydia Substrate

  1. ติดตั้ง Cydia Substrate บน “Emulator” อย่างไรก็ตาม “Cydia Substrate” สามารถติดตั้งได้บน “Android 2.3 – 4.3” แต่ก็ไม่ทุก “Emulator” จะติดตั้งได้เช่นกัน

Android Studio

  1. ดาวน์โหลดและติดตั้ง Android Studio

Android Substrate SDK

  1. จากนั้นเราจะติดตั้ง Android Substrate SDK
  2. ไปที่เมนู “SDK Manager”android-code-injecion-03
  3. ไปที่ “Tab” ชื่อ “SDK Update Sites” กด + แล้วใส่ URL เป็น http://asdk.cydiasubstrate.com/addon.xml เมื่อเสร็จสิ้นให้กดปุ่ม “Apply”android-code-injecion-04
  4. กลับมาที่ “Tap” ชื่อ “SDK Tools” มองหา “Cydia Substrate API” จากนั้นกด “Apply” เมื่อปรากฏหน้าต่าง “Confirm Change” ให้กด “OK”android-code-injecion-05
  5. รอดาวน์โหลดจนเสร็จสิ้น แล้วกดปุ่ม “Finish”android-code-injecion-06
  6. เปลี่ยนมุมมอง “Project” android-code-injecion-07
  7. จากนั้นไปที่โฟลเดอร์ “app/libs” แล้วให้ลากไฟล์ “substrate-api.jar” เข้ามา จะปรากฏหน้าต่าง “Move” จากนั้นกดปุ่ม “OK”android-code-injecion-08
  8. ปรากฏหน้าต่าง “Non-Project Files Access” ให้กดปุ่ม “OK”android-code-injecion-09
  9. จากนั้นคลิกขวาที่ไฟล์ “substrate-api.jar” แล้วเลือกที่ “Add As Library” android-code-injecion-10
  10. จะปรากฏหน้าต่าง “Create Library” ให้กดปุ่ม “OK”android-code-injecion-11
  11. ถ้าปรากฏดังรูปถือว่าเสร็จสิ้นandroid-code-injecion-12

VulnerApp

  1. ดาวน์โหลดโปรแกรมช่องโหว่ “VulnerApp” จากนั้นติดตั้งบน “Emulator”
  2. ทดลองเปิดใช้งานโปรแกรม จะพบหน้า “Login” ให้ “Login” โดยใช้ “Account” ข้างล่าง จะสามารถผ่านไปหน้า “Home” ได้
    Username = admin
    Password = Password
    

    android-code-injecion-01

  3. ที่นี้ถ้าไม่ใส่ “Username” และ “Password” แล้ว “Submit” ก็จะไม่สามารถ “Login” ไปหน้า “Home”
  4. จากนั้นให้ “Convert Byte-code” ให้อ่านออกให้ได้ก่อนเพื่อตรวจสอบ “Source-code” ของหน้า “Login” (สามารถติดตามบทความสำหรับ Convert Bytecode ได้ที่)
  5. มี “Code” ที่น่าสนใจคือ “Class” ที่ชื่อ “LoginActivity” ซึ่งน่าจะเดาได้ว่าคือหน้า “Login” นั้นมี “Method” ที่ชื่อว่า “isLogin” มีการคืนค่า “True” หรือ “False”
    public boolean isLogin(String paramString1, String paramString2)
    {
    //Backdoor admin and password
    String str1 = "admin";
    String str2 = "password";
    return (paramString1.contentEquals(str1)) && (paramString2.contentEquals(str2));
    }
    
  6. ซึ่งคืนไปยังปุ่ม “Submit” ที่เกิดจากการ “Login” จากนั้นถ้าค่าคืนเป็น “True” จะสามารถข้ามไปยังหน้า “Home” ได้
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_login);
    
            txtUser = (EditText)findViewById(R.id.txtLogin2);
            txtPass = (EditText)findViewById(R.id.txtLogin3);
    
            final Button btn1 = (Button) findViewById(R.id.cmdLogin);
    
            btn1.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
    
                    if (isLogin(txtUser.getText().toString() , txtPass.getText().toString())) {
                        Intent i = new Intent(LoginActivity.this, HomeActivity.class);
                        startActivity(i);
                    }
            }
    });
    

Exploit code

  1. ที่นี้จะเริ่มเขียน “Code” สำหรับปรับเปลี่ยนค่าส่งคืนกัน โดยสมมติถ้าเราไม่ทราบ “Username” และ “Password” เราก็ต้องเปลี่ยนค่าส่งคืนของ “Method” ที่ชื่อ “isLogin” จาก “False” เป็น “True” ถึงจะสามารถไปหน้า “Home” ได้
  2. โดยเริ่มแรกเราจะต้องเพิ่ม “Permission” ให้กับโปรแกรมเราสามารถใช้งาน “Cydia Substrate” ได้ก่อนโดยเพิ่มใน “AndroidManifest.xml” ดังนี้ (ดูรายละเอียดเพิ่มเติมได้ที่ http://www.cydiasubstrate.com/inject/dalvik/) โดยให้ Syntax อยู่ก่อน application
    <uses-permission android:name="cydia.permission.SUBSTRATE" />
    
  3. และเพิ่มระหว่าง application
    <application>
         <meta-data android:name="com.saurik.substrate.main" android:value=".BypassLoginSubstrate" />
    </application>
    
  4. จะได้ดังตัวอย่าง android-code-injecion-02
  5. จากนั้นเราจะมาใส่ “code” สำหรับ “Bypass” หน้า “Login” โดยให้อยู่ใน “Method” ชื่อ “initialize”
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import java.lang.reflect.Method;
    import com.saurik.substrate.*;
    
    static void initialize() {
        MS.hookClassLoad("com.example.wsunpachit.vulnerapp.LoginActivity", new MS.ClassLoadHook() {
                @SuppressWarnings({"unchecked", "rawtypes" })
    
                public void classLoaded(Class<?> resources) {
                    Method methodToHook;
    
                    try{
                        methodToHook = resources.getMethod("isLogin", String.class, String.class);
                    }catch(NoSuchMethodException e){
                        methodToHook = null;
                    }
    
                    if (methodToHook == null) {
                        Log.v("cydia","No method found");
                    }
    
                    else{
                        MS.hookMethod(resources, methodToHook, new MS.MethodAlteration&lt;Object, Boolean&gt;() {
                            public Boolean invoked(Object _class, Object... args) throws Throwable
                            {
                                return true;
                            }
                        });
                    }
                }
       });
    }
    
  6. จาก “code” ข้างต้นมีฟังก์ชันที่สำคัญดังนี้
    //เป็น function สำหรับ Load class ที่มี Method ที่เราสนใจจะเปลี่ยนแปลงค่า return
    MS.hookClassLoad("com.example.wsunpachit.vulnerapp.LoginActivity", new MS.ClassLoadHook() {
          @SuppressWarnings({"unchecked", "rawtypes" })
          public void classLoaded(Class<?> resources) {
             // ... code to modify the class when loaded
          }
    });
    
    //เป็นฟังก์ชันสำหรับเปลี่ยนแปลงค่าของ Method ที่เราสนใจ
    public void classLoaded(Class<?> resources) {
          Method methodToHook;
          try{
                methodToHook = resources.getMethod("isLogin", String.class, String.class);
          }catch(NoSuchMethodException e){
                methodToHook = null;
          }
    
          if (methodToHook == null) {
               Log.v("cydia","No method found");
          }
          else{
                 MS.hookMethod(resources, methodToHook, new MS.MethodAlteration&lt;Object, Boolean&gt;() {
                 public Boolean invoked(Object _class, Object... args) throws Throwable
                   {
                      return true;
                   }
                 });
          }
     }
    
  7. ในส่วนของการเรียกใช้ “Method” ที่ต้องการเปลี่ยนแปลงแก้ไขค่านั้น เราจะต้องระบุ “Method” ที่ต้องการแก้ไข และระบุ “Parameter” ที่จะต้องส่งเข้าไปด้วย (ถ้ามี) ซึ่งก็คือ “username” และ “password” ซึ่งทั้งคู่เป็นข้อมูลประเภท “String” เพราะฉะนั้นเราสามารถนิยาม “Class” ได้ดังนี้
    methodToHook = resources.getMethod("isLogin", String.class, String.class);
    
  8. แล้วถ้าพบมี Method ดังกล่าวก็จะสามารถปรับเปลี่ยนค่าได้ตามต้องการดังนี้ จากตัวอย่างเราต้องการเปลี่ยนเป็น “True” เสมอทำให้ไม่จำเป็นต้องรู้ “username” และ “password”
    MS.hookMethod(resources, methodToHook, new MS.MethodAlteration&lt;Object, Boolean&gt;() {
         public Boolean invoked(Object _class, Object... args) throws Throwable
         {
              return true;
         }
    });
    
  9. ที่นี้ลองใช้งาน “Exploit code” ที่เราเขียนกันมา โดยกดปุ่ม “Bypass Login” android-code-injecion-13
  10. “Code” ในการ “Hook” ไปยัง “Function” ที่เราเขียนนั้นจะเกิดขึ้นเมื่อโหลดหน้านี้เสร็จแล้ว ที่นี้ให้เรา “Reboot” เครื่องหรือกดปุ่มตามภาพ android-code-injecion-14
  11. จากนั้นให้ไปที่โปรแกรมช่องโหว่ของเรา แล้วลอง กดปุ่ม “submit” เพื่อ “login” โดยไม่ต้องใส่ “username” และ “password” อะไรเลย ผลคือสามารถข้ามไปหน้าหลัง “login” ได้ android-code-injecion-15

 

ใส่ความเห็น