Created
May 16, 2024 17:47
-
-
Save theSoberSobber/59d1eca9e8becd2d401c7a8e84417582 to your computer and use it in GitHub Desktop.
create a user_agents.txt and IPs.txt in the same directory, int user_agents.txt paste the comment at the end, needs libcurl, install by sudo apt-get install libcurl4-openssl-dev, compile using ++ -o scanner main.cpp -lcurl -pthread
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <string> | |
#include <vector> | |
#include <thread> | |
#include <curl/curl.h> | |
#include <cstdlib> | |
#include <ctime> | |
#include <sstream> | |
#include <mutex> | |
#include <algorithm> | |
#include <cctype> | |
const std::string USER_AGENT_FILE = "user_agents.txt"; | |
const std::string IP_FILE = "IPs.txt"; | |
const int NUM_THREADS = 2; | |
const std::vector<std::string> ENDPOINTS = {"mjpg/video.mjpg"}; | |
std::mutex ip_file_mutex; | |
bool check_ip(const std::string& ip_address) { | |
CURL* curl = curl_easy_init(); | |
if (!curl) return false; | |
curl_easy_setopt(curl, CURLOPT_URL, ("http://" + ip_address + ":80").c_str()); | |
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); | |
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); | |
CURLcode res = curl_easy_perform(curl); | |
curl_easy_cleanup(curl); | |
return (res == CURLE_OK); | |
} | |
bool is_cam(const std::string& content_type) { | |
return content_type == "multipart/x-mixed-replace; boundary=myboundary"; | |
} | |
void save_ip(const std::string& ip_address, const std::string& endpoint) { | |
std::lock_guard<std::mutex> guard(ip_file_mutex); | |
std::ofstream file(IP_FILE, std::ios::app); | |
if (file.is_open()) { | |
file << "http://" << ip_address << "/" << endpoint << "\n"; | |
file.close(); | |
} | |
} | |
size_t header_callback(char* buffer, size_t size, size_t nitems, std::string* headers) { | |
headers->append(buffer, size * nitems); | |
return size * nitems; | |
} | |
void scan_one(const std::vector<std::string>& user_agents) { | |
std::ostringstream ip_address; | |
ip_address << rand() % 256 << '.' << rand() % 256 << '.' << rand() % 256 << '.' << rand() % 256; | |
std::string selected_user_agent = user_agents[rand() % user_agents.size()]; | |
if (!check_ip(ip_address.str())) { | |
std::cerr << "IP Address " << ip_address.str() << " at port 80 did not respond.\n"; | |
return; | |
} | |
CURL* curl = curl_easy_init(); | |
if (!curl) return; | |
for (const auto& endpoint : ENDPOINTS) { | |
std::string url = "http://" + ip_address.str() + "/" + endpoint; | |
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | |
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); | |
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L); | |
curl_easy_setopt(curl, CURLOPT_USERAGENT, selected_user_agent.c_str()); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); | |
std::string headers; | |
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); | |
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headers); | |
CURLcode res = curl_easy_perform(curl); | |
if (res == CURLE_OK) { | |
long response_code; | |
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); | |
if (response_code == 200) { | |
std::cout << "http://" << ip_address.str() << "/" << endpoint << "\n"; | |
std::cout << "Generated IP Address: " << ip_address.str() << ", Endpoint: " << endpoint << "\n"; | |
std::cout << "User Agent: " << selected_user_agent << "\n"; | |
std::cout << "Response Headers:\n" << headers; | |
std::size_t pos = headers.find("Content-Type:"); | |
if (pos != std::string::npos) { | |
std::size_t end = headers.find("\r\n", pos); | |
std::string content_type = headers.substr(pos + 14, end - pos - 14); | |
if (is_cam(content_type)) { | |
std::cout << "Response suggests it's from a camera. Saving IP to " << IP_FILE << "\n"; | |
save_ip(ip_address.str(), endpoint); | |
} | |
} | |
} else { | |
std::cerr << "Received response with status code " << response_code << ". Skipping processing.\n"; | |
} | |
} else { | |
std::cerr << "Failed to retrieve headers from " << url << ": " << curl_easy_strerror(res) << "\n"; | |
} | |
} | |
curl_easy_cleanup(curl); | |
} | |
void scan(const std::vector<std::string>& user_agents) { | |
while (true) { | |
scan_one(user_agents); | |
} | |
} | |
std::vector<std::string> read_lines(const std::string& file_path) { | |
std::vector<std::string> lines; | |
std::ifstream file(file_path); | |
if (file.is_open()) { | |
std::string line; | |
while (std::getline(file, line)) { | |
line.erase(line.begin(), std::find_if(line.begin(), line.end(), [](unsigned char ch) { | |
return !std::isspace(ch); | |
})); | |
if (!line.empty()) { | |
lines.push_back(line); | |
} | |
} | |
file.close(); | |
} | |
return lines; | |
} | |
int main() { | |
srand(static_cast<unsigned int>(time(0))); | |
std::vector<std::string> user_agents = read_lines(USER_AGENT_FILE); | |
std::ofstream file(IP_FILE, std::ios::app); // Create the file if it doesn't exist | |
file.close(); | |
std::vector<std::thread> threads; | |
for (int i = 0; i < NUM_THREADS; ++i) { | |
threads.emplace_back(scan, user_agents); | |
} | |
for (auto& thread : threads) { | |
thread.join(); | |
} | |
return 0; | |
} | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/90.0.818.56 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/90.0.818.56 Safari/537.36 Edg/90.0.818.56 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15 | |
// Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 | |
// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to handle redirects and not skip 308's