一、环境准备
1.虚拟机下的搭建与配置
(1)mysql的安装(192.168.64.88)
wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
rpm -ivh mysql57-community-release-el7-9.noarch.rpm
yum install mysql-server --nogpgcheck
systemctl start mysqld
sudo mysql_secure_installation
grep 'temporary password' /var/log/mysqld.log
可能会遇到密码总是无法修改成功的情况:
①首先打开 vim /etc/my.cnf做如下修改:
增添了新的一行skip-grant-tables
②重启数据库服务,输入service mysqld restart
③使用sql语句来修改密码
直接在终端输入mysql,然后输入sql语句并执行
④输入mysql -uroot -p,然后输入你设置的密码就可以成功登录
⑤数据库的配置
mysql> create database pwnhub charset utf8mb4;
mysql> use pwnhub;
mysql> SET NAMES utf8;
然后将pwnhub_6670.sql脚本直接复制进去,执行完可以进行查看:
(2)虚拟主机
①
[root@localhost ~]# cd /home/nginx/html
[root@localhost html]# systemctl restart php56-php-fpm
[root@localhost html]# systemctl start nginx.service
[root@localhost html]# mkdir pwnhub
然后使用工具将文件导入:
删除pwnhub/protected/tmp,并且修改config.php文件:
[root@localhost pwnhub]# cd protected/
[root@localhost protected]# rm -rf tmp
[root@localhost protected]# vim config.php
②虚拟主机的配置
[root@localhost nginx]# cd conf/
[root@localhost nginx]# vim nginx.conf
在etc/hosts文件下添加虚拟主机域名与IP的映射(不添加此部分无法访问域名)
结束之后查看防火墙以及重启linux:
[root@localhost conf]# iptables -nvxL INPUT
[root@localhost conf]# ../sbin/nginx -s reload
虚拟机中访问:
403,是由于权限问题:
[root@localhost html]# chown -R apache:apache pwnhub
修改上述配置后记得重启nginx。
又出现问题:
[root@localhost nginx]# cd html/pwnhub/
[root@localhost pwnhub]# ls -al
[root@localhost pwnhub]# chmod -R 777 protected/
[root@localhost pwnhub]# cd protected/
[root@localhost protected]# mkdir tmp
[root@localhost protected]# chown -R apache:apache tmp/
[root@localhost protected]# chmod 777 tmp/
权限问题修改完成后,再进行访问:
如果想保证本机也可以访问到,则做如下配置:
进入本地C:\Windows\System32\drivers\etc,找到hosts并作修改:
然后在本地可以访问到,本地操作较方便:
2.若在本机搭建,可做如下配置配置
(1)
网站中存在两张表,flags和users表。
(2)
首先在本机数据库中创建数据:
mysql> CREATE DATABASE lnmp;
mysql> show databases;
mysql> use lnmp;
mysql> show tables;
mysql> source D:\pwnhub_6670.sql ;使用脚本给lnmp数据库增加数据
mysql> show tables; ;此时lnmp数据库中已有数据
下图中字段修改为自己的:
(3)本地nginx的配置:
二、SQL注入漏洞挖掘
1.MainController.php core.php
(1)首先分析登陆页面
此过滤函数会过滤ages接收的所有参数
username,password和上面login一致,都被escape函数过滤,所以我们无法在登陆页面渗透。
(2)注册页面分析
①75行中,若email为空,虽然使用arg函数获取了email且进行了过滤,此时email的组成就是username拼接了一个@符号和一个HTTP_HOST,此时我们需要考虑到HTTP_HOST的用法。
下图中可以见得HTTP_HOST打印出了网址(主机):
然后回到76行,邮箱就会以aaaaa@2024.mhz.pw的形式保存,这个是标准的邮箱格式。
我们应该思考,如何闭合单引号?
这里是存在一个判断的,使用php自带函数FILTER_VALIDATE_EMAIL,如果邮箱不符合要求是无法通过的(注册页面):
②75行中,如果有email,则会直接被放在89行的create中去
我们思考,若在92行中也存在一个单引号,也可以进行闭合。
(3)
可见所有的函数都需要使用escape过滤:
但是$_SERVER没有被过滤:
$_SERVER获取的就是HTTP_HOST(web.php中可见)
获取:
可得HTTP_HOST是从SERVER中获取出来的。但escape过滤函数并未对其进行过滤。
(4)目标网站只有简单的注册、登陆功能,有关代码的输入如下:
<?php
escape($_REQUEST);
escape($_POST);
escape($_GET);
function escape(&$arg) {
if(is_array($arg)) {
foreach ($arg as &$value) {
escape($value);
}
} else {
$arg = str_replace(["'", '\\', '(', ')'], ["‘", '\\\\', '(', ')'], $arg);
}
}
function arg($name, $default = null, $trim = false) {
if (isset($_REQUEST[$name])) {
$arg = $_REQUEST[$name];
} elseif (isset($_SERVER[$name])) {
$arg = $_SERVER[$name];
} else {
$arg = $default;
}
if($trim) {
$arg = trim($arg);
}
return $arg;
}
这里写入REQUEST,即可以接受GET也可以接受POST请求,然后escape就会过滤REQUEST,可以用$_SERVER去接受,这样的方式不经过全局转义,也就是说并未被过滤掉,意味着我们可以提交一些东西。
三、FILTER_VALIDATE_EMAIL绕过
构造一个合法邮箱:
四、绕过Nginx Host限制(依据nginx与php处理host不同方式的绕过)
[root@localhost protected]# cd view/
[root@localhost view]# vim main_register.html
添加如下字段,然后进行抓包:
抓包:
抓包键为on,然后在前端页面写入数据,点击sign up,再设为off,抓到如下信息:
将大圈内的数据发送到repeater中去:
Host值修改为:
然后这个双引号就可以与username的双引号拼接在一起。
产生404的原因:
虚拟主机找的是/home/centos/nginx/html/pwnhub/protected
例如我现在请求到一个2023.mhz.pw后,才会找到html/pwnhub,但此时请求的host变成了aaa""@qq.com,它就找不到虚拟主机了,只能去找默认模块,如下图所示:
但是默认模块并不存在/main/register这个函数,所以会提示404。
1.方案一
Nginx中,会将冒号后面的当作端口号全部丢弃,这时nginx还是可以顺利的处理Host模块然后访问到页面,而在php处理时,后面的又会被拿回来,相当于是
"x@2023.mhz.pw:xxx'"@qq.com
的形式,双引号包裹起来的是php的规范,但是走到mysql后,单引号会将前面的单引号闭合,然后产生注入点。
我们将host字段改写如下: 2023.mhz.pw:xxx'"@qq.com
此时其实已经注入成功!
这里的单引号进来了,email字段已经被闭合,后面可以写自己想写的内容,这里语法出错是因为我们写的单引号把前面的单引号闭合了,后面的单引号还留在那里,但是出错其实就意味着注入成功(sql注入时就需要的是报错就代表成功),意味着我们可以在"@qq.com这个地方注入我们想注入的内容。
2.方案二
这里需要更换版本,且需要做一些配置:
进入C:\Windows\System32\drivers\etc 添加如下数据:
然后启动后php_study中的mysql和nginx。
如何利用:
测试结果:
3.方案三
https在三次握手之前,
但如果是在http中,如果我们修改Host头,Nginx将因为识别不到Server Name而被导向默认的页面。
在https中,ssl可以提前发送Host字段让Nginx识别到正确的域,返回正确的证书
在bp右上角的target旁边可以修改Host信息,让其包含在ClientHello中
五、Mysql5.7 INSERT注入方式
按照上面的方法我们成功触发了SQL的报错信息,那就再继续构造SQL注入的语句
1.插入显示位
因为用户成功登录后,将会显示出该用户的邮箱地址,所以我们可以将数据插到这个位置,发送如下数据包:
'),('t123',md5(12123),(select(flag)from(flags)))#"@a.com
会被放入第四行的email中,第四行的email中是"a@ , 这里的"a是提交的用户名
email的生成规则为user + @ + host , 第一行是host,相当于拼接成了:
' "a@'),('t123',md5(12123),(select(flag)from(flags)))#"@a.com
此时第一个单引号把第二个单引号也就是我们提交的单引号闭合住了,后面跟着的括号将email直接提交结束了,相当于第一个email提交了一个"a@',闭合之后相当于又插入了三个字段
host是蓝色的整体,引号和后括号都闭合了,然后后面的是直接插入的值,最后是闭合。
此时相当于用户已经注册成功,现在可以直接在网页中登录,登陆成功以后将会获得flag