티스토리 뷰

CTF/App

[2016 HolyShield] SoundMeter

Notchicken 2017. 4. 11. 17:05

[2016 HolyShield] SoundMeter

주어진 APK 파일을 설치하여 실행하면 로그인 화면이 나온다.
APK의 Smali 코드 중 로그인 부분의 분기문을 수정하여
아이디 비밀번호를 틀려도 로그인이 되도록 바꿔보았다.

:cond_2
if-eq v0, v5, :cond_3
new-instance v0, Landroid/content/Intent;
iget-object v1, p0, Lme/daei/soundmeter/d;->a:Lme/daei/soundmeter/MainActivity;
const-class v2, Lme/daei/soundmeter/SecondActivity;
invoke-direct {v0, v1, v2}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
iget-object v1, p0, Lme/daei/soundmeter/d;->a:Lme/daei/soundmeter/MainActivity;
invoke-virtual {v1, v0}, Lme/daei/soundmeter/MainActivity;->startActivity(Landroid/content/Intent;)V
:goto_2
return-void
:cond_3
iget-object v0, p0, Lme/daei/soundmeter/d;->a:Lme/daei/soundmeter/MainActivity;
invoke-virtual {v0}, Lme/daei/soundmeter/MainActivity;->getApplicationContext()Landroid/content/Context;
move-result-object v0
const-string v1, "\ub85c\uadf8\uc778 \uc2e4\ud328" //로그인 실패
invoke-static {v0, v1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
goto :goto_2

값을 비교하여 다를 경우 로그인 실패로 넘기는 분기문을
같을 경우 넘기도록 수정하였다.


로그인을 하면 소리를 측정하여 일정 데시벨에서 문자열이 출력되는데, 대회의 Flag 형태인 HS{ 가 출력되는 것을 보고
데시벨이 정해진 값을 만족시킬 때, Flag값이 차례대로 출력될 것이라 예상할 수 있었다.


먼저, 데시벨을 확인하여 Flag를 출력해주는 SoundDiscView를 보았다.

protected void onDraw(Canvas paramCanvas)
  {
    super.onDraw(paramCanvas);
    if (this.f == null) {
      b();
    }
    this.e.setRotate(a(h.a), this.c / 2, this.d * 215 / 460);
    paramCanvas.drawBitmap(this.f, this.e, this.g);
    if ((h.a > 55.0F) && (h.a < 65.0F)) {
      paramCanvas.drawText("H", this.c / 2, this.d * 36 / 46, this.g);
    }
    if ((h.a > 65.0F) && (h.a < 70.0F)) {
      paramCanvas.drawText("HS", this.c / 2, this.d * 36 / 46, this.g);
    }
    if ((h.a > 70.0F) && (h.a < 80.0F)) {
      paramCanvas.drawText("HS{", this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 80) && ((int)h.a < 82)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 82) && ((int)h.a < 84)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 84) && ((int)h.a < 86)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 86) && ((int)h.a < 88)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 88) && ((int)h.a < 90)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 91) && ((int)h.a < 93)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 94) && ((int)h.a < 96)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 97) && ((int)h.a < 99)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 104) && ((int)h.a < 106)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 108) && ((int)h.a < 110)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 110) && ((int)h.a < 112)) {
      paramCanvas.drawText("" + (char)(int)a.a((int)h.a), this.c / 2, this.d * 36 / 46, this.g);
    }
    if (((int)h.a > 113) && ((int)h.a < 115)) {
      paramCanvas.drawText("}", this.c / 2, this.d * 36 / 46, this.g);
    }
  }

데시벨값이 70 < dB < 80 일 때, "HS{" 를 출력해주고,
그 이후엔 각각 81, 83, 85, 87, 89, 92, 95, 98, 105, 109, 111, 114( "}" ) 일 때 
a 클래스에 값을 넘기고 리턴값을 Flag를 출력해주는 것을 알 수 있다.


