githubEdit

sqli-lab通关笔记

第一关

输入单引号报语法错误,说明是字符型注入,输入#注释符成功不显示报错

image-20210510214933062

开始order by查看列数 union select 查看显示的列数信息,然后查看database()、version()、如果是mysql数据库并且版本号大于5.0,就可以利用information_schema这个数据库进行信息的显示。而本关卡正好符合,很容易就破解了。

  • 获取列数,4列报错,3列正常显示,则说明显示SQL语句显示3列信息

    image-20210510215437509

  • 获取显示的列 注意,单引号前面的1要改成-1,因为他不能显示信息,后面的语句才能显示

image-20210510215708911

显示2,3,下面我们就在2,3列上修改sql函数

  • 获取SQL数据库信息

    image-20210510215854464

  • 先获取数据库信息、数据库表名信息、表的列名信息、最后成功显示出表中的信息

枚举所有的数据库信息image-20210510220708753

枚举数据库所有表名

image-20210510220948625

枚举users表中的所有列名

image-20210510221142238

枚举出所有的users表中的username和password,破解成功

image-20210510221810545

第二关

输入'单引号报语法错误,然后输入注释符之后报错并没有消失,根据报错信息可以推断出这个SQL查询语句应该是数字型的。

image-20210511101332144

于是开始针对数字型注入开始测试,成功得到信息

image-20210511101454919

于是开始和第一关一样的套路,详情略过

第三关

判断注入类型,输入 '单引号报错,但是显示的报错信息有一个 ),我们猜测代码中进行了限制,用()把id变量包含了起来,输入)进行验证,报错成功不显示了

image-20210511140358241
image-20210511140524020

接下来就是判断列数--》3列

以下步骤和前两关一样,不在赘述

image-20210511140815064

第四关

输入 '单引号判断注入类型,不报错,然后我就以为是数字类型注入,直接输入order by 判断列数,结果并没有回显列数,看来也不是数字型注入。看了源码才知道原来是 "双引号字符型+ ) 注入,代码写的还挺绕。。。。

于是开始老套路,先判断列数

image-20210511141636612

显示database()、version()、users()

利用information_schema数据库爆出想要的数据表信息,不再赘述

image-20210511141936063

第五关

这一关是字符型注入,和第一关一样,但是这一关并不显示数据信息,只显示You are in……

image-20210511142142909

我的思路是利用报错注入,利用那三种报错注入显示数据库信息。

接下来利用三种语句的其中之一利用information_schema库进行注入即可

image-20210511145507931

在报错注入过程中会出出现字符串信息显示不全的问题

解决方案:

  1. limit(pos,len)

  2. mid(str,startpos,len) example:

    and updatexml(1,concat(0x7e,mid((select group_concat(schema_name) from information_schema.schemata),1,31),0x7e),1) %23

    and updatexml(1,concat(0x7e,mid((select group_concat(schema_name) from information_schema.schemata),32,31),0x7e),1) %23

  3. substr(str,startpos,len) 用法同mid()

第六关

输入 '单引号没错误显示,可能不是单引号字符注入,试试双引号成功回显语法错误信息,看来是id用双引号包起来的,再在后面加个注释符看看错误信息消不消失,如果消失了,那就是双引号字符注入。果然错误信息消除,正常回显信息。

image-20210512221642700

于是开始下一波的操作,查询列数,回显数据库的相关信息。很明显这一关他不回显数据库中的正确信息,如果语法正确他只显示You are in……,看来只能用报错注入语句试试了。

image-20210512222329424

成功通关

第七关

第七关输入 '单引号报错了,然后输入注释符还是报错。输入双引号并不会报错说明不是双引号字符报错。在单引号后面输入)括号加上注释符还是报错,试试在单引号后面加上两个))引号+注释符,报错消失了,说明payload是 ')) #。于是开始注入,判断列数和数据库信息,但是都不回显有用的信息,用报错注入还会提示有语法错误。

image-20210513212407123

提示了 Use outfile

百度一下

