Whitehat Contest 2018 PreQual - Grape (200 pts.)

Grape (Android)

먼저 디컴파일 후 살펴보면 두더지 게임이 있었다.

일단 점수 배점이 500, 1999, 201806를 기준으로 무슨 값을 출력해주기에 값을 변조해서 다 출력해보기로 했다.

1
2
3
4
5
public String m3185i() {
return this.f2076m < 500 ? getString(R.string.goal_1):
this.f2076m < 1999 ? getString(R.string.goal_2):
this.f2076m < 201806 ? getString(R.string.goal_3): getString(R.string.goal_4);
}

메모리 조작으로 손쉽게 값을 계속 바꿔주면서 모든 결과를 확인할 수 있었다.


Result

1
2
3
4
There is Not Enough Score
1st Hint: Can you manipulate a Broadcast Message?
2nd Hint: The 7th Receiver is Real
Key : Kings Never Die!

정보를 추합해보면 apk안에 receiver가 굉장히 많았는데 그 중 7번이 진짜고, 키가 Kings Never Die!라는 것을 알게 됐다.

Receiver007.java

1
2
3
4
5
6
7
8
9
10
public class Receiver007 extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.cyber.whitehat2018.hidden") &&
intent.getCategories().contains("android.intent.category.DEFAULT")) {
String a;
C0631a c0631a = new C0631a();
try {
a = C0631a.m3182a(context.getString(R.string.c7),
intent.getStringExtra("dkey"));
} /* 나머지 생략 */

C0631a은 그냥 단순히 AES 복호화를 해주는 코드다.

C0631a.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class C0631a {
public static byte[] IV = new byte[]{(byte) 0, (byte) 0,
(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
(byte) 0, (byte) 0, (byte) 0, (byte) 0};
public static String m3182a(String str, String str2) {
byte[] decode = Base64.decode(str, 0);
AlgorithmParameterSpec ivParameterSpec = new IvParameterSpec(IV);
Key secretKeySpec = new SecretKeySpec(str2.getBytes("UTF-8"), "AES");
Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");
instance.init(2, secretKeySpec, ivParameterSpec);
return new String(instance.doFinal(decode), "UTF-8");
}
}

R.string.c7의 값 i9bjnfNaIew5cZF0cVb5fagP8vWGf/WHjmdmzPJmAXM=base64decode하고 keyKings Never Die!, IV0000000000000000로 해서 AES복호화를 하면 된다.

1
2
3
4
5
6
7
>>> import base64
>>> from Crypto.Cipher import AES
>>> key = "Kings Never Die!"
>>> iv = "\x00" * 16
>>> obj = AES.new(key, AES.MODE_CBC, iv)
>>> obj.decrypt(base64.b64decode('i9bjnfNaIew5cZF0cVb5fagP8vWGf/WHjmdmzPJmAXM='))
'one summer d@y in june\n\n\n\n\n\n\n\n\n\n'

flag : one summer d@y in june

Share