SQL Injection Attack Lab
1、网上搜索并且阅读Four different tricks to bypass StackShield and StackGuard protection这篇文章,描述这些现有保护机制的弱点。
2、阅读下面这篇文章:
Bypassing non-executable-stack during exploitation using return-to-libc.
http://www.infosecwriters.com/text_resources/pdf/return-to-libc.pdf
3、阅读这个链接的第3章,解释怎样构造 return2libc 的访问链 http://www.phrack.org/issues.html?issue=58&id=4
4、阅读这个链接
https://bbs.pediy.com/thread-224643.htm
SQL Injection Attack Lab
Step1:实验环境搭建
(1)、配置DNS:
输入命令: sudo vim /etc/hosts
其实可以发现是已经配置好了的,后面的不需要再重新配置。
(2)、关闭php配置策略
输入命令:sudo vim /etc/php5/apache2/php.ini
(3)、启动Apache:
输入命令:sudo service apache2 start
Step2:select语句的sql注入
(1)、用火狐浏览器打开网址www.sqllabmysqlphpbb.com,其登陆界面如下:
(2)、分析漏洞
在实验指导PDF中给出了这部分的后台sql语句:
假设我们要登陆管理员admin账户,却不知道密码。因为这里可以看出没有任何输入检测措施,我们可以直接在username框中输入admin’#,这样即把where语句改变为:
WHERE username = ’amdin’# AND user_password = ’md5($password)’;
我们知道,#在sql语句中是表示注释的,即密码验证部分被注释掉了,我们就可以这样直接绕过密码验证。
(3)、执行攻击
点击登陆,可以发现登陆成功,并且是以admin的身份登陆的,如下图:
Step3:尝试修改数据库
由于希望对其他用户数据进行非法篡改,我们考虑执行update更新操作。构建如下注入语句:
amdin’;update USERS_TABLE set username=’hacker’where username=’admin’#
原理上说,是没有问题的,我们可以试一试。
发现报错。分析原因是MySql中采取了一种特殊的保护机制,mysq_query不允许提交多个请求,导致我们两个连续的请求就会报错。
Step1:首先注册一个自己的账号,如图所示:
Step2:使用Tamper Data插件,对递交信息进行修改
如果我们查看后台程序其实是可以发现整个更新(包括密码)都是放在一条set语句中的,而且没有对language进行输入审查,所以我们可以借此进行SQL注入,按照task1中方法把where语句偷换成where username=’bob’#,这样就把对我们自己账户的修改转移到了目标用户bob上,从而修改了他的密码。如下图:
这里具体的语句为:
我们在框中输入english’ where username=’bob’#
显示修改成功:
Step3:登陆验证攻击
我们登陆bob的账号,并使用我们刚才修改的密码654321登陆。
发现成功登陆bob的账号。
SQL注入漏洞的根本问题是数据与代码的分离失败,因此我们可以针对这个原因进行防御
1、Escaping Special Characters using magic quotes gpc
默认开启magic_quotes_gpc,将magic_quotes_gpc值设为On。如果输入的数据有单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符都会被加上反斜线。这些转义是必须的,如果这个选项为Off,那么我们就必须调用addslashes这个函数来为字符串增加转义。
2、Escaping Special Characters using addslashes()
addslashes()就是为变量中的'或者"加\,当有人在变量(url)打入特殊的字符串的时候,语义起到变化。加斜杠后破坏语义,所以起到防注入的作用。
3、Escaping Special Characters using mysql real escape string
避免使用特殊字,MySQL提供一个函数 mysql_real_escape_string(),这个函数可以用来过滤一些特殊字符;如\x00, \n, \r, \, ', " and \x1a;
4、Prepare Statement
预编译,传递给PreparedStatement对象的参数可以被强制进行类型转换,使开发人员可以确保在插入或查询数据时与底层的数据库格式匹配。
以上方法都能不同程度地提高数据库安全性。
(1)、在标准编译的C代码中,函数的参数位于堆栈中的高位地址,而不是返回地址,返回地址位于保存的帧指针之后,该指针始终位于局部变量之后。 当存在基于堆栈的缓冲区溢出条件时,我们可能能够控制函数的参数,这可能会将受保护的程序转变为易受攻击的程序。
(2)、StackGuard8的默认设置是使用金丝雀,固定值为0x000aff0d。 对于常见的字符串操作,不可能通过这个金丝雀写入,但是可以在不改变它的情况下写入金丝雀,有效地获得对帧指针的完全控制。
(3)、对于StackGuard,如果错误不是一次溢出而是完全缓冲区溢出,并且如果使用了金丝雀,我们可以完全控制调用者的帧指针,而不仅仅是一个字节。 StackShield也是如此,因为它不使用金丝雀。
(4)、在标准编译的C代码中,当不使用-fomit-frame-pointer14all时,相对于帧指针访问局部变量,如果我们完全控制它,我们可以选择在内存中放置局部变量的位置。
Bypassing non-executable-stack during exploitation using return-to-libc.
缓冲区溢出的常用攻击方法是用shellcode的地址来覆盖漏洞程序的返回地址,使得漏洞程序去执行存放在栈中shellcode。为此有一种栈不可执行的保护机制使得以上方法失效
return-to-libc 攻击不需要一个栈可以执行,甚至不需要一个 shellcode。这个方法的基本原理是让漏洞程序调转到现存的代码(比如已经载入内存的libc库中的system()函数等)来实现我们的攻击。
fake_ebp0应该是“第一帧”的地址,fake_ebp1 - 第二帧的地址等。
接着:
1)易受攻击的函数的结尾(leave;ret)将fake_ebp0放入%ebp并返回到leaveret。
2)接下来的2条指令(leave; ret)将fake_ebp1放入%ebp并返回f1。 f1为合适的参数。
3)f1执行,然后返回。步骤2和3重复,用f1代替f2,f3,...,fn。
这篇文章主要展示了利用栈溢出绕过金丝雀。
主要的难点就是获取金丝雀的值。这题中有个fork。对fork而言,作用相当于自我复制,每一次复制出来的程序,内存布局都是一样的,当然canary值也一样。 那我们就可以逐位爆破,如果程序GG了就说明这一位不对,如果程序正常就可以接着跑下一位,直到跑出正确的canary。直接爆破canary。这是个32位的程序,所以canary有4个字节,最低位一定是\x00,所以只需要爆破三个字节即可。