logger

問題概要

ジャンル

exploit
(Linuxカテゴリな気がする)

点数

300 points

問題文

logger
Host : logger.pwn.seccon.jp
Port : 6565

logger (SHA1 : fee7140cb33d79c0406de49f7f8985fd459468ea)
libc-2.19.so (SHA1 : 8674307c6c294e2f710def8c57925a50e60ee69e)

フラグ

???

挑戦者

tkmru
K_atc

解法

議論

可能性:

  • ディレクトリトラバース脆弱性によるflagファイル読み取り
  • ログファイルにshellcode
  • fopenの引数書き換えてflag読ませる

表層調査

$ checksec.sh --file ./logger 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   Canary found      NX disabled   Not an ELF file   No RPATH   No RUNPATH   ./logger

$ ./logger
Welcome to logging service.
Log file will be removed every 5 minites.
1. Login
2. exit
1
Name    :1234
Password:1234
1. Read log
2. Append log
3. Display info
4. exit
1
qqqqq
1. Read log
2. Append log
3. Display info
4. exit
3
=====Info=====
Your Name: 1234Your Password: 1234filename: ed2b1f468c5f915f3f1cf75d7068baaeP2`==============
1. Read log
2. Append log
3. Display info
4. exit
  • NX disabled

ファイル読み取り処理があるのでどうにかflag読ませるとか?
free()してないのでheap exploitingではない気がする。

ファイル名の後ろにゴミが付いているのが気になる
えーそんな問題ある?

=====Info=====
Your Name: nameYour Password: passfilename: efc2792ddf38f661f9d3965005555f3d\x10 #\x0c\x89\x7f==============

なんかのアドレスがリークしてる([rsp+0x100+X])

0x401234 call j_fopenの引数書き換えたい。
0x401037 call j_fopenの引数は直前のf_openの間にcalc_filenameがあるからきびしい気がする
stack_chk_fail()はcalc_filename()の中でしか読まれない。
0x40116d call j___isoc99_scanfで書き換えたい。
scanf('%ld', buf)なのでだめだった。

自由に書き込めるのLog size(max 128byte):のとこくらいかな???

  • 負数指定可能

main()

function main {
    rax = *__TMC_END__;
    setvbuf(rax, 0x0, 0x2, 0x0);
    rax = *stdout@@GLIBC_2.2.5;
    setvbuf(rax, 0x0, 0x2, 0x0);
    puts("Welcome to logging service.");
    puts("Log file will be removed every 5 minites.");
    puts("1. Login\n2. exit");
    __isoc99_scanf("%ld", var_1A0);
    getchar();
    if (var_1A0 == 0x1) goto loc_400f78;

loc_400f6e:
    // avoid
    rax = exit(0x0);
    return rax;

loc_400f78:
    // BOF不可
    printf("%s", "Name    :");
    __isoc99_scanf("%63s", var_90);
    printf("%s", "Password:");
    __isoc99_scanf("%63s", var_50);
    rax = calc_filename(var_90, var_50, var_100);
    strcat('/tmp/log', rax);
    if (check_dir() != 0x0) goto loc_401023;

loc_40100f:
    // avoid
    puts("/tmp/logger directory not exists");
    rax = exit(0x1);
    return rax;

loc_401023:
    *fp = fopen('/tmp/log', "a+");
    if (*fp != 0x0) goto loc_40105e;

loc_40104a:
    puts("open error.");
    rax = exit(0x1);
    return rax;

loc_40105e:
    stat('/tmp/log', var_190);
    var_E0 = malloc(sign_extend_32(var_160));
    goto loc_40108f;

loc_40108f:
    do {
            puts("1. Read log\n2. Append log\n3. Display info\n4. exit");
            __isoc99_scanf("%ld", var_1A0);
            getchar();
            if (var_1A0 != 0x1) {
                break;
            }
            var_1A8 = 0x0;
            do {
                    var_1A4 = fgetc(*fp);
                    if (var_1A4 == 0xffffffff) {
                        break;
                    }
                    *(int8_t *)(var_E0 + sign_extend_32(var_1A8)) = var_1A4;
                    var_1A8 = var_1A8 + 0x1;
            } while (true);
            write(0x1, var_E0, var_160);
    } while (true);
    if (var_1A0 != 0x2) goto loc_40127d;

loc_401145:
    printf("%s", "Log size(max 128byte):");
    __isoc99_scanf("%ld", var_1A0);
    getchar();
    if (var_1A0 <= 0x80) goto loc_40119a;

loc_401186:
    puts("Size error.");
    rax = exit(0x1);
    return rax;

loc_40119a:
    var_198 = malloc(var_1A0);
    rax = read(0x0, var_198, var_1A0);
    fwrite(var_198, sign_extend_64(rax), 0x1, *fp);
    rax = *fp;
    fclose(rax);
    stat('/tmp/log', var_190);
    // closeしてからreopenしていない?
    *fp = fopen('/tmp/log', "a+");
    if (*fp != 0x0) goto loc_401260;

loc_40124c:
    puts("open error.");
    rax = exit(0x1);
    return rax;

loc_401260:
    var_E0 = malloc(sign_extend_32(var_160));
    goto loc_40108f;

loc_40127d:
    if (var_1A0 != 0x3) goto loc_4012e8;

loc_40128a:
    puts("=====Info=====");
    printf("Your Name: %s", var_90);
    printf("Your Password: %s", var_50);
    printf("filename: %s", var_100);
    puts("==============");
    goto loc_40108f;

loc_4012e8:
    rax = *fp;
    fclose(rax);
    puts("Thank you for your logging :)");
    rax = exit(0x0);
    return rax;
}