---
# System prepended metadata

title: Write-up picoCTF - droids

---

# Write-up picoCTF - droids

## droids 0
![image](https://hackmd.io/_uploads/BkAZh1NBbe.png)

Xem source code bằng `jadx`.

![image](https://hackmd.io/_uploads/B1Ih2y4rZg.png)
`Log.i("PICO", paprika(input))` in kết quả của paprika(input) ra logcat.

```java
public void buttonClick(View view) {
        String content = this.text_input.getText().toString();
        this.text_bottom.setText(FlagstaffHill.getFlag(content, this.ctx));
    }
```
Nhấn button trong `MainActivity` sẽ in ra flag trong log.
Mở logcat ra để xem dùng lệnh: `adb logcat`.
![image](https://hackmd.io/_uploads/ByngAJ4rbe.png)

## droids 1

![image](https://hackmd.io/_uploads/SynbAkNSWx.png)

Decomplie file bằng `apktool` rồi tìm password ở `res/values/strings.xml`.
![image](https://hackmd.io/_uploads/ByerRJEr-x.png)
![image](https://hackmd.io/_uploads/SyNHAyErWe.png)

## droids 2
![image](https://hackmd.io/_uploads/HJSLAJVBZe.png)
![image](https://hackmd.io/_uploads/B1zw0kNBWx.png)
`FlagstaffHill` xử lý password bằng logic đơn giản.

```python
def solve_password():
    witches = ["weatherwax", "ogg", "garlick", "nitt", "aching", "dismass"]

    second = 3 - 3          
    third = (3 // 3) + second   
    fourth = (third + third) - second 
    fifth = 3 + fourth          
    sixth = (fifth + second) - third  
    indices = [fifth, third, second, sixth, 3, fourth]
    password = ".".join([witches[i] for i in indices])

    print(f"{password}")

if __name__ == "__main__":
    solve_password()
```

![image](https://hackmd.io/_uploads/r1UGJgErbx.png)

## droids 3

![image](https://hackmd.io/_uploads/H1ZE1e4rZe.png)
![image](https://hackmd.io/_uploads/SJr8kgNrZg.png)
Trong `FlagstaffHill` hàm `yep()` xử lý input nhưng không được gọi. Nơi xử lý logic password là `native` cụ thể là hàm `cilantro()`.
Decomplie file bằng `apktool`.
Mở `lib/x86/libhellojni.so` bằng IDA hoặc ghidra.

![image](https://hackmd.io/_uploads/SJx16gl4Bbx.png)

`dill(v7)` check input nếu input đúng thì gọi `sumac()` để trả flag.
![image](https://hackmd.io/_uploads/SkombxEBbx.png)
![image](https://hackmd.io/_uploads/ryeV-xEBbg.png)
![image](https://hackmd.io/_uploads/HkI4blNHZg.png)
![image](https://hackmd.io/_uploads/H1kSbxNBWg.png)

```python
def solve():
    #.rodata (unk_1C41)
    encrypted_data = [
        0x11, 0x0E, 0x02, 0x06, 0x2D, 0x39, 0x2F, 0x08, 0x07, 0x00, 
        0x1D, 0x49, 0x03, 0x12, 0x15, 0x47, 0x0F, 0x43, 0x1A, 0x10, 
        0x01, 0x08, 0x1A, 0x04, 0x09, 0x1A
    ]
    key = "againmissing"
    key_bytes = [ord(c) for c in key]
    key_len = len(key_bytes)
    
    flag = ""
    for i in range(len(encrypted_data)):
        char_code = encrypted_data[i] ^ key_bytes[i % key_len]
        flag += chr(char_code)
    
    print(f"{flag}")

if __name__ == "__main__":
    solve()
#picoCTF{tis.but.a.scratch}
```

## droids 4

![image](https://hackmd.io/_uploads/Skg9blNS-e.png)
![image](https://hackmd.io/_uploads/HJLcWgEBZg.png)
`FlagstaffHill` cho password là `alphabetsoup` nhưng nhìn về `return` thì nếu nhập đúng password thì nó chỉ trả về `call it`. 
![image](https://hackmd.io/_uploads/B1pxMeVr-e.png)
Hàm `cardamom()` không được gọi nên làm tương tự câu trên.
Mở file `lib/x86/libhellojni.so` bằng IDA.
![image](https://hackmd.io/_uploads/BkopMeNBbx.png)
![image](https://hackmd.io/_uploads/BJsCMx4BWg.png)
Reverse ra key của hàm `chervil()`
`v6` khởi tạo là `aaa` 
`v5`, `v4`, `v3` cũng được khởi tạo từ một vùng nhớ cố định (`strdup` sao chép chuỗi từ vùng nhớ gốc sang một vùng nhớ mới heap). Do cả 3 biến `v5`, `v4`, `v3` đều lấy dữ liệu từ cùng một phép tính `offset`, nên chúng đều bắt đầu bằng `aaa`. Cuối cùng cộng các kí tự trong mảng lại sau khi thay đổi logic. 
```python
def reverse_chervil():
    base = "aaa"

    def shift(s, ops):
        s = list(s)
        for idx, val in ops.items():
            s[idx] = chr(ord(s[idx]) + val)
        return "".join(s)

    v6 = shift(base, {0: 4, 1: 19, 2: 18})   # ets
    v5 = shift(base, {0: 7, 2: 1})           # hab
    v4 = shift(base, {1: 11, 2: 15})          # alp
    v3 = shift(base, {0: 14, 1: 20, 2: 15})   # oup
    password = v4 + v5 + v6 + v3
    return password


if __name__ == "__main__":
    print(reverse_chervil())
#alphabetsoup
```
![image](https://hackmd.io/_uploads/ryH4Qg4B-g.png)
![image](https://hackmd.io/_uploads/By8kXeNrWx.png)
![image](https://hackmd.io/_uploads/BkVg7xErZg.png)

Logic cũng tương tự câu trên nếu `chervil()` check input đúng thì `pepper()` sẽ được gọi và trả flag.

```python
def solve_final_flag():
    #.rodata:00001C5C
    encrypted_data = [
        0x11, 0x05, 0x13, 0x07, 0x22, 0x36, 0x23, 0x0F, 
        0x1D, 0x00, 0x01, 0x5E, 0x11, 0x0D, 0x02, 0x1C, 
        0x08, 0x01, 0x10, 0x18, 0x12, 0x1D, 0x19, 0x09, 
        0x4F, 0x1F, 0x19, 0x04, 0x0D, 0x1B, 0x18
    ]
    key = "alphabetsoup"
    key_bytes = [ord(c) for c in key]
    key_len = len(key_bytes)
    
    flag = ""
    for i in range(len(encrypted_data)):
        char_code = encrypted_data[i] ^ key_bytes[i % key_len]
        flag += chr(char_code)
    
    print(f"{flag}")

if __name__ == "__main__":
    solve_final_flag()
#picoCTF{not.particularly.silly}
```