package me.daei.soundmeter;
/* renamed from: me.daei.soundmeter.a */
public class C0308a {
    public static float m2871a(float f) {
        int i = 0;
        char[] cArr = new char[]{'Z', '\u000e', '\u0011', '\u000b', '\f', '\u0006', '\u001d', '\u001c', '\'', '.', '*', ')', '6', '@', '?', 'P', 'N', 'L', 'G', '=', ':', ',', '\u001f', '\u0010', '\u0013', '\u0001', '\u0004', '-', '9', 'E', 'O', 'R', 'V', 'Q', 'S', '\\', ']', ';', '1', '!', '\u0016', '\r', '\n', '\u0012', '\u0003', '\u0000', '\u0005', '<', '>', 'F', 'K', 'J', 'W', '[', '4', '\u001b', '\u001a', '2', '/', 'C', 'H', 'X', '\u0002', '\t', '\b', '\u0007', '+', '(', '7', 'M', 'T', 'U', '\u0014', '%', '5', '\u001e', '\"', 'A', 'D', 'I', '#', '\u0015', 'Y', '\u0018', '0', 'B', '\u0017', '\u000f', '&', '8', '\u0019', ' ', '$', '3'};
        char[] cArr2 = new char[]{'!', '@', '`', 'A', 'a', '\"', 'B', 'b', '#', 'C', 'c', 'd', 'D', '$', 'E', '%', 'e', 'F', 'f', '&', '\'', 'G', 'g', 'h', 'H', '(', ')', 'I', 'i', 'j', 'J', '*', '+', 'K', 'k', ',', 'l', 'L', '-', 'M', 'm', 'n', '.', 'N', 'O', 'o', '/', '0', '1', '2', 'P', 'p', 'Q', 'q', 'R', 'r', '3', 'S', 's', 't', 'T', '4', '5', '6', '7', '8', 'U', 'V', 'W', 'X', 'u', 'v', 'w', 'x', '9', 'Y', 'y', ':', 'Z', 'z', ';', '[', '{', '|', '\\', '<', '=', ']', '}', '_', '^', '~', '>', '?'};
        int i2 = 0;
        int i3 = 0;
        while (i2 < 1000 && ((int) f) != cArr2[i2]) {
            i3++;
            i2++;
        }
        float f2 = (float) i3;
        i2 = 33;
        while (i < 1000 && f2 != ((float) cArr[i])) {
            i2++;
            i++;
        }
        float f3 = (float) i2;
        return (((char) ((int) f3)) < '!' || ((char) ((int) f3)) > '/') ? (((char) ((int) f3)) < 'a' || ((char) ((int) f3)) > 'o') ? (((char) ((int) f3)) < 'A' || ((char) ((int) f3)) > 'O') ? (((char) ((int) f3)) < '0' || ((char) ((int) f3)) > ':') ? (((char) ((int) f3)) < 'P' || ((char) ((int) f3)) > 'Z') ? (((char) ((int) f3)) < 'p' || ((char) ((int) f3)) > 'z') ? f3 : f3 - 64.0f : f3 + 32.0f : f3 + 32.0f : f3 - 32.0f : f3 - 32.0f : f3 + 64.0f;
    }
}

a클래스 소스를 보면, 받은 데시벨값으로 정해진 연산을 거친 뒤 여러 조건을 따져 값을 리턴해주는 것을 알 수 있다.
그래서 a 클래스의 코드를 C로 구현하여 데시벨 값을 넘겨 Flag를 보기로 했다.


#include<stdio.h>
int a(float f){
         int i =0;
         int cArr[] ={90, 14, 17, 11, 12, 6, 29, 28, 39, 46, 42, 41, 54, 64, 63, 80, 78, 76, 71, 61, 58, 44, 31, 16, 19, 1, 4, 45, 57, 69, 79, 82, 86, 81, 83, 92, 93, 59, 49, 33, 22, 13, 10, 18, 3, 0, 5, 60, 62, 70, 75, 74, 87, 91, 52, 27, 26, 50, 47, 67, 72, 88, 2, 9, 8, 7, 43, 40, 55, 77, 84, 85, 20, 37, 53, 30, 34, 65, 68, 73, 35, 21, 89, 24, 48, 66, 23, 15, 38, 56, 25, 32, 36, 51 };
         int cArr2[] = {33, 64, 96, 65, 97, 34, 66, 98, 35, 67, 99, 100, 68, 36, 69, 37, 101, 70, 102, 38, 39, 71, 103, 104, 72, 40, 41, 73, 105, 106, 74, 42, 43, 75, 107, 44, 108, 76, 45, 77, 109, 110, 46, 78, 79, 111, 47, 48, 49, 50, 80, 112, 81, 113, 82, 114, 51, 83, 115, 116, 84, 52, 53, 54, 55, 56, 85, 86, 87, 88, 117, 118, 119, 120, 57, 89, 121, 58, 90, 122, 59, 91, 123, 124, 92, 60, 61, 93, 125, 95, 94, 126, 62, 63};
         int i2 = 0;
         int i3 = 0;
         while (i2 < 1000 && ((int) f) != cArr2[i2]){
                 i3++;
                 i2++;
         }
         float f2 = (float) i3;
         i2 = 33;
         while (i<1000 && f2 != ((float) cArr[i])){
                 i2++;
                 i++;
         }
         float f3 = (float)i2;
         return   (((char) ((int) f3)) < '!' || ((char) ((int) f3)) > '/') ? (((char) ((int) f3)) < 'a' || ((char) ((int) f3)) > 'o') ? (((char) ((int) f3)) < 'A' || ((char) ((int) f3)) > 'O') ? (((char) ((int) f3)) < '0' || ((char) ((int) f3)) > ':') ? (((char) ((int) f3)) < 'P' || ((char) ((int) f3)) > 'Z') ? (((char) ((int) f3)) < 'p' || ((char) ((int) f3)) > 'z') ? f3 : f3 - 64.0f : f3 + 32.0f : f3 + 32.0f : f3 - 32.0f : f3 - 32.0f : f3 + 64.0f;
}
void main(){
         printf("HS{%c%c%c%c%c%c%c%c%c%c%c%c}\n", a(81),a(83),a(85),a(87),a(89),a(90),a(95),a(98),a(105),a(109),a(111));
}

Flag: HS{w=6OsQ3BhD<}


'CTF > App' 카테고리의 다른 글

[CodeEngn] SmartApp 03  (0) 2017.04.22
[CodeEngn] SmartApp 02  (0) 2017.04.20
[CodeEngn] SmartApp 01  (0) 2017.04.20
[2016 SECCON] Rock Paper Scissors  (0) 2017.04.11
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday