Pincode (10)
MainActivity
메인엑티비티를 분석해보면 Pinchecker.checkPin() 매소드에서 Pin번호를 검증한다.
올바른 Pincode를 입력할 경우 검증 과정에서 사용되는 매소드들이 True가 계속 반환되며 화살표 순으로 진행된다.
그리고 최종적으로 서버와의 통신을 통해 Flag를 반환받을 수 있다.
핵심 로직은 Pincheck.checkPin() 매소드를 분석해보자.
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분이 소요되었다. .
하지만 너무 오래 걸렸다는 생각이 들어서 허접하지만 멀티스레드 코드를 구현하였다.
범위의 구간을 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 |
---|