# PicoCTF - droids4
## Background
[ Android App 逆向入門之一:拆開與重組 apk ](https://blog.huli.tw/2023/04/27/android-apk-decompile-intro-1/)
[ Android App 逆向入門之二:修改 smali 程式碼 ](https://blog.huli.tw/2023/04/27/android-apk-decompile-intro-2/)
## Source code
```java
package com.hellocmu.picoctf;
import android.content.Context;
/* loaded from: classes.dex */
public class FlagstaffHill {
public static native String cardamom(String str);
public static String getFlag(String input, Context ctx) {
StringBuilder ace = new StringBuilder("aaa");
StringBuilder jack = new StringBuilder("aaa");
StringBuilder queen = new StringBuilder("aaa");
StringBuilder king = new StringBuilder("aaa");
ace.setCharAt(0, (char) (ace.charAt(0) + 4));
ace.setCharAt(1, (char) (ace.charAt(1) + 19));
ace.setCharAt(2, (char) (ace.charAt(2) + 18));
jack.setCharAt(0, (char) (jack.charAt(0) + 7));
jack.setCharAt(1, (char) (jack.charAt(1) + 0));
jack.setCharAt(2, (char) (jack.charAt(2) + 1));
queen.setCharAt(0, (char) (queen.charAt(0) + 0));
queen.setCharAt(1, (char) (queen.charAt(1) + 11));
queen.setCharAt(2, (char) (queen.charAt(2) + 15));
king.setCharAt(0, (char) (king.charAt(0) + 14));
king.setCharAt(1, (char) (king.charAt(1) + 20));
king.setCharAt(2, (char) (king.charAt(2) + 15));
String password = "".concat(queen.toString()).concat(jack.toString()).concat(ace.toString()).concat(king.toString());
return input.equals(password) ? "call it" : "NOPE";
}
}
```
## Recon
基本上用眼睛看應該看的出來password是啥,不過他最後只會print出`call it`或是`NOPE`,所以我們要像上一題一樣改造一下smali,可以對照一下前一題的smali是怎麼call的
## Exploit
* 前一題的FlagstaffHill和smali
```java
package com.hellocmu.picoctf;
import android.content.Context;
/* loaded from: classes.dex */
public class FlagstaffHill {
public static native String cilantro(String str);
public static String nope(String input) {
return "don't wanna";
}
public static String yep(String input) {
return cilantro(input);
}
public static String getFlag(String input, Context ctx) {
String flag = nope(input);
return flag;
}
}
```
:::spoiler smali
```smali!
.class public Lcom/hellocmu/picoctf/FlagstaffHill;
.super Ljava/lang/Object;
.source "FlagstaffHill.java"
# direct methods
.method public constructor <init>()V
.locals 0
.line 6
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static native cilantro(Ljava/lang/String;)Ljava/lang/String;
.end method
.method public static getFlag(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;
.locals 1
.param p0, "input" # Ljava/lang/String;
.param p1, "ctx" # Landroid/content/Context;
.line 19
invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->yep(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
.line 20
.local v0, "flag":Ljava/lang/String;
return-object v0
.end method
.method public static nope(Ljava/lang/String;)Ljava/lang/String;
.locals 1
.param p0, "input" # Ljava/lang/String;
.line 11
const-string v0, "don\'t wanna"
return-object v0
.end method
.method public static yep(Ljava/lang/String;)Ljava/lang/String;
.locals 1
.param p0, "input" # Ljava/lang/String;
.line 15
invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->cilantro(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
return-object v0
.end method
```
:::
所以我們只要像前一題一樣,把input丟到yep然後在call cardamon這個method應該就可以了,所以具體來說就是新增`yep`這個method
```java!
.method public static yep(Ljava/lang/String;)Ljava/lang/String;
.locals 1
.param p0, "input" # Ljava/lang/String;
.line 15
invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->cardamom(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
return-object v0
.end method
```
然後把最後getFlag的return改掉,變成:
```java!
.line 36
invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->yep(Ljava/lang/String;)Ljava/lang/String;
move-result-object v5
return-object v5
```
:::spoiler Completely FlagstaffHill.smali
```java!
.class public Lcom/hellocmu/picoctf/FlagstaffHill;
.super Ljava/lang/Object;
.source "FlagstaffHill.java"
# direct methods
.method public constructor <init>()V
.locals 0
.line 6
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static native cardamom(Ljava/lang/String;)Ljava/lang/String;
.end method
.method public static getFlag(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;
.locals 8
.param p0, "input" # Ljava/lang/String;
.param p1, "ctx" # Landroid/content/Context;
.line 12
new-instance v0, Ljava/lang/StringBuilder;
const-string v1, "aaa"
invoke-direct {v0, v1}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
.line 13
.local v0, "ace":Ljava/lang/StringBuilder;
new-instance v2, Ljava/lang/StringBuilder;
invoke-direct {v2, v1}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
.line 14
.local v2, "jack":Ljava/lang/StringBuilder;
new-instance v3, Ljava/lang/StringBuilder;
invoke-direct {v3, v1}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
.line 15
.local v3, "queen":Ljava/lang/StringBuilder;
new-instance v4, Ljava/lang/StringBuilder;
invoke-direct {v4, v1}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
move-object v1, v4
.line 17
.local v1, "king":Ljava/lang/StringBuilder;
const/4 v4, 0x0
invoke-virtual {v0, v4}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v5
add-int/lit8 v5, v5, 0x4
int-to-char v5, v5
invoke-virtual {v0, v4, v5}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 18
const/4 v5, 0x1
invoke-virtual {v0, v5}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v6
add-int/lit8 v6, v6, 0x13
int-to-char v6, v6
invoke-virtual {v0, v5, v6}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 19
const/4 v6, 0x2
invoke-virtual {v0, v6}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/lit8 v7, v7, 0x12
int-to-char v7, v7
invoke-virtual {v0, v6, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 21
invoke-virtual {v2, v4}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/lit8 v7, v7, 0x7
int-to-char v7, v7
invoke-virtual {v2, v4, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 22
invoke-virtual {v2, v5}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/2addr v7, v4
int-to-char v7, v7
invoke-virtual {v2, v5, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 23
invoke-virtual {v2, v6}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/2addr v7, v5
int-to-char v7, v7
invoke-virtual {v2, v6, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 25
invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/2addr v7, v4
int-to-char v7, v7
invoke-virtual {v3, v4, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 26
invoke-virtual {v3, v5}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/lit8 v7, v7, 0xb
int-to-char v7, v7
invoke-virtual {v3, v5, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 27
invoke-virtual {v3, v6}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/lit8 v7, v7, 0xf
int-to-char v7, v7
invoke-virtual {v3, v6, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 29
invoke-virtual {v1, v4}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v7
add-int/lit8 v7, v7, 0xe
int-to-char v7, v7
invoke-virtual {v1, v4, v7}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 30
invoke-virtual {v1, v5}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v4
add-int/lit8 v4, v4, 0x14
int-to-char v4, v4
invoke-virtual {v1, v5, v4}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 31
invoke-virtual {v1, v6}, Ljava/lang/StringBuilder;->charAt(I)C
move-result v4
add-int/lit8 v4, v4, 0xf
int-to-char v4, v4
invoke-virtual {v1, v6, v4}, Ljava/lang/StringBuilder;->setCharAt(IC)V
.line 33
invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v4
const-string v5, ""
invoke-virtual {v5, v4}, Ljava/lang/String;->concat(Ljava/lang/String;)Ljava/lang/String;
move-result-object v4
invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v5
invoke-virtual {v4, v5}, Ljava/lang/String;->concat(Ljava/lang/String;)Ljava/lang/String;
move-result-object v4
.line 34
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v5
invoke-virtual {v4, v5}, Ljava/lang/String;->concat(Ljava/lang/String;)Ljava/lang/String;
move-result-object v4
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v5
invoke-virtual {v4, v5}, Ljava/lang/String;->concat(Ljava/lang/String;)Ljava/lang/String;
move-result-object v4
.line 36
invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->yep(Ljava/lang/String;)Ljava/lang/String;
move-result-object v5
return-object v5
.end method
.method public static yep(Ljava/lang/String;)Ljava/lang/String;
.locals 1
.param p0, "input" # Ljava/lang/String;
.line 15
invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->cardamom(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
return-object v0
.end method
```
:::
在用apktool打包,在簽名和align就可以丟到Android Studio了
```bash!
$ apktool b four -o four_new.apk
$ java -jar ./uber-apk-signer-1.1.0.jar --apks four_new.apk
```

Flag: `picoCTF{not.particularly.silly}`