导出文件GET字符型注入

导出到文件就是可以将查询结果导出到一个文件中,如常见的将一句话木马导出到一个php文件中,sqlmap中也有导出一句话和一个文件上传的页面

常用的语句是: select "" into outfile "XXX\test.php" ,当这里要获取到网站的在系统中的具体路径(绝对路径)

这个要怎么获取呢,根据系统和数据库猜测,如winserver的iis默认路径是c:/inetpub/wwwroot/,这好像说偏了,这是asp的,但知道也好

linux的nginx一般是/usr/local/nginx/html,/home/wwwroot/default,/usr/share/nginx,/var/www/htm等

apache 就/var/www/htm,/var/www/html/htdocs

获取路径下面给一个很有可能获取得到的方法,(因为less7不输出信息,先从less获取信息)

首先介绍两个可以说是函数,还是变量的东西

@@datadir 读取数据库路径 @@basedir MYSQL 获取安装路径

那对于此处注入 没有输出 没有报错 信息回显 我们可以干嘛呐???

可以写入文件 别问我为什么知道 他上面写了outfile 可是我们不知道他的绝对路径 从何写入

判断是否有写权限,可以判断有写权限

/Less-7?id=1')) and (select count(*)from mysql.user)>0 --+ //如果返回正常则有读写权限

没办法了 这里只有从第一关来获取了

image-20210513213648272

现在就是要根据目录判断该项目的地址,并写一个一句话木马文件进行连接

构造payload

上传成功,这里注意会出现 **mysql 报错The MySQL server is running with the --secure-file-priv option so it cannot execute**,需要在my.ini修改secure_file_priv='into 文件的地址'

image-20210513220146623

然后用蚁剑成功连接服务器

image-20210513220212340

第八关

报错注入和普通语句错误都不回显错误信息,语法输入正确只是显示you are in……

看来是需要用盲注了,时间盲注或者布尔盲注。弄个脚本爆破试试

盲注需要掌握一些mysql的相关函数:

length(str): 返回str字符串的长度

substr(str,pos,len): 将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是 数组的0开始

mid(str,pos,len): 跟上面的substr一样,截取字符串

ascii(str): 返回字符串str的最左面字符的ASCII码

ord(str): 同上,返回ASCII码

if(a,b,c): a为条件,a为true,返回b,否则返回c,如if(1>2,1,0)这个式子返回0

需要我们要记得常见的ASCII,A:65,Z:90,a:97,z:122,0:48,9:57:a

首先 select database()查询数据库

ascii(substr((select database()),1,1)): 返回数据库名称的第一个字母,转化为ASCII码

ascii(substr((select database()),1,1))>64:ascii大于64就返回true,if就返回1,否则返回0

payload:

python GET布尔盲注脚本:

更多脚本代码(get时间盲注、post布尔盲注、post时间盲注)arrow-up-right

成功爆出用户名和密码

image-20210517203014403

第九关

这一关无论输入什么特殊字符,出现语法错误和正常SQL语句返回的页面都是一样的,看看源码显示,限制了正确结果与错误结果返回的页面一致,看来不能使用布尔盲注了,要使用时间盲注。

image-20210517203434270

接下来,学习基于时间型SQL盲注。

我们在这里使用if(查询语句,1,sleep(5)),即如果我们的查询语句为真,那么直接返回结果;如果我们的查询语句为假,那么过5秒之后返回页面。所以我们就根据返回页面的时间长短来判断我们的查询语句是否执行正确,即我们的出发点就回到了之前的基于布尔的SQL盲注,也就是构造查询语句来判断结果是否为真。

先判断能不能基于时间盲注来展开注入错误的语句 等了5秒才返回的 能基于时间的错误进行盲注

成功执行语句,页面加载了5秒,说明注入语句成功,接下来就是爆破数据库名、表名、列名、数据库信息。

时间盲注脚本,准确度不太满意,由于时间网页延迟的问题,多换几个时间就可以了

image-20210517211032100

第十关

