🙆

[SadServers] 解説 "Karakorum": WTFIT – What The Fun Is This?

2023/02/18に公開

"Karakorum": WTFIT – What The Fun Is This?

SadServersの "Karakorum": WTFIT – What The Fun Is This? の解説です。

SadServers って何? って人は、 SadServers解説 を見てください。
一言でいうと、LeetCode (コーディング問題集) の Linuxサーバ設定版のようなものです。

問題

問題を見ていきます。 > の箇所は DeepLでの翻訳です。

Scenario: "Karakorum": WTFIT – What The Fun Is This?

Level: Hard

Description: There's a binary at /home/admin/wtfit that nobody knows how it works or what it does ("what the fun is this"). Someone remembers something about wtfit needing to communicate to a service in order to start. Run this wtfit program so it doesn't exit with an error, fixing or working around things that you need but are broken in this server. (Note that you can open more than one web "terminal").
> /home/admin/wtfitにバイナリがありますが、誰もそれがどう動くのか、何をするのか知りません(「これは何が面白いんだ」)。誰かが、wtfitが起動するためにサービスと通信する必要があることを何かで覚えているのです。このwtfitプログラムがエラーで終了しないように実行し、必要だがこのサーバーでは壊れているものを修正したり、回避したりします。(複数のウェブ「端末」を開くことができることに注意してください)。

Test: Running /home/admin/wtfit returns OK.


Time to Solve: 20 minutes.

OS: Debian 11

/home/admin/wtfit というプログラムを実行して、 OK が表示させるということです。

解説

早速、/home/admin/wtfitを実行します。

admin@ip-172-31-47-197:/$ /home/admin/wtfit
bash: /home/admin/wtfit: Permission denied

Permission(権限)が無いため動きません。
ls -l で、 /home/admin/wtfitの権限を確認します。

admin@ip-172-31-47-197:/$ ls -l /home/admin/wtfit 
-rw-r--r-- 1 admin admin 6381234 Sep 13 18:17 /home/admin/wtfit

-rw-r--r--r となっており、4文字目が -x ではないため、実行権限がありません。
chmod +x で、実行権限を与えます。

admin@ip-172-31-47-197:/$ chmod +x /home/admin/wtfit
bash: /usr/bin/chmod: Permission denied

おっと、 /usr/bin/chmod も Permission(権限)が無いと言われます。
こちらも ls -lで権限を確認します。

admin@ip-172-31-45-197:~$ ls -l /usr/bin/chmod 
-rw-r--r-- 1 root root 64448 Sep 24  2020 /usr/bin/chmod

確かに、 /usr/bin/chmod も実行権限がありません。
chmod が使えない状況で 実行権限を与える方法をググると、 How to execute Linux binary without execute permission の方法が見つかったので、これを試します。

# /lib64/ld-linux-x86-64.so.2 で chmod を実行。 正しく動いています。
admin@ip-172-31-45-197:~$ /lib64/ld-linux-x86-64.so.2 /usr/bin/chmod 
/usr/bin/chmod: missing operand
Try '/usr/bin/chmod --help' for more information.


# chmod で、chmod に 実行権限を与えます。
admin@ip-172-31-45-197:~$ sudo /lib64/ld-linux-x86-64.so.2 /usr/bin/chmod  +x /usr/bin/chmod 

# 確認
admin@ip-172-31-45-197:~$ ls -l /usr/bin/chmod
-rwxr-xr-x 1 root root 64448 Sep 24  2020 /usr/bin/chmod

chmod が動くようになったので、改めて、 /home/admin/wtfitに実行権限を与えて、実行します。

# /home/admin/wtfitに 実行権限を与える。
admin@ip-172-31-45-197:~$ ./chmod +x /home/admin/wtfit 

# /home/admin/wtfitを実行
admin@ip-172-31-45-197:~$ /home/admin/wtfit 
ERROR: can't open config file

エラーとなりました。

ERROR: can't open config file

config fileが openできないと言っています。 config file とは具体的にどのファイルのことでしょうか?
それを調べるために straceコマンドで、/home/admin/wtfitプログラムを調べます。
straceコマンドは、プログラムがどのようなシステムコールを呼び出しているかを調べることができるツールです。 参考

