리버싱CTF/mobisec

[MOBISEC] Pincode (10)

우와해커 2020. 7. 26. 18:24

Pincode (10)

MainActivity

메인엑티비티를 분석해보면 Pinchecker.checkPin() 매소드에서 Pin번호를 검증한다.
올바른 Pincode를 입력할 경우 검증 과정에서 사용되는 매소드들이 True가 계속 반환되며 화살표 순으로 진행된다.

그리고 최종적으로 서버와의 통신을 통해 Flag를 반환받을 수 있다.

핵심 로직은 Pincheck.checkPin() 매소드를 분석해보자.

 

[그림-1] MainActivity

PinChecker.checkPin()

PinChecker클래스의 checkPin 매소들를 분석해보면 Pin은 6글자이고 MD5로 다이제스트한 값이 "d04988522ddfed3133cc24fb6924eae9"과 동일해야한다는 것을 알 수 있다.

 

6글자의 숫자이기 때문에 브루트포스로 충분히 찾아낼 수 있겠다는 생각이 들었다.

if (pin.length() != 6) {
  return false;
}

try {
 byte[] pinBytes = pin.getBytes();
 for (int i = 0; i < 25; i++) {
     for (int j = 0; j < 400; j++) {
         MessageDigest md = MessageDigest.getInstance("MD5");
         md.update(pinBytes);
         pinBytes = (byte[]) md.digest().clone();
     }
 }

if (toHexString(pinBytes).equals("d04988522ddfed3133cc24fb6924eae9")) {
 return true;
}

간단한 방법으로 JADX의 코드를 로컬에서 사용할 수 있도록 Copy/paste 하고 checkPin의 값이 true가 나올때까지 while문을 실행하면 된다.

 

싱글스레드로 진행하였더니 약 30분이 소요되었다. .

 

[그림-2] 싱글스레드 테스트 코드 구현

 

 

하지만 너무 오래 걸렸다는 생각이 들어서 허접하지만 멀티스레드 코드를 구현하였다.

범위의 구간을 10개로 나누어서 멀티스레드를 실행하였더니 5분만에 Flag를 찾아낼 수 있었다.

특정 스레드가 Pincode를 찾을 경우 System.exit(0); 매소드를 실행하여 프로그램을 바로 종료시킨다.

import java.security.MessageDigest;
public class Main extends Thread{

int start;
int last;

Main(int start,int last){
    this.start = start;
    this.last = last;
}

public void run() {
   String str = new String();
    str = "";
    System.out.println("Let's get started: "+start+","+last);

    int i=start;
    int j=last;
    while(i<j){
        str=Integer.toString(i);

        if(checkPin(str)){
            System.out.println("Pin code:"+str);
            System.exit(0);
            break;
        }            
        i++;
    }  
    System.out.println("Nothing herer: "+start+","+last);
}

 public static boolean checkPin(String pin) {
    if (pin.length() != 6) {
        return false;
    }
    try {
        byte[] pinBytes = pin.getBytes();
        for (int i = 0; i < 25; i++) {
            for (int j = 0; j < 400; j++) {
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(pinBytes);
                pinBytes = (byte[]) md.digest().clone();
            }
        }
        if (toHexString(pinBytes).equals("d04988522ddfed3133cc24fb6924eae9")) {
            return true;
        }
        return false;
    } catch (Exception e) {
        System.out.println("Exception while checking pin");
        return false;
    }
}

public static String toHexString(byte[] bytes) {
    StringBuilder hexString = new StringBuilder();
    for (byte b : bytes) {
        String hex = Integer.toHexString(b & 255);
        if (hex.length() == 1) {
            hexString.append('0');
        }
        hexString.append(hex);
    }
    return hexString.toString();
}

public static void main(String[] args) {
    // TODO code application logic here
    int start=0, last=100000;
    for(int i=0;i<10;i++){
        Main myThread = new Main(start, last);
        myThread.start();
        start += 100000;
        last += 100000;
    }  
}
}//Main class

 

'리버싱CTF > mobisec' 카테고리의 다른 글

[MOBISEC] BabyRev (10)  (0) 2020.07.25