Bbbbloat
Writeupt6o_o6t.icon
まずはfileでファイル形式を確認
$ file bbbbloat
bbbbloat: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID..., for GNU/Linux 3.2.0, stripped fileの出力を読む
version 1 (SYSV)
シンボル情報は消失している
何もせずに実行する
このファイルが何を目的に書かれたファイルなのかを把握することが必要だから
$ chmod u+x ./bbbbloat
$ ./bbbbloat
What's my favorite number? 15
Sorry, that's not it!
入力値の判定のみを行っているみたい。
$ strings ./bbbbloat
フラグはなかった
以下抜粋
code:latrace.txt
aaaaa
Sorry, that's not it!
判定処理を見に行ったほうが良さそう
gdbでデバッグする
今回標準入力を要求されるシーンがあるので、そこで中断する 操作
(gdb) run
code:start.txt
Starting program: /home/coolwind0202/documents/picoctf/bbbbloat/bbbbloat
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
What's my favorite number?
ここで標準入力を求められるので、Ctrl+Zで中断するのにちょうどよいタイミング
戻った状態でCtrl+Zするとgdbが中断されてしまう
code:stop.txt
Program received signal SIGTSTP, Stopped (user).
0x00007ffff7e9c992 in __GI___libc_read (fd=0, buf=0x5555555596b0, nbytes=1024) at ../sysdeps/unix/sysv/linux/read.c:26
26 ../sysdeps/unix/sysv/linux/read.c: No such file or directory.
(gdb)
(gdb) info stack
code:stack.asm
#0 0x00007ffff7e9c992 in __GI___libc_read (fd=0, buf=0x5555555596b0, nbytes=1024) at ../sysdeps/unix/sysv/linux/read.c:26
#1 0x00007ffff7e14cb6 in _IO_new_file_underflow (fp=0x7ffff7fa1aa0 <_IO_2_1_stdin_>) at ./libio/libioP.h:947
#2 0x00007ffff7e15e16 in __GI__IO_default_uflow (fp=0x7ffff7fa1aa0 <_IO_2_1_stdin_>) at ./libio/libioP.h:947
#3 0x00007ffff7deb150 in __vfscanf_internal (s=<optimized out>, format=<optimized out>, argptr=argptr@entry=0x7fffffffde10, mode_flags=mode_flags@entry=2)
at ./stdio-common/vfscanf-internal.c:628
#4 0x00007ffff7dea1c2 in __isoc99_scanf (format=<optimized out>) at ./stdio-common/isoc99_scanf.c:30
#5 0x000055555555545e in ?? () #6 0x00007ffff7db1d90 in __libc_start_call_main (main=main@entry=0x555555555307, argc=argc@entry=1, argv=argv@entry=0x7fffffffe058)
at ../sysdeps/nptl/libc_start_call_main.h:58
#7 0x00007ffff7db1e40 in __libc_start_main_impl (main=0x555555555307, argc=1, argv=0x7fffffffe058, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fffffffe048) at ../csu/libc-start.c:392
#8 0x000055555555518e in ?? () 経験上t6o_o6t.icon
今回は0x555555555307
b *0x555555555307
現在のプログラム実行を止める
kill
確認を求められるのでy
再度実行
run
layout asm
または、x/10i $pcなどでも可能
layout asmで表示したほうが、上下移動が可能なので便利そう
code:pseudo.c
int main(void) {
}
追記:書こうと思ったが、読んでいくと擬似コードを書かなくても解けた
書きながら、分からない点を動的解析で見ていく
rbp-0x3c
初期値が0x3078
rbp-0x30
ポインタだと思われる
rbp-0x28
rbp-0x20
rbp-0x18
scanfの直前にブレークポイントを張って、第一引数の文字列のアドレス付近を見る
code:string.txt
(gdb) x/20s $rdi
0x555555556020: "%d"
0x555555556023: "Sorry, that's not it!"
0x555555556039: ""
0x55555555603a: ""
0x55555555603b: ""
0x55555555603c: "\001\033\003;H"
0x555555556042: ""
0x555555556043: ""
0x555555556044: "\b"
0x555555556046: ""
0x555555556047: ""
0x555555556048: "\344\357\377\377|"
0x55555555604e: ""
0x55555555604f: ""
0x555555556050: "\204\360\377\377\244"
0x555555556056: ""
0x555555556057: ""
0x555555556058: "\224\360\377\377\274"
0x55555555605e: ""
0x55555555605f: ""
なぜstringsで現れなかったのだろうか?
scanfの第二引数は、rbp-0x40
これが入力値
途中に多く挟まっているのは、難読化ではないか?
rbp-0x40の行き先を知りたいので、同じような処理を飛ばして読む
rbp-0x40は即値としか比較されていない!!
code:target.asm
0x5555555554c8: mov eax,DWORD PTR rbp-0x40 0x5555555554cb: cmp eax,0x86187
0x5555555554d0: jne 0x555555555583
0x86187 = 549255
入力値がこれと一致しない場合の飛び先はputsだった これがFavorite numberである可能性
入力すると、フラグが出力された
余談t6o_o6t.icon
A:4@r%uLHという文字列も、使い回し?
復号処理を見に行く
復号処理の擬似コードを書く
code:pseudo_decrypt.c
char *decrypt(int _, char *input)
{
// s: rbp-0x10
// len: rbp-0x8
// i: rbp-0x18
// t: rbp-0x1c
char *s;
size_t len;
int i, t;
s = strdup(input);
len = strlen(s);
i = 0;
while (i < len)
{
if (si > 0x20 && si != 0x7f) {
if (t > 0x7e)
{
}
else
{
}
}
i++;
}
return s;
}
gdbで、復号関数の第二引数のアドレスを見たところ、以下の文字列が入っていた
code:rdi.txt
0x7fffffffdf10: "A:4@r%uL4Ff0f9b03=_cf0be55b`e2N"
これが暗号化されたフラグだとは気づかなかった
code:encrypted.txt
A:4@r%uLH
4Ff0f9b0H
3=_cf0beH
55b`e2N