目录
4、给/usr/local/nginx/html/xjl/protected/tmp赋予权限
第二种处理方法---双host字段绕过(nginx低版本可用,高版本不在适用)
一、LNMP环境搭建
1、nginx的基础配置
对nginx的配置文件进行配置
# vim /usr/local/nginx/conf/nginx.conf
配置内容如下
server {
listen 80;
server_name www.xjl.com;
root /usr/local/nginx/html/xjl/web;
index index.php index.html;
access_log logs/host.access.log main;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$(.*)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
}
2、将域名与IP映射的关系添加到hosts文件
192.168.75.139 www.xjl.com
启动nginx
# cd /usr/local/nginx/sbin
# ./nginx -s reload
3、上传pwnhub文件
检测
4、给/usr/local/nginx/html/xjl/protected/tmp赋予权限
# chmod 777 /usr/local/nginx/html/xjl/protected/tmp
再次测试
二、配置数据库MySQL
1、首先连接MySQL
# mysql -uroot -proot
2、创建数据库以及创建表
CREATE DATABASE sercuity;
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `flags`;
CREATE TABLE `flags` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`flag` VARCHAR(256) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(256) NOT NULL,
`password` VARCHAR(32) NOT NULL,
`email` VARCHAR(256) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=INNODB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4;
SET FOREIGN_KEY_CHECKS = 1;
3、给表中插入数据
insert into flags(flag) vlaues (i love you);
三、FILTER_VALIDATE_EMAIL 绕过
早在当初PHPMailer的CVE-2016-10033就提到过。 RFC 3696规定,邮箱地址分为local part和domain part两部分。local part中包含特殊字符,需要如下处理
-
将特殊字符用\转义,如Joe\'Blow@example.com
-
或将local part包裹在双引号中,如"Joe'Blow"@example.com
-
local part长度不超过64个字符
虽然PHP没有完全按照RFC 3696进行检测,但支持上述第2种写法。所以,我们可以利用之绕过FILTER_VALIDATE_EMAIL 的检测。
因为代码中邮箱是用户名、@、Host三者拼接而成,但用户名是经过了转义的,所以单引号只能放在Host中。我们可以传入用户名为",Host为nameis'"@xjl.com ,最后拼接出来的邮箱为"@nameis'"@xjl.com,这个邮箱是合法的,这个邮箱包含单引号,将闭合SQL语句中原本的单引号,造成SQL注入漏洞。
# cat web.php
<?php
$email = '"nameis\'"@xjl.com';
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
四、nginx配置自定义证书---ssl模块
1、配置证书
创建ca文件存放证书密钥文件
# mkdir /usr/local/nginx/ca
# cd /usr/local/nginx/ca
生成私钥以及证书的请求文件
# openssl genrsa -des3 -out ssl.key 4096
# openssl req -new -key ssl.key -out ssl.csr
最终生成crt证书文件
# openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
2、nginx配置ssl模块
1.判断是否具有ssl模块 --- 输出含有configure arguments: --with-http_ssl_module
/usr/local/nginx/sbin/nginx -V
#2.移动到nginx源码解压目录
./configure --with-http_ssl_module
#3.编译执行
make
#4.备份原有已安装好的nginx
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
#5.然后将刚刚编译好的nginx覆盖掉原有的nginx(这个时候nginx要停止状态)
cp ./objs/nginx /usr/local/nginx/sbin/
#6.测试查看
[root@192 sbin]# ./nginx -V
nginx version: nginx/1.22.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --with-http_ssl_module
#7.对nginx配置文件进行配置ssl
server {
listen 443 ssl;
server_name www.xjl.com;
root /usr/local/nginx/html/xjl/web;
index index.php index.html;
ssl_certificate /usr/local/nginx/ca/ssl.crt;
ssl_certificate_key /usr/local/nginx/ca/ssl.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
五、绕过nginx host限制
尝试向目标注册页面发送刚才构造好的用户名和Host
直接显示404,为什么呢?似乎没有被php处理。
Host头究竟是干什么用的?
Host作用:用来区分用户访问的究竟是哪个网站(Nginx中就是Server块)
如果Nginx发现我们传入的Host找不到对应的Server块,将会发送给默认的Server块,也就是我们通过IP地址直接访问的那个Nginx默认页面 ,默认网站并没有/main/register
这个请求的处理方法,所以自然会返回404。
第一种处理方法---冒号分隔host字段
Nginx在处理Host的时候,会将Host用冒号分割成hostname和port,port部分被丢弃。所以,我们可以设置Host的值为www.xjl.com:'"example.com ,这样就能访问到目标Server块
第二种处理方法---双host字段绕过(nginx低版本可用,高版本不在适用)
当我们传入两个Host头的时候,Nginx将以第一个为准,而PHP-FPM将以第二个为准。
我以如下方式传入
Host: www.xjl.com
Host: aaa'"@example.com
Nginx将认为Host为www.xjl.com,并交给目标Server块处理;但PHP中使用$_SERVER['HTTP_HOST'] 取到的值却是aaa'"@example.com。
低版本测试(可用)
用上述方式可以进行绕过
高版本测试(不可用)
用上述方式则无法进行绕过
第三种处理方法---利用SNI机制进行绕过
其实原理就是,我们在发送https数据包的时候,SNI中指定的域名是example2.com,而无需和HTTP报文中的Host头保持一致,Nginx会选择SNI中的域名作为Server Name。
此时我们在Burpsuite里修改协议为https,并指定好https的Host,也就是SNI
我们再修改HTTP数据包的Host头,就能正常访问目标后端了