見出し画像

OverTheWire:Behemoth4

今日は久々の休暇。さぁ出かけよう!と思ったら生憎の梅雨空、外は雨。
というわけで、今日も "Over The Wire" (リンクはこちら)に掲載されている問題を解いて遊ぶことにした。。

"Over The Wire" は初心者向けの常設CTFサイト。コンピュータセキュリティに関する様々な練習問題が掲載されていて、それらを解くことでLinux やセキュリティについて段階的に学ぶことができるようになっている。

誰でも無料で利用ができるのでセキュリティを勉強したい人にはお勧めのサイトである。

ますは、前回の記事で取得したパスワードでサーバーに接続。
ssh behemoth4@behemoth.labs.overthewire.org -p 2221

今回の問題は behemoth4  。このプログラムを解析し、次のレベル( bemoth5 ) のパスワードを取得することがこのゲームのゴールである。

behemoth4@behemoth:~$ ls -l /behemoth/
total 72
-r-sr-x--- 1 behemoth1 behemoth0 5900 Aug 26  2019 behemoth0
-r-sr-x--- 1 behemoth2 behemoth1 5036 Aug 26  2019 behemoth1
-r-sr-x--- 1 behemoth3 behemoth2 7536 Aug 26  2019 behemoth2
-r-sr-x--- 1 behemoth4 behemoth3 5180 Aug 26  2019 behemoth3
-r-sr-x--- 1 behemoth5 behemoth4 7488 Aug 26  2019 behemoth4  #<--これ
-r-sr-x--- 1 behemoth6 behemoth5 7828 Aug 26  2019 behemoth5
-r-sr-x--- 1 behemoth7 behemoth6 7564 Aug 26  2019 behemoth6
-r-xr-x--- 1 behemoth7 behemoth6 7528 Aug 26  2019 behemoth6_reader
-r-sr-x--- 1 behemoth8 behemoth7 5676 Aug 26  2019 behemoth7
behemoth4@behemoth:~$ 

どんなプログラムなのか調べるため、まずはとりあえず実行してみる。「PIDが見つからない」という表示が出てあっけなく終了した。

behemoth4@behemoth:~$ /behemoth/behemoth4
PID not found!

何が起きているのだろう? ltrace でどんな関数がコールされているのか見てみよう。

behemoth4@behemoth:~$ ltrace /behemoth/behemoth4
__libc_start_main(0x804857b, 1, 0xffffd764, 0x8048640 <unfinished ...>
getpid()                                         = 3369
sprintf("/tmp/3369", "/tmp/%d", 3369)            = 9
fopen("/tmp/3369", "r")                          = 0
puts("PID not found!"PID not found!
)                           = 15
+++ exited (status 0) +++

どうやら、「自身のプロセスID」が名前になっているファイルを開こうとしているようだ。

ファイルが存在した場合はどんな処理をするのだろう?
プロセスIDを予想して、予め /tmp にファイルを作成し、問題のプログラムを ltrace で実行してみれば判る。

こんなのはシェルスクリプトを使えば簡単!

behemoth4@behemoth:/tmp/foo$ cat a.sh
PID=$$
echo $PID
cd /tmp
echo abc > $(($PID+2))
ltrace /behemoth/behemoth4

上記のスクリプトを実行してみる。

ehemoth4@behemoth:/tmp/foo$ bash a.sh
3469
__libc_start_main(0x804857b, 1, 0xffffd774, 0x8048640 <unfinished ...>
getpid()                                         = 3471
sprintf("/tmp/3471", "/tmp/%d", 3471)            = 9
fopen("/tmp/3471", "r")                          = 0x804b008
sleep(1)                                         = 0
puts("Finished sleeping, fgetcing"Finished sleeping, fgetcing
)              = 28
fgetc(0x804b008)                                 = 'a'
putchar(97, 0x80486c8, 3471, 0x8048591)          = 97
fgetc(0x804b008)                                 = 'b'
putchar(98, 0x80486c8, 3471, 0x8048591)          = 98
fgetc(0x804b008)                                 = 'c'
putchar(99, 0x80486c8, 3471, 0x8048591)          = 99
fgetc(0x804b008)                                 = '\n'
putchar(10, 0x80486c8, 3471, 0x8048591abc
)          = 10
fgetc(0x804b008)                                 = '\377'
fclose(0x804b008)                                = 0
+++ exited (status 0) +++
behemoth4@behemoth:/tmp/foo$ 

これで、このプログラムの動作が判った。

ここから先は

573字

¥ 500

期間限定!Amazon Payで支払うと抽選で
Amazonギフトカード5,000円分が当たる

この記事が気に入ったらチップで応援してみませんか?