Wargame

[Mobile] Androgoat_Root detection 문제풀이

작성자 - 현우는 5살

[Mobile] Androgoat_Root detection 문제풀이

목차

  • 실행 확인
  • jadx(디컴파일 후 문제 분석)
  • 문제풀이 (Frida Script 작성)

실행확인

- Androgoat_Root detection의 문제를 확인

문제

1. Undersstand what is Rooting

2. How app can detection if device is Rooted?

3. Bypass Root Detection using

3_1. RootCloack(github 기준 9년전 업데이트를 멈춤) 예외

3_2. Repackaging

3_3. Frida

먼저 CheckRoot버튼을 눌러 확인해본 결과  Device is rooted라는 토스트와 함께 루팅이 탐지되었다는 사실을 확인할 수 있습니다.

 

1.Undersstand what is Rooting?
먼저 루팅이란 휴대폰의 기기에서 root권한을 취득하는 행위를 의미합니다. Android상에서 Odin이라는 기기를 통해서 루팅을 진행할 수 있으며, IOS 상에서는 iOS16.5.5이하의 버전(2025.08.31일 기준)에서 탈옥이라는 행위를 통해 루트권한을 취득할 수 있습니다.


jadx(디컴파일 후 문제 분석)

- jadx 어플을 통해 디컴파일 후 문제를 분석한다.

먼저 Androgoat의 AndroidManifest.xml 파일을 분석합니다.

        <activity
            android:label="@string/app_name"
            android:name="owasp.sat.agoat.MainActivity"/>
        <activity
            android:label="@string/root"
            android:name="owasp.sat.agoat.RootDetectionActivity"/>

 

에서 맨 AndroidManifest에서 확인 가능한 MainActivity와 RootDetectionActivity(문제 관력 엑티비티로 추정)를 분석합니다.

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((Button) _$_findCachedViewById(R.id.rootButton1)).setOnClickListener(new View.OnClickListener() { // from class: owasp.sat.agoat.MainActivity.onCreate.1
            @Override // android.view.View.OnClickListener
            public final void onClick(View it) {
                MainActivity.this.startActivity(new Intent(MainActivity.this, (Class<?>) RootDetectionActivity.class));
            }
        });

MainActivity상의 코드상에서 저희가 확인할 수 있는 부분은 여러개의 버튼을 클릭하면, 각 액티비티로 이동할 수 있다는 사실을 확인할 수 있습니다. 문제와 관련이 있는 RootDetectionActivity를 확인합니다.

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_root_detection);
        Button rootBt = (Button) findViewById(R.id.rootCheck);
        rootBt.setOnClickListener(new View.OnClickListener() { // from class: owasp.sat.agoat.RootDetectionActivity.onCreate.1
            @Override // android.view.View.OnClickListener
            public final void onClick(View it) {
                if (RootDetectionActivity.this.isRooted()) {
                    Toast.makeText(RootDetectionActivity.this.getApplicationContext(), "Device is rooted", 1).show();
                } else {
                    Toast.makeText(RootDetectionActivity.this.getApplicationContext(), "Device is not rooted", 1).show();
                }
            }
        });
    }

코드상에서 이 클래스상에서 호출된 isRooted()함수의 값을 받아와 탐지하는 사실을 확인할 수 있습니다.

    public final boolean isRooted() {
        String[] file = {"/system/app/Superuser/Superuser.apk", "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su", "/data/local/su", "/su/bin/su", "re.robv.android.xposed.installer-1.apk", "/data/app/eu.chainfire.supersu-1/base.apk"};
        boolean result = false;
        for (String files : file) {
            File f = new File(files);
            result = f.exists();
            if (result) {
                break;
            }
        }
        return result;
    }

isRooted를 확인해본결과 file 리스트 상에 경로의 파일을 확인된다면, 루팅으로 판별되는 사실을 확인할 수 있습니다.

2. How app can detection if device is Rooted?

{"/system/app/Superuser/Superuser.apk", "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su", "/data/local/su", "/su/bin/su", "re.robv.android.xposed.installer-1.apk", "/data/app/eu.chainfire.supersu-1/base.apk"}

경로상의 각 파일이 있을경우 루팅으로 판별

 


문제 풀이 (Frida script)

- Frida Script를 통해 우회 진행(3-3 Frida)

Java.perform(function(){
    console.log("디버깅 시작");

     try {
        const RootActivity = Java.use('owasp.sat.agoat.RootDetectionActivity');

        RootActivity.isRooted.implementation = function(){
            const result = this.isRooted();
            console.log(result);
            return result;
        }
            } catch (e) {
        console.log("오류 발생:", e);
    }
});

제가 작성한 Frida코드를 기반으로 isRooted의 결과값을 확인합니다.

frida-ps를 통해서 PID를 확인 후에 터미널에서 attach 진행합니다.

에서 클릭을하면 true가 나오는 사실을 확인할 수 있습니다. 코드상에서 루팅이 되어있다면 true가 뜬다고 명시되어 있었기에 이 부분은 충분히 짐작할 수 있습니다. 이제 여기서 return 값을 implementation을 통해서 false로 바꿔보겠습니다.

Java.perform(function(){
    console.log("디버깅 시작");

     try {
        const RootActivity = Java.use('owasp.sat.agoat.RootDetectionActivity');

        RootActivity.isRooted.implementation = function(){
            const result = false;
            return result;
        }
            } catch (e) {
        console.log("오류 발생:", e);
    }
});

를 통해서

Frida를 통해서 루팅을 우회할 수 있습니다.

'Wargame' 카테고리의 다른 글

[HackTheBox] APKey  (1) 2025.04.30
DFC 2024 : 301 - App Sleuth  (0) 2025.03.31
[Malware Bytes] Sample 악성코드 분석  (0) 2025.02.28
DFC 2024 : 205 - Analyze Drone Log File  (0) 2025.02.20
Contents

이 글이 도움이 되었다면, 응원의 댓글 부탁드립니다.