admin@ip-172-31-45-197:~$ cd /home/admin
admin@ip-172-31-45-197:~$ strace ./wtfit 

rt_sigreturn({mask=[]})                 = 0
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
fcntl(0, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fed4b1bc000
fcntl(1, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
fcntl(2, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
openat(AT_FDCWD, "/home/admin/wtfitconfig.conf", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(1, "ERROR: can't open config file\n", 30ERROR: can't open config file
) = 30
exit_group(1)                           = ?
+++ exited with 1 +++

openat(AT_FDCWD, "/home/admin/wtfitconfig.conf", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(1, "ERROR: can't open config file\n", 30ERROR: can't open config file
) = 30

/home/admin/wtfitconfig.conf を開こうとしています。
touch/home/admin/wtfitconfig.confを作り、再度実行します。

# /home/admin/wtfitconfig.conf ファイルを作成
admin@ip-172-31-45-179:~$  touch /home/admin/wtfitconfig.conf

# 再度 /home/admin/wtfitを実行
admin@ip-172-31-45-179:~$  ./wtfit  
ERROR: can't connect to server

次はサーバに接続できないとのエラーが出ています。
再び、straceで確認します。

admin@ip-172-31-45-179:~$ strace ./wtfit  

close(3)                                = 0
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(7777), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
epoll_ctl(4, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=983903976, u64=139935313374952}}) = 0
write(6, "\0", 1)                       = 1
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
getsockopt(3, SOL_SOCKET, SO_ERROR, [ECONNREFUSED], [4]) = 0
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
epoll_ctl(4, EPOLL_CTL_DEL, 3, 0xc0000b5324) = 0
close(3)                                = 0
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000034548, FUTEX_WAKE_PRIVATE, 1) = 1
write(1, "ERROR: can't connect to server\n", 31ERROR: can't connect to server
) = 31
exit_group(1)                           = ?
+++ exited with 1 +++

connect(3, {sa_family=AF_INET, sin_port=htons(7777), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)

IPアドレス 127.0.0.1、 ポート番号 7777にTCP接続しようとしていることがわかります。

問題ページの Open the server terminal in a new window.をクリックして、ターミナルをもう一つ開き、ncツールで、 127.0.0.1:7777 のサーバを立てます。

# 2番目のターミナル

# 7777ポートで接続を待ち受ける。 
admin@ip-172-31-45-179:/$ nc -l 7777

その後、最初のターミナル(1番目のターミナル)で、 /home/admin/wtfitコマンドを実行すると、次のように表示されます。

# 2番目のターミナル

admin@ip-172-31-45-179:/$ nc -l 7777
GET / HTTP/1.1
Host: localhost:7777
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

これは、おなじみのHTTPリクエストです。 /home/admin/wtfitは HTTPクライアントのようです。
手動でHTTPレスポンスを返しましょう。

# 2番目のターミナル

admin@ip-172-31-45-179:/$ nc -l 7777
GET / HTTP/1.1
Host: localhost:7777
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

HTTP/1.1 200 OK    # これを入力する。

HTTP/1.1 200 OKを入力すると、1番目のターミナルで動作している/home/admin/wtfit側に、OK.が表示されます。

1番目のターミナル
admin@ip-172-31-45-179:~$ ./wtfit 
OK.

これで良さそうです。

2番目のターミナルで、 nc -l 7777を入力し、Check My Solutionをクリックします。

GET / HTTP/1.1
Host: localhost:7777
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

が表示された直後に HTTP/1.1 200 OK を入力すればよいのですが、駄目です。Solution is incorrect or the server agent can't respond properly (something broke). をなります。人手でレスポンスを入力するのでは間に合わないようです。
python3 が使えるようなので、python3 で、HTTPサーバを起動させます。

# 2番目のターミナル

admin@ip-172-31-45-179:/$ python3 -m http.server 7777
Serving HTTP on 0.0.0.0 port 7777 (http://0.0.0.0:7777/) ...

改めて、 Check My Solution をクリックすると、パスします。

Discussion