我一直在努力了解有关SQL注入攻击的更多信息。我理解这个原则,但当我真正看到其中一些攻击时,我不知道他们是如何做他们正在做的事情。
通常看起来引用不均匀,并且通过HEX字符进行大量混淆。
我没有得到HEX字符......,它们肯定会被浏览器翻译回ASCII,那么重点是什么?
然而,我主要对奇怪的引用感到困惑。我现在很难找到一个例子,但通常看起来引用会在声明结束之前的某个时刻结束,那时我会认为它会在最后?
也许一个例子是'1或1 = 1
的常见用法这样的陈述是做什么的?
答案 0 :(得分:2)
我没有得到HEX角色..., 他们肯定会被翻译回来 浏览器的ASCII码
不。
然而,我主要是对此感到困惑 奇怪的引用。我遇到了麻烦 然而,现在找一个例子 它似乎通常会引用 在结束前的某个时刻结束 声明,我会的 以为它会在最后?
想象一下,您正在构建内联SQL而不是使用参数替换。我们将使用一种看似与PHP非常相似的虚构语言。
$sql = "delete from foo where bar = '" + $param + "'";
所以,现在,想象一下$param
被浏览器设置为......
$param = "' or 1=1 --"
(我们假装--
就像这里的SQL注释序列一样。如果不是这样的那种方式呢?
那么,现在,字符串替换完成后你的SQL是什么?
delete from foo where bar = '' or 1=1 --'
将删除foo
中的所有记录。
这有点简单,但它应该让你很好地了解不均匀的报价是什么。
答案 1 :(得分:2)
假设我们有一个表单,我们提交一个带有名称字段的表单。 name用于变量$ Name。然后运行此查询:
INSERT INTO Students VALUES ( '$Name' )
它将被翻译成:
INSERT INTO Students VALUES ( 'Robert' ); DROP TABLE STUDENTS; --')
- 是一个评论分隔符。之后,一切都将被忽略。 '用于分隔字符串文字。
在攻击中使用十六进制字符有一些原因。其中一个是混淆,另一个是绕过一些天真的安全措施。
答案 2 :(得分:2)
有些情况下,sql注入禁止引号。在这种情况下,攻击者必须使用编码方法,例如对其字符串进行十六进制编码。例如,'/etc/passwd'
可以写为0x2f6574632f706173737764
,不需要引号。以下是禁止引号的易受攻击查询的示例。 :
mysql_query("select name from users where id=".addslashes($_GET[id]));
如果要使用像load_file()
这样的mysql函数,则必须使用十六进制编码。
的PoC:/vuln.php?id=1 union select load_file(0x2f6574632f706173737764)
在这种情况下,正在读取/ etc / passwd,它将是第2行。
以下是我在MySQL SQL Injection漏洞利用中使用的十六进制编码函数的变体:
function charEncode($string){
$char="char(";
$size=strlen($string);
for($x=0;$x<$size;$x++){
$char.=ord($string[$x]).",";
}
$char[strlen($char)-1]=")%00";
return $char;
}
我对exploiting HLStats 1.35使用这种确切的方法。我还在我的php nuke exploit中使用此功能绕过xss过滤器,使用<?php?>
将into outfile
写入磁盘。重要的是要注意into outfile
是一个不接受函数输出或十六进制编码字符串的查询运算符,它只接受带引号的字符串作为路径,因此在{{1}上面的易受攻击的查询中攻击者不能使用它。其中into outfile
是函数调用,可以使用十六进制编码。
答案 3 :(得分:1)
引用不均匀; sql注入发生在编码器没有清除危险字符(如单引号)的用户输入的地方 - 请考虑以下语句
SELECT * FROM admin WHERE username='$_GET["user"]' and password='$_GET["pass"]'
如果我知道有效用户是'admin'并插入'or 1=1
我会得到以下
SELECT * FROM admin WHERE username='admin' and password='something' or 1=1
这将导致返回查询总是为真,因为无论密码的值如何,表达式的左侧始终为true。
这是sql注入的最简单的例子,你会发现攻击者根本不需要使用引用,或者可以使用注释分隔符(例如{{1})注释其余的查询。 }或--
,如果在注入点之后传递了更多参数。
对于HEX编码,可能有几个原因,避免过滤,使用十六进制编码值更容易,因为您不必担心在查询中引用所有值。
例如,如果您想使用/*
将两个字段共同标记在一起,这是非常有用的:
concat
哪一个提供第三行是可见的,返回为isntance inject.php?id=1 and 1=0 union select 1,2,concat(username,0x3a3a,password) from admin
。如果我不使用十六进制编码,我将不得不这样做:
admin::admin
这可能是前面提到的 inject.php?id=1 and 1=0 union select 1,2,concat(username,'::',password) from admin
函数的问题,但也可能是写得不好的正则表达式清理函数或者查询非常复杂。
Sql注入是一个非常广泛的主题,而我所涵盖的内容甚至都不是介绍。