-
-
[翻译]如何安全地进行SQL注入测试
-
发表于: 2017-8-4 06:06 5285
-
如果从Gitlab最近的离线事件(他们处理的非常好)能够吸取某个教训的话,那就是公司必须溺爱般地保护他们的生产数据库;而作为渗透工程师,这个责任也延伸到我们。生产数据库从本质上就不适合作为实验的场所,因为任何意外的结果都可能对数据造成不可逆的不良影响,但渗透测试(至少黑盒渗透)却必须通过实验的方式寻找漏洞。本篇文章讨论的就是如何在避免修改数据的情况下安全地在生产数据库寻找漏洞。
许多公司都允许对生产服务器和数据库的测试,而这也并非没有道理:生产环境是公司最可能被攻击的位置,所以必须经过严密测试。虽然本文中说的所有内容都同样适用于非生产环境,但在其他环境下意外修改数据的后果相比之下并不严重。作为渗透工程师,最大的噩梦恐怕就是自己的一个失误搞垮了客户的生产环境。运气好的话也许仅导致一些离线时间,通过备份可以恢复服务器;差的话可能用户没有完整的备份,失误直接导致关键数据丢失。我们必须找到一种不会意外修改生产数据的方法来测试SQL注入。
我用谷歌搜索了“安全的SQL注入”,却没有找到任何相关的结果。当然,肯定有其他人写过这个话题,NetSPI(原作者公司)的其他员工们也提到过他们解决这个问题的方法,但我希望通过这篇博文让这个话题获得更广泛的关注并易于访问。
准备测试环境
让我们来重现一下常见的数据库环境,来测试我们的注入。我们先安装三款企业常用的关系数据库管理系统(RDBMS),MySQL、MSSQL、和Oracle,并在它们中各创建一个储存用户的表(USERS),如下。
RDBMS
Create Table
MySQL 5.7.12
MSSQL Server 2014 Express Edition
Oracle SQL 12c
再添加一些用户。
RDBMS
Add Users
MySQL 5.7.12
MSSQL Server 2014 Express Edition
Oracle SQL 12c
新手渗透工程师的第一天
在设置完成后,每个数据库里都有一个名为USERS的表,它们的结构如下:
username
password
1
jake
reynolds
2
net
spi
3
johnjacob
jingle
heimer@schmidt.com
对于多数渗透测试来说,用户表通常第一个被触碰的表,因为它被用于用户登录。我们假设查询它的代码如下:
很明显,这段代码存在SQL注入漏洞,但它本身并不能对系统造成什么影响(仅是泄露数据),所以我们案例中的新手渗透工程师可以大胆地随意注入’ or 1=1 --。但如果是下面这段查询代码呢?这段代码用于更新用户的电子邮箱:
这回,如果渗透工程师还在大意地随便乱用’ or 1=1 --,则后果不堪设想。
username
password
1
jake
reynolds
2
net
spi
3
johnjacob
jingle
糟啦!
公司数据库中的所有电子邮件都被删除了。假设这个公司没有完整的备份,无法恢复这些邮件,那接下来该怎么办?更新一下简历,准备去面试吧– 这个工程师可以和这份工作说再见了。
如何保住你的工作
有几种办法可以避免上述的失误,而它们的关键其实都在于多花一秒时间去思考服务器需要执行什么类型的查询来实现被测试的功能。咱们换个角度来看刚才执行的这个查询。
虽然在黑盒测试中我们看不到服务器上执行的代码,但我们能看到浏览器向它发送的请求,如下:
从这个HTTP请求的格式和服务端点的名称应该不难推断出服务器需要执行的查询。很明显,这个服务端点的用途是更新用户的电邮,那必然会执行UPDATE查询。我们的目标就是找到既可证明SQL注入漏洞存在,又不会造成破坏的注入载荷,并用其进行测试。
我们先来试试串联两个字符串。我们先用一个单引号结束当前的字符串,然后用相应的串联运算符将另一个字符串与其串联。如果数据库成功将两个字符串串联在一起,我们就能得知它存在SQL注入漏洞了。
MSSQL
MySQL
Oracle
'+'concat
con' 'cat'
'||'concat
虽然每个数据库系统的语法不太一样,但它们的功效都等同于:
若是成功,那么数据库的内容将被更新为:
username
password
1
jake
reynolds
concat
2
net
spi
alex@netspi.com
3
johnjacob
jingle
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [翻译]返回导向编程实例入门 9646
- [翻译]如何安全地进行SQL注入测试 5286
- [翻译]利用命令注入控制雅虎服务器 9189
- [翻译]Moodle远程代码执行漏洞 9767