和第九关一样,错误输入和正确输入的页面信息显示一样。先用时间盲注找出是字符型注入还是数字型注入,最终确定是双引号字符型注入

payload:

开始直接运行时间盲注的python脚本吧,在上一关的脚本的基础上,修改一下start_str字段即可

image-20210517212451407

准确率还是很差

第十一关

image-20210519114118567

使用post方法传递参数,经过测试username存在单引号字符型注入,并且没有过滤任何特殊字符

获取数据库payload:

image-20210519114246873

获取security数据库的表payload:

image-20210519114424756

security数据库中有表:emails、referers、uagents、users

现在获取users表中的所有字段,payload:

image-20210519114644033

security.users表中有字段:id、username、password

获取security.users表中的所有数据,payload:

image-20210519115045872

成功获取想得到的数据

第十二关

image-20210519122506609

这一关依然是post方法传递参数值

经过测试,这一关是 ") 字符型注入,并没有过滤任何特殊字符,payload:

image-20210519123004345

获取数据库版本信息、数据库名称等

image-20210519123224721

开始获取数据库,payload:

image-20210519123437363

获取hadsky数据库中的所有表名称,payload:

image-20210519123759380

获取hadsky.pk_user表中字段的信息,payload:

image-20210519124015764

获取hadsky.pk_user表中的username和password信息,payload:

image-20210519124320254

成功获取所需的username和password信息

第十三关

经过测试,本关卡是 ')'字符型注入,但是使用 union select字符并不会显示数据库版本之类的信息,估计后台代码并没写回显代码,接下来我试了报错注入和利用布尔盲注都成功了。接下来我还是选择报错注入语句

payload:

image-20210519125512762

开始利用information_schema数据库获取所有数据库名称,limit关键字是从0开始遍历的!!!

payload:

image-20210519130002929

接下来咱们获取一下数据库 mms中的一些信息,payload:

image-20210519130448745

mms数据库中有四张表,获取一下user表中的信息吧,下一步先获取user表中字段信息。payload:

image-20210519130636730

现在可以直接获得mms.user表中的信息了,payload:

image-20210519181903184

成功获得需要得到的信息,通过本关卡

第十四关

经过测试,本关卡是双引号字符型注入,并且注入的列数为两列

image-20210521113903090

但是使用 union select 无回显信息,报错注入成功显示信息

image-20210521114227279

获取数据库,其中用到了 right()函数:right(str, length),即:right(被截取字符串, 截取长度)

获得数据库payload:

image-20210521130413879

开始获取数据库 security中的表,payload:

image-20210521130702574

获取security.users表中的字段,payload:

image-20210521130823024

获取security.users表中的数据,payload:

image-20210521130942406

内容没有显示完全,可以使用left()或者right()查看剩余的内容

第十五关

image-20210521131658328

使用这个语句成功判断这一关是单引号字符注入,报错注入和union注入都不会回显任何消息,看来只能盲注了

使用布尔盲注,因为执行成功与失败页面会显示不同的图片内容

image-20210521132216267

下面就是编写py脚本,语句成功返回上面的图片

python脚本:

上面的脚本是获取 pikachu.message表中的content和time字段的信息,时间没有显示完全,使用以下函数调用索引即可:mid()、substr()、left()、right()、substring()

image-20210521192440701

通过python脚本正确遍历出数据库中的内容

第十六关

使用Username payload:aa") or 1 #判断出注入类型

image-20210527163352492

页面显示出了success图片,页面并无回显任何数据库信息,只显示报错图片和成功图片,所以可以采用python脚本的post方法布尔盲注

payload:

成功使用脚本爆破出表中的值

image-20210527170429861

第十七关

image-20210527170508219

要求重置密码,我们怎么根据重置密码来获取数据库中的值呢?

这里后台代码是先根据username的值来判断数据库中是否有输入的值,如果有的话,就会执行update语句,更新密码,这里的密码存在注入,由于它是update,所以就不能使用 union select,我们在这里可以使用报错注入

image-20210527173059828

而且通过语法错误回显可以测试出这一关是单引号字符型注入。但是通过这一关卡的前提是必须知道一个用户名。

获得数据库payload:

image-20210527173514622

获取表payload:注意:这里的updatexml关键字前面是and,这是因为1和报错注入语句要都执行,如果是or,执行完更新密码为1之后,后面的updatexml语句就不会执行

image-20210527174337740

从users表中查询password信息,报错了

image-20210527175607769
img

看来是更新信息的表和查信息的表不能同时使用,想办法绕过限制,在里面再嵌套一层select查询使用别名aa

payload:

image-20210527180352717

第十八关

image-20210602192059992

数据包请求头注入,抓包测试一下

这一关的代码:

image-20210602193555386

由于select语句做了很强的过滤,所以他并不存在注入,所以咱们只能从insert语句下手了。但是insert成功执行的前提就是需要成功输入正确的用户名和密码,才能执行到insert语句。

image-20210602194023706

接下来就是尝试在UA字段或者XXF字段注入SQL代码

image-20210602194220760

根据上述图片咱们发现XXF字段对ip并没有什么影响,所以尝试在ua字段中进行注入。在1后面加上单引号,报了语法错误,很明显此关卡是单引号字符注入。

image-20210602194354165

看到报错信息,猜想后台的insert语句应该是 : insert into table values('User-Agent','ip','username')

接下来我们尝试在User-Agent的位置进行注入测试,我们修改User-Agent的值使其符合整个insert into的语法,闭合后就应该为 insert into table values('1',1,1)#'ip','username'),成功绕过

image-20210602195344190

现在利用报错注入语句来注入到insert语句中

爆破出当前数据库

payload:

image-20210602200726586

获取当前数据库中的表名:

image-20210602201329697

获取users表中的字段:

image-20210602201505454

获取security.users表中的数据:

image-20210602201926359

成功获得users表中的数据

第十九关

image-20210602202311752
image-20210602202452936

这个关卡跟上一个关卡一样,都需要输入正确的username和password,才能进行insert注入。本关卡是对Referer字段字段进行注入:

image-20210602202656722

输入单引号提示有语法错误,本关卡是单引号字符型注入。但是并没有回显insert注入的字段有几个,咱们只能猜测了。

一个注入字段报错

image-20210602203036348

两个注入字段成功

image-20210602203119236

下面使用报错注入开始获取数据库中的数据信息

获取当前数据库名称信息:

image-20210602203720724

获取所有数据库名称信息:用substring()函数获取了全部信息

image-20210602204133315
image-20210602204303568
image-20210602204406153

获取security数据库中所有表的名称

image-20210602204525176

获取security.users表中的字段信息:

image-20210602204640784

获取security.users表中的数据信息:

image-20210602204815178
image-20210602204911776
image-20210602204926621

获取了全部的users表中的信息

第二十关

image-20210604200830978

在请求头字段加上cookie的uname字段,会回显一些数据信息,试试cookie是否存在注入漏洞。

经测试本关卡是字符型注入,union select

image-20210604201125396

获取所有数据库名称:

image-20210604201254604

获取security数据库中的所有表名:

image-20210604201554304

获取security.users表中的字段:

image-20210604201728550

获取security.users表中的所有数据

image-20210604201855487

第二十一关

下面是21关的源码

image-20210604202656519

他把cookie进行了base64解码,说明我们需要提前进行base64编码再修改cookie值,而且单引号加括号的注入方式

base64编码:

image-20210604203133165

会显得数据:

image-20210604203201799

接下来就是获取数据库的信息了,多一道步骤就是需要先base64编码,在传输到cooKie中

获取所有的数据库名称:

image-20210604203410776
image-20210604203423534

获取security数据中的所有表名称:

image-20210604203549704
image-20210604203541713

获取security.users表中的字段:

image-20210604203653839
image-20210604203714873

获取security.users表中的所有数据:

image-20210604203813712
image-20210604203833871

Last updated