首页 > 代码库 > sql注入

sql注入


一   什么是sql注入:

    SQL注入(Structured Query Language Injection)技术在国外最早出现在1999年,我国在2002年后开始大量出现,目前没有对SQL注入技术的标准定义,微软中国技术中心从2个方面进行了描述:

1)脚本注入式的攻击

2)恶意用户输入用来影响被执行的SQL脚本

SQL注入,就是攻击者通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到让后台数据库执行恶意的SQL命令的目的,并根据程序返回的结果,获得某些攻击者想得知的数据。

   sql注入的危害

1、未经授权状况下操作数据库中的数据,比如管理员密码,用户密码等信息;

2、恶意篡改网页内容,宣传虚假信息等;

3、私自添加系统帐号或者是数据库使用者帐号;

4、网页挂广告、木马病毒等;

5、上传webshell,进一步得到系统权限,控制电脑.获得肉鸡。

  sql注入原理

总体思路是:

(1)扫描目标网络信息(判断是否存在SQL注入漏洞);

(2)判断后台数据库类型;

(3)发现WEB虚拟目录

(4)上传木马;

(5)得到管理员权限。

详细介绍如下:

1、SQL注入一般存在于形如:http://xxx.xxx.xxx/abc.asp?p=YY的网站中。

2、在http://xxx.xxx.xxx/abc.asp?p=YY后面追加“and 1=1”,并访问该网址即http://xxx.xxx.xxx/abc.asp?p=YY and 1=1应该与访问原地址得到的结果相同。

3、在http://xxx.xxx.xxx/abc.asp?p=YY后面追加“and 1=2”,并访问该网址即http://xxx.xxx.xxx/abc.asp?p=YY and 1=2应该与访问原地址得到的结果不同,并提示数据库错误。

23同时满足则此网站必定存在SQL漏洞,可以进行sql注入攻击。)

4、访问http://xxx.xxx.xxx/abc.asp?p=YYand exists (select * from 网站数据库常用表段名)

网站数据库常用表段名:adminusers administrator 等,如果进入的网页像步骤二一样,是正常网页,证明存在该表段名。找寻该SQL数据库使用的表名,进而寻找网站的管理员名、密码等信息。

5、访问http://xxx.xxx.xxx/abc.asp?p=YYand exists (select [网站数据库常用字段名] from 第4步找到的可入侵表名)

网站数据库常用字段名:adminpassword username 等,如果进入的网页像步骤2一样,是正常网页,证明存在该字段名。找寻该SQL数据库使用的字段名,进而寻找网站的管理员名、密码等信息。

6、访问http://xxx.xxx.xxx/abc.asp?p=YYand exists (select *from第4步找到的可入侵表名where第5步找到的可入侵字段名like‘_ ‘)

7、访问http://xxx.xxx.xxx/可入侵后门字段名,找到网站后门。

8、利用从数据库中查到的敏感数据进入网站后门,可以任意的对数据库进行各种不同方式的增删改查操作。

 

 

 

   sql注入的方式

进行SQL注入时一般会用到两种方式,

第一是手工注入.

SQL篡改

攻击者试图通过向where语句增加元素或者利用集合操作符如UNION,INTERSECT和MINUS等来扩展SQL语句的方法来修改现有的SQL语句。

 

SELECT * FROM users  WHEREusername = ‘bob‘ and PASSWORD = ‘mypassword

 

       一个攻击者可能试图篡改SQL语句并执行下面的语句:

SELECT * FROM users  WHERE username = ‘bob‘ andPASSWORD = ‘mypassword‘ or ‘a‘ = ‘a‘  

 

 

 

       集合操作符UNION在SQL攻击中经常被使用到。目标是控制SQL语句来获取另外一张数据表中的元组。一个网页窗口可能执行下面的语句来获得所有可获取商品的列表:

SELECTproduct_name FROM all_products WHERE product_name like ‘%Chairs%‘

一个攻击者可能试图篡改SQL语句并执行下面的语句:

SELECTproduct_name FROM all_products WHERE product_name like ‘%Chairs

UNION  SELECTusername FROM dba_users

WHERE username like ‘ %‘

 

       2、代码注入

攻击试图向已有的SQL语句中增加额外的SQL语句或者命令

SELECT * FROM users WHERE username = ‘bob‘ and PASSWORD= ‘mypassword‘; DELETE FROM usersWHEREusername = ‘admin‘;

 

第二是工具注入。

  SQL注入实例演示

利用Pangolin工具实现针对MSSQL环境的SQL注入攻击。

1. 在本地主机上通过Internet Explorer等Web浏览器访问目标Web服务器(即Windows Server A,IP地址为192.168.1.103)的主页。

技术分享

点击其中的某一新闻链接后即访问显示出具体的某一新闻内容。比如http://192.168.1.103/news.aspx?id=1

技术分享

2. 在访问的网页URL地址后加上一个单引号(‘)继续访问,

即http://192.168.1.103/news.aspx?id=1‘,如下图所示:

技术分享

从图中可以看到数据库连接出错消息中可以看到如下错误消息“字符串 ‘‘  之前有未闭合的引号。”,也就是单引号没有闭合的意思。

3. 继续手动测试SQL注入是否存在:访问如下网页URL地址: 

http://192.168.1.103/news.aspx?id=1 and 1=1

技术分享

以及

http://192.168.1.103/news.aspx?id=1 and 1=2

技术分享

其中访问第一个网页地址的情况与正常情况相同,而访问第二个网页地址则一片空白,即新闻文档不存在的意思。

4. 进入实验工具目录,双击运行Pangolin程序(pangolin.exe),在注入地址“URL”输入框中输入http://192.168.1.103/news.aspx?id=1

技术分享

然后点击工具栏中的开始按钮开始自动检测SQL注入漏洞情况。从检测结果中可以看到,该网站的SQL注入类型为“Integer(字符型)”,后台数据库类型为“MS SQL with Error”。

5. 在主界面中的“Information”选项卡中,点击“Select All”按钮选择所有信息类型,包括下面所列举的“Version”、“Db Name”、“Server Name”等,然后点击“Go”按钮开始探测目标服务器的基本信息。

技术分享

6. 在主界面中选择“Data”选项卡,点击左下方的“Tables”按钮来枚举目标当前数据库中存在的所有数据表的名称。

7. 点击选择数据库中的“admin”表,然后点击下方的“Columns”按钮来枚举该数据表中所有的数据列名。展开“admin”表前面的“+”号可以查看详细的列名信息。

8. 勾选感兴趣的数据表以及其中的数据列,如admin表中的id、username以及password列,然后点击右侧的“Datas”按钮则可以枚举该表中的所有数据项内容。在这里,我们还可以通过自定义查询条件来自定义查询所感兴趣的数据内容,默认为“1=1”表示所有的数据内容。

技术分享

9. 在主界面中选择“Command”选项卡,然后在“Command”输入框中输入要在目标服务器上执行的系统命令,比如“ipconfig”等;在“Type”下拉框中选择执行命令的技术方法,默认为“xp_cmdshell”,其他可选的主要方法有“sp_oa***”等。最后点击右侧的“Execute”按钮执行命令,可在下方的黑色文本框中看到执行结果。

10. 选择“type”为“sp_oa***”,尝试执行添加用户的命令操作。

 技术分享

11. 在主界面中选择“Dir Tree”选项卡,然后点击“Drivers”按钮列举目标服务器上的所有驱动器。双击“C:\”节点可以进一步展开获得C:\根目录下的所有子目录和文件,依次可以获得磁盘上的目录结构。

12. 双击某一文件,可以在右侧的文本框中显示文件的详细内容。

13. 仔细查看“C:\inetpub\wwwroot”目录中的网站文件,获得连接后台MS SQL数据库的账号和密码。

 技术分享

五 sql注入的预防

一绑定变量(程序的预编译)

       针对SQL注入攻击最有效的方法是使用绑定变量。使用绑定变量同时也会提升程序的性能。程序编码标准应该要求所有的SQL语句都使用绑定变量。没有一个SQL语句应该用用拼接字符串或者参数传递的方式产生。

PreparedStatement pstmt = conn.prepareStatement ("insert into EMP (ENAME) values (?)");

 

String name =request.getParameter("name");

pstmt.setString (1, name);

pstmt.execute();

pstmt.close();

二输入有效性验证

       每一个传递进来的字符串参数都应该进行有效性验证。许多web应用程序使用的隐藏字段或者其他技术,也都需要进行有效性验证。如果不使用绑定变量,则需要对特殊的数据库字符进行删除或者过滤。

三错误信息

       如果攻击者无法获得程序的源代码,那么错误提示信息对于一次成功的攻击是至关重要的。许多Java程序并不返回错误信息的细节,程序需要进行分析和测试来确定是否返回错误信息的细节。相比将数据库错误信息返回给用户而言,将这些信息写入日志日志文件更妥当些。以至于让攻击者没法对数据库信息做试探。

四 sql语句转移

通过把完整的sql语句写入工程对应的配置文件中,比如根据key=value的方式把完整的sql语句封装到配置文件中,利用単例模式设计一个类把sql语句从配置文件中读取出来。

 

 

 

sql注入