前言
在上次总结内网穿透工具时,注意到反向代理这个名词。这里通过nginx学习顺便补上这一课。
安装
选择使用虚拟机centos安装nginx。
首先需要安装一些依赖
yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
再到nginx官网 ,下载ngiunx安装包版本,这里选择使用nginx-1.7.11版本。
下载移动到/usr/local/目录下,进行配置
./configure --prefix=/usr/local/nginx
nginx目录就是配置好的目录。cd进去进行编译。
make && make install
编译后,切换至/usr/local/nginx/sbin 目录下,执行./nginx -t
查看是否配置成功
命令
简单列举关于nginx服务的几个命令:
./nginx -t 查看是否配置成功
./nginx -v 查看版本号
./nginx -s stop
./nginx 启动
./nginx -s reload 重加载,不重启
记得被访问时需要查看本地防火墙状态。
再列举firewall-cmd防火墙的几个命令。
firewall-cmd --state 查看防火墙状态
firewall-cmd --list-all 查看防火墙规则
firewall-cmd --add-port=80/tcp --permanent 添加80端口以供访问
firewall-cmd --reload 防火墙重载
systemctl status firewalld.service 查看firewalld状态
systemctl stop firewalld.service 关闭firewalld
systemctl start firewalld.service 启动firewalld
客户端访问centos
可顺利访问页面。
配置文件
主要介绍/usr/local/nginx/conf/nginx.conf
配置文件。
该配置文件由3部分组成:
- 全局块
用来配置影响nginx全局的指令
#user nobody; 设置nginx服务的系统使用用户
work_precesses 工作进程数
#error_log logs/error.log; 错误日志存放目录
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid; nginx启动的pid
- event块
用来影响nginx服务器和用户网络连接
worker_connaction 支持的最大连接数
- http块
可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
include mime.types; 文件扩展名与文件类型映射表
default_type application/octet-stream; 默认文件类型
sendfile on; 开启高效文件传输模式
keepalive_timeout 65; 长连接的超时时间
http全局块还包括server块
server块用来配置虚拟主机的相关参数。
server {
listen 80; 端口
server_name localhost; 域名
#charset koi8-r; 编码格式
#access_log logs/host.access.log main; 日志地址
location / {
root html;
index index.html index.htm;
}
}
location用来配置请求的路由,以及各种页面的处理情况。
这里列举location的语法规则:
空 表示URI从头开始匹配
~ 执行一个正则匹配,区分大小写
~* 执行一个正则匹配,不区分大小写
^~ 普通字符匹配,多用来匹配目录
= 执行普通字符精确匹配
!~ 大小写敏感不匹配
!~* 大小写不敏感不匹配
location也有优先级,如下列举从上到下
location = /abc { } 精确匹配
location ^~ /abc { } 匹配路径的前缀,如果找到停止搜索
location ~* /abc { } 不区分大小写的正则匹配
location ~ /abc { } 正则匹配
location /abc { } 普通路径前缀匹配
实现反向代理
这里先简单介绍一下正向代理和反向代理的概念。
正向代理
正向代理类似一个跳板,通过代理来访问互联网。比如我们熟知的通过挂一层代理,跨过长城访问google。
反向代理
反向代理是指以代理服务器来接受互联网上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给互联网上请求连接的客户端。
比如浏览器去访问百度,其实访问到的是代理服务器,然后由代理服务器转发请求到内网的某台服务器上。而客户端是不知道具体那台服务器提供访问的。
如何在nginx上实现反向代理?
配置过程如下:
- 首先需要在客户端修改
C:\Windows\System32\drivers\etc\hosts.txt
文件实现本地的域名解析。即:
10.211.55.30 www.cseroad.com
- 安装并启动tomcat服务。
- 在nginx服务端修改nginx.conf配置文件。
配置proxy_pass实现代理转发,即访问10.211.55.30的80端口流量被转发到本地的8080端口上。
windows客户端访问www.cseroad.com域名即可。
扩展:
根据反向代理,实现根据访问路径的不同跳转到不同端口的服务。
- 需要准备两个tomcat服务,并将其中一个tomcat默认端口8080修改为8081。
且创建demo01、demo02 文件夹。编辑index.html首页为8080、8081。
- 进行nginx反向代理的配置
- 记得防火墙放行9001端口
firewall-cmd --add-port=9001/tcp --permanent
成功实现访问demo01文件夹为8080端口的服务,访问demo02文件夹为8081端口的服务。
实现负载均衡
负载均衡通常是通过增加服务器数量,将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。
比如说客户端访问某个页面,nginx将请求平均分发到8080端口和8081端口上去。
- 修改上面两个tomcat的demo01、demo02文件夹重命名为demo。
- 修改nginx.conf配置文件如下:
添加upstream节点,用来将访问10.211.55.30的80端口demo文件夹的请求全部转发到10.211.55.30的8080端口和8081端口的tomcat上去。
客户端访问同一个demo文件夹,即会出现8080端口也会出现8081端口。
相关漏洞
学习了nginx的配置,作为一名安全从业者,再看一下有没有关于nginx的漏洞。
目录遍历
该漏洞是因为nginx配置时使用别名忘记加/,闭合目录,造成的目录遍历漏洞。
autoindex on 开启目录浏览功能,默认关闭
alias 设置虚拟目录
demo文件名没有闭合,当访问/demo../时,nginx实际处理的路径就会是/home/../,从而实现了穿越目录。
SSRF漏洞
SSRF漏洞是在nginx配置正向代理产生的。
resolver 114.114.114.114; 指定DNS服务器IP地址
proxy_pass https://$host$request_uri; 设置代理服务器的协议和地址
主要是因为$host$request_uri
全部可控。
curl -v --proxy 10.211.55.30:80 http://www.baidu.com
也可以使用 gixy 来检测nginx配置的相关漏洞。
解析漏洞
该解析漏洞和php版本,nginx版本没有关系,主要是php-fpm的问题。
nginx解析php的过程是什么样的呢?
当浏览器请求静态资源html、css、images等资源时,nginx不需要调用php解释器,直接返回静态资源。当请求动态语言php脚本时,nginx会调用fastcgi模块,将http请求映射为对应的 fastcgi请求。fastcgi协议是cgi协议的改良版。而php-fpm是一个程序,通过fastcgi协议来和php进行通信。然后php把http请求响应后按照fastcgi协议标准发给nginx,nginx返回给浏览器。
先把漏洞环境复现一下,再解释这其中的原理。
这里使用lnmp集成环境安装。
wget http://soft.vpser.net/lnmp/lnmp1.7.tar.gz -cO lnmp1.7.tar.gz && tar zxf lnmp1.7.tar.gz && cd lnmp1.7 && ./install.sh lnmp
安装成功后。
- 修改
/usr/local/nginx/conf/nginx.conf
配置文件。
location ~ \.php$ {
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME /home/wwwroot/default$fastcgi_script_name; #脚本文件请求的路径
fastcgi_param DOCUMENT_ROOT /home/wwwroot/default; #网站的根目录。在server配置中root指令中指定的值
fastcgi_pass unix:/tmp/php-cgi.sock; #nginx与php-fpm通信的方式
}
- 编辑
/usr/local/php/etc/php-fpm.conf
文件
security.limit_extensions = 允许执行所有的扩展名文件
- 修改
cgi.fix_pathinfo=1
编辑a.jpg文件内容为<?php phpinfo()?>
访问a.jpg
利用解析漏洞访问
解析漏洞过程如下:
请求/a.jpg/a.php时,script_filename接收到的为/home/wwwroot/default/a.jpg/a.php
,但是因为配置cgi.fix_pathinfo=1,将以/开始查找其中真正的脚本文件名字,所以script_filename变为/home/wwwroot/default/a.jpg
,path_info为a.php
。
最后,以/home/wwwroot/default/a.jpg
作为请求执行的脚本,就可以让nginx以php来解析任何类型的文件。
该漏洞需要同时满足设置cgi.fix_pathinfo=1 获取当前请求的URL路径信息,security.limit_extensions 不限制执行文件扩展名。
总结
通过学习nginx的命令配置,知道正向代理,反向代理的原理以及配置。明白了实战中一些目标的访问技巧。复现了nginx配置中出现的漏洞,明白ssrf漏洞、目录遍历漏洞、解析漏洞的原理。
如有错误,还请斧正。
参考资料
https://www.bilibili.com/video/BV1zJ411w7SV?p=11
https://www.onebug.org/websafe/98595.html
http://byd.dropsec.xyz/2017/11/09/Nginx%E8%A7%A3%E6%9E%90%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90/
https://www.jianshu.com/p/bf745d97681a