C++ for Cyber Security
Build high-performance security tools with C++ - from network scanners to malware analyzers. Combines C's power with modern OOP and safety features.
Why C++ for Security
C++ combines C's low-level access with object-oriented programming, making it ideal for building professional-grade security tools. Many commercial security products, antivirus engines, and network scanners are written in C++.
- Performance - Near-C speed for real-time packet processing and analysis.
- OOP - Clean architecture for complex security tools with classes and inheritance.
- STL - Standard Template Library provides containers, algorithms, and iterators.
- Memory control - Smart pointers for safe memory management.
- Cross-platform - Build tools for Linux, Windows, and embedded systems.
C++ Basics
cpp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
struct ScanResult {
int port;
bool open;
std::string service;
};
int main() {
// Vector for dynamic arrays
std::vector<ScanResult> results;
// Map for service lookup
std::map<int, std::string> services = {
{22, "SSH"}, {80, "HTTP"}, {443, "HTTPS"}
};
// Range-based for loop
for (const auto& [port, name] : services) {
results.push_back({port, true, name});
std::cout << "[+] Port " << port << ": " << name << std::endl;
}
// Lambda for filtering
auto https_results = std::find_if(results.begin(), results.end(),
[](const ScanResult& r) { return r.service == "HTTPS"; });
if (https_results != results.end()) {
std::cout << "Found HTTPS on port " << https_results->port << std::endl;
}
return 0;
}
OOP for Security Tools
cpp - SecurityScanner.h
#include <iostream>
#include <string>
#include <vector>
#include <functional>
// Abstract base class for security scanners
class Scanner {
protected:
std::string target;
int timeout;
public:
Scanner(const std::string& t, int tm = 3)
: target(t), timeout(tm) {}
virtual ~Scanner() = default;
// Pure virtual - must be implemented
virtual void scan() = 0;
virtual std::string name() const = 0;
};
// Concrete port scanner
class PortScanner : public Scanner {
private:
int start_port, end_port;
public:
PortScanner(const std::string& t, int s, int e)
: Scanner(t), start_port(s), end_port(e) {}
void scan() override {
std::cout << "Scanning ports " << start_port
<< "-" << end_port << " on " << target << std::endl;
}
std::string name() const override { return "PortScanner"; }
};
// Concrete web scanner
class WebScanner : public Scanner {
private:
std::vector<std::string> paths;
public:
WebScanner(const std::string& t)
: Scanner(t), paths({"/admin", "/backup", "/.env"}) {}
void scan() override {
for (const auto& path : paths) {
std::cout << "Checking " << target << path << std::endl;
}
}
std::string name() const override { return "WebScanner"; }
};
Memory Management
cpp
#include <memory>
#include <iostream>
// Raw pointer - DANGEROUS (C-style)
void dangerous() {
int* ptr = new int(42);
// If exception thrown here, ptr leaks!
delete ptr; // Easy to forget
}
// Smart pointers - SAFE (modern C++)
void safe() {
// unique_ptr - exclusive ownership
auto uptr = std::make_unique<int>(42);
// shared_ptr - reference counted
auto sptr = std::make_shared<std::string>("secret");
auto sptr2 = sptr; // Both point to same data
// Automatically freed when scope ends - no leaks!
}
// RAII for security resources
class Socket {
private:
int fd;
public:
Socket(int domain, int type)
: fd(socket(domain, type, 0)) {}
~Socket() {
if (fd >= 0) close(fd); // Auto-cleanup!
}
int get_fd() const { return fd; }
bool is_valid() const { return fd >= 0; }
};
Network Programming
cpp - port_scanner.cpp
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <atomic>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
std::mutex cout_mutex;
std::atomic<int> open_count(0);
void scan_port(const std::string& ip, int port) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) return;
struct sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, ip.c_str(), &addr.sin_addr);
// Set timeout
struct timeval tv{.tv_sec = 1};
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
std::lock_guard<std::mutex> lock(cout_mutex);
std::cout << "[+] Port " << port << " OPEN" << std::endl;
open_count++;
}
close(sock);
}
int main(int argc, char** argv) {
std::string target = (argc > 1) ? argv[1] : "127.0.0.1";
std::vector<std::thread> threads;
for (int port = 1; port <= 1024; port++) {
threads.emplace_back(scan_port, target, port);
if (threads.size() >= 100) {
for (auto& t : threads) t.join();
threads.clear();
}
}
for (auto& t : threads) t.join();
std::cout << "\nFound " << open_count << " open ports" << std::endl;
return 0;
}
Building Security Tools
cpp - network_tool.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <thread>
#include <mutex>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
class ServiceDetector {
private:
std::map<int, std::string> common_services = {
{21, "FTP"}, {22, "SSH"}, {25, "SMTP"},
{80, "HTTP"}, {443, "HTTPS"}, {3306, "MySQL"},
{3389, "RDP"}, {5432, "PostgreSQL"}, {8080, "HTTP-Alt"}
};
std::string host;
std::mutex result_mutex;
std::vector<std::pair<int, std::string>> open_services;
public:
ServiceDetector(const std::string& h) : host(h) {}
void detect(int port) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) return;
struct sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, host.c_str(), &addr.sin_addr);
struct timeval tv{.tv_sec = 2};
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
std::string service = common_services.count(port) ?
common_services[port] : "Unknown";
std::lock_guard<std::mutex> lock(result_mutex);
open_services.emplace_back(port, service);
}
close(sock);
}
void run(int start = 1, int end = 1024) {
std::vector<std::thread> threads;
for (int p = start; p <= end; p++) {
threads.emplace_back(&ServiceDetector::detect, this, p);
if (threads.size() >= 100) {
for (auto& t : threads) t.join();
threads.clear();
}
}
for (auto& t : threads) t.join();
std::sort(open_services.begin(), open_services.end());
for (const auto& [port, svc] : open_services) {
std::cout << "[+] Port " << port << ": " << svc << std::endl;
}
}
};
int main(int argc, char** argv) {
std::string target = (argc > 1) ? argv[1] : "127.0.0.1";
ServiceDetector scanner(target);
std::cout << "[*] Scanning " << target << std::endl;
scanner.run();
return 0;
}
Practice
Extend this tool by adding SSL/TLS certificate checking, HTTP response analysis, and vulnerability signature matching.
Resources
- C++ Reference: cplusplus.com
- Effective C++: Scott Meyers
- Network Security Tools: Building custom tools with C++ sockets
- Rootkits and Botnets: Understanding at the system level