Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
Hale — 봇넷 명령 및 제어 모니터 | Kitploit
도구/GitHubGitHub/pjlantz/hale
OSINT (Open Source Intelligence)ReconnaissanceInformation GatheringNetwork SecurityMalware AnalysisCommand and ControlThreat IntelligenceIncident Response
GitHubpjlantz/hale

Hale

봇넷 명령 및 제어 모니터

저장소 보기
20260504년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

정보

Hale는 모듈식 설계를 통해 C&C 서버에서 사용되는 새로운 프로토콜을 모니터링하는 새 모듈을 쉽게 개발할 수 있는 봇넷 명령 및 제어 모니터/스파이입니다. Hale는 많은 연결의 확장성을 처리하기 위해 Twisted로 개발된 IRC 및 HTTP 모니터를 제공합니다. 이 모듈들은 설정 가능한 프로토콜 문법과 봇 설정을 가지며 필요에 맞게 수정할 수도 있습니다. 캡처된 모든 로그와 파일은 데이터베이스에 저장되며, IRC의 경우 추적된 IP 번호도 저장됩니다.

운영자의 위치를 숨기기 위해 SOCKSv5 프록시를 통해 연결할 수 있으며, 이는 통계 차트와 타임라인과 함께 모든 로그를 탐색할 수 있는 웹 인터페이스를 통해 설정 가능합니다. 인터페이스는 Django와 Google Visualization API로 개발되었습니다. 웹 UI의 추가 기능으로는 OAuth를 지원하는 RESTful API와 검색 엔진 지원이 있습니다.

Hale의 주요 아이디어는 센서 네트워크(Hale 모니터)를 생성하여 봇넷 사냥 및 연구가 협력할 수 있도록 돕는 것입니다. 이 아이디어를 개선하기 위해 중앙 집중식 XMPP 서버에 연결할 수 있는 XMPP 봇을 사용할 수 있으며, 현재 두 개의 다른 그룹룸이 센서 간 조정에 사용되고 하나의 방이 로그 및 파일 공유에 사용됩니다. 조정 방은 봇넷 설정의 고유 키로 만들어진 봇넷 해시를 활용하므로, 동일한 해시(신원)를 가진 두 봇넷이 동시에 모니터링될 필요가 없어 효율성이 향상됩니다. 타사가 이 네트워크를 활용할 수 있도록 봇이 조정 방에 참여하여, 봇넷이 추적되지 않는 경우 해당 설정을 전송하여 센서가 추적을 시작하도록 요청할 수 있습니다. 또한 공유 방에서 타사 봇은 센서가 캡처한 로그와 파일을 실시간으로 받을 수 있습니다. 로그 기록을 지원하기 위해 GET 요청을 지원하는 웹 API를 사용할 수 있습니다.

설치

Hale의 의존성은 다음과 같습니다:

root@kitploit:~
Python == 2.6
Django == 1.2.1
Twisted == 10.1.0
GeoIP-Python == 1.2.4 (and GeoIP C lib)
Whoosh == 0.3.18
django-haystack == 1.0.1-final
django-piston == 0.2.3rc1
pefile == 1.2.10-63
sleekxmpp == 0.9Rrc1
wsgiref == 0.1.2
zope.interface == 3.6.1
oauth2 == 1.2.0
httplib2 == 0.6.0

또한 모니터는 django에서 사용하는 데이터베이스에 해당하는 데이터베이스 백엔드 드라이버가 필요합니다. 이 라이브러리들이 설치되면 여기서 소스를 다운로드하여 원하는 위치에 추출하세요.

설정

  1. 먼저 Hale에서 사용할 데이터베이스를 생성합니다. 데이터베이스 엔진은 원하는 것을 사용할 수 있습니다. 기존 데이터베이스를 사용하는 경우 이 단계를 건너뜁니다.

  2. 다음 단계는 서버 엔진에서 사용하는 데이터베이스에 해당하는 Python 데이터베이스 백엔드 드라이버를 설치하는 것입니다.

  3. hale/src/webdb/ 에 있는 settings.py 를 편집하고 ENGINE, NAME, USER, PASSWORD, HOST, PORT 설정을 수정합니다. 예를 들어 서버 엔진이 MySQL인 경우 엔진 설정은 django.db.backends.mysql 입니다. NAME 설정은 데이터베이스를 생성할 때 사용한 데이터베이스 이름입니다.

  4. 자체 웹 UI를 시작하지 않으려면 이 단계를 건너뛰고 8)로 이동하세요. settings.py 에서 PATH_TO_APP를 Django 애플리케이션의 전체 경로(예: '/home/..../Hale/src/webdb' )로 변경합니다. webdb 디렉토리에서 다음 명령을 실행합니다: python manage.py syncdb. 여기서 오류가 발생하면 settings.py 의 데이터베이스 설정이 올바르지 않은 경우가 대부분입니다. 또한 동기화 중에 사용자 관리를 위한 슈퍼유저를 설정하세요.

  5. 웹 인터페이스에서 검색을 지원하려면 python manage.py rebuild_index 를 실행하여 검색 엔진이 처음으로 인덱싱하도록 합니다. 그러면 whoosh.index/ 디렉토리가 생성됩니다. 웹 서버가 여기에 쓸 수 있도록 chmod o+w whoosh.index/ 를 실행합니다. 이후에는 python manage.py update_index 를 대신 실행하고, 원하는 정기적인 간격으로 인덱스를 업데이트하도록 cron 작업으로 설정하세요.

  6. python manage.py runserver 를 실행하고 http://127.0.0.1:8000 으로 이동하여 설정이 올바르게 되었는지 확인합니다.

  7. runserver 명령은 성능 문제로 인해 프로덕션 사용에는 권장되지 않는 개발 서버를 배포합니다. 대신 Apache용 mod_wsgi 를 설치하여 웹 UI를 배포하세요. Ubuntu를 사용 중인 경우 apt-get install libapache2-mod-wsgi 를 실행합니다. /etc/apache2/sites-available/default 에 다음을 추가합니다:

root@kitploit:~
    Alias /media /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media/
    <Location /media>
      Order allow,deny
      Allow from all
    </Location>


    WSGIDaemonProcess username processes=2 maximum-requests=500 threads=10
    WSGIProcessGroup group

    WSGIScriptAlias / /home/..../webdb/django.wsgi

그리고 WSGI 데몬이 실행될 username과 group을 편집합니다. WSGIScriptAlias 는 webdb 디렉토리에 있는 django.wsgi 파일의 전체 경로로 설정해야 합니다. 위에 지정된 Alias는 관리 페이지가 올바르게 렌더링되도록 하기 위해 필요합니다. 웹 인터페이스를 통해 모듈을 업로드할 수 있도록 chmod o+w webdb/modules 를 실행합니다.

  1. hale/src/modules/ 에서 사용할 모듈을 업로드하거나 직접 작성합니다(개발 섹션 참조). 관리 인터페이스에서 원하는 모듈을 업로드하고, 예를 들어 모듈 이름을 irc , 파일 이름을 ircModule.py 로 편집합니다. hale/conf/modules.conf 의 해당 섹션에 모듈에 대한 config 규칙을 지정하고 텍스트 상자에 넣습니다. 또한 업로드하는 모듈에 대한 uniqueKeys 섹션도 추가합니다.

  2. 모니터를 실행하기 전에 XMPP 서버를 사용하려면 hale/src/conf/ 의 hale.conf 를 편집합니다. XMPP 봇을 활성화하려면 use 설정을 True로 설정하고 기존 계정 및 서버의 로그인 정보를 편집하거나 자체 XMPP 서버를 시작합니다. XMPP 서버를 시작할 때 중요한 단계는 최대 스탠자 크기를 기본값에서 약 10Mb로 늘리는 것입니다. 그렇지 않으면 악성코드 광고가 불가능합니다. hale.conf 의 채널 설정은 봇이 사용하는 공유 그룹룸에 사용되고, coord 설정은 모든 센서 간 조정이 이루어지는 그룹룸에 사용됩니다.

  3. hale.conf 를 편집하고 클라이언트 및 서버 설정을 지정합니다.

사용법

모니터를 시작하려면 hale/src/ 로 이동하여 python server.py 를 실행합니다. 오류가 발생하면 django settings.py 파일이 올바르게 설정되지 않았거나 일부 라이브러리가 누락된 것입니다. 클라이언트를 사용하여 서버에 명령을 내릴 수 있지만 사용자는 서버에 대해 인증을 받아야 합니다. 웹 인터페이스를 통해 스태프 구성원으로 설정된 사용자에게만 액세스가 허용됩니다. 클라이언트가 실행 중일 때 help 또는 ? 를 입력하면 사용 가능한 명령을 확인할 수 있습니다. help 명령어를 입력하면 특정 명령에 대한 자세한 정보를 얻을 수 있습니다. 모니터 봇을 시작하려면 먼저 hale/src/conf/modules.conf 파일을 편집합니다. 예를 들어 다음과 같은 irc 구성을 사용합니다:

root@kitploit:~
[uniqueKeys]
irc = botnet, *grammar

[ircConf] 
module = irc 
botnet = irc.freenode.net 
port = 6667 
password = None 
nick = nickname
username = agent007 
realname = Spying 
channel = #channelname 
channel_pass = somepass 
pass_grammar = PASS 
nick_grammar = NICK 
user_grammar = USER 
join_grammar = JOIN 
version_grammar = VERSION 
time_grammar = TIME 
privmsg_grammar = PRIVMSG 
topic_grammar = TOPIC 
currenttopic_grammar = 332 
ping_grammar = PING 
pong_grammar = PONG

새로운 고유 이름의 섹션([ircConf] 부분)을 지정하여 구성을 편집하거나 새로 만듭니다. 구성 파일 상단에는 uniqueKeys 라는 섹션이 있으며, 여기에는 모듈의 모든 고유 필드가 지정되고 봇넷 해시를 생성하는 데 사용됩니다. 올바른 봇넷 추적을 유지하기 위해 일반적으로 변경해서는 안 됩니다. 완료되면 useconf section 을 실행하여 구성을 로드한 다음 exec modulename id 로 봇을 실행합니다. 여기서 id는 봇넷을 식별하기 위해 사용자가 설정합니다.

웹 인터페이스는 데이터베이스에 캡처된 모든 데이터에 대한 액세스를 제공하며 색인 페이지에서 접근할 수 있습니다. 또한 사용자가 봇넷 및 파일 해시, 관련 IP 번호, 봇넷 ID, 사용된 봇넷 모듈 및 봇넷 호스트를 검색할 수 있는 검색 기능이 있습니다. 사용자가 프록시 또는 모듈을 편집할 수 있는 액세스 권한이 있는 경우 관리 섹션에서 수행할 수 있으며, URL은 http://.../admin 입니다. 관리자는 사용자 모드를 설정하고 웹 API 소비자를 추가할 수 있습니다.

개발

모듈 추가 방법

  1. 모듈 구현 예시:

    import moduleManager from utils import moduleInterface

    @moduleManager.register("irc") def module_setup(config, hash): """ 함수를 사용하여 모듈 등록. 단순히 config와 hash를 모듈 객체에 전달하고 다시 반환하도록 구현합니다. """

    root@kitploit:~
     return IRC(config, hash)
    

    Module 클래스를 상속해야 함

    class IRC(moduleInterface.Module):

    root@kitploit:~
    def __init__(self, config, hash):
        self.config = config
        self.hash = hash
    
    # 반드시 구현해야 함
    def stop(self):
        # 실행 중지
    
    # 반드시 구현해야 함
    def run(self):
        # 실행 시작
    
    # 반드시 구현해야 함    
    def getConfig(self):
        return self.config
    

등록 함수(이 경우 module_setup)에 데코레이터를 추가합니다. 이 함수는 현재 구성과 고유 키로 만들어진 구성 해시를 인수로 호출됩니다. 함수 이름은 무엇이든 될 수 있습니다. 구성을 모듈 객체에 전달합니다. configHandler는 KeyErrors를 포착하므로 이 함수에 잘못된 구성이 전송되면 configHandler가 이에 대해 알려줍니다.

또한 명명 규칙 nameModule.py 와 @moduleManager.register("name") 을 따르고 moduleManager 를 임포트해야 합니다. 그렇지 않으면 moduleManager가 오류를 알려줍니다.

나머지 모듈 코드는 생략되었지만 twisted 팩토리 객체를 생성하고 run 메서드에서 reactor로 시작해야 합니다. 예제는 기존 모듈을 참조하세요. Twisted 프로그래밍 튜토리얼은 여기를 참조하십시오. 또한 모듈을 개발할 때 사용할 수 있는 일부 유틸리티가 있습니다. 다음과 같이 사용합니다:

Socksify:

root@kitploit:~
# 모든 유틸리티 임포트
from utils import *

# 생성자에서 새 프록시 객체 생성
self.prox = proxySelector.ProxySelector()

# run 메서드에서 팩토리 메서드를 생성한 후 다음을 추가
proxyInfo = self.prox.getRandomProxy()
    if proxyInfo == None:
        self.connector = reactor.connectTCP(host, port, factory)
    else:
        proxyHost = proxyInfo['HOST']
        proxyPort = proxyInfo['PORT']
        proxyUser = proxyInfo['USER']
        proxyPass = proxyInfo['PASS']
        socksify = socks5.ProxyClientCreator(reactor, factory)
        if len(proxyUser) == 0:
            self.connector = socksify.connectSocks5Proxy(host, port, proxyHost, proxyPort, "HALE")
        else:
            self.connector = socksify.connectSocks5Proxy(host, port, proxyHost, proxyPort, "HALE", proxyUser, proxyPass)

팩토리 객체에서 연결 오류 처리:

root@kitploit:~
def clientConnectionFailed(self, connector, reason):
    """
    서버 연결 실패 시 호출
    """

    moduleCoordinator.ModuleCoordinator().putError("Error connecting to " + self.config['botnet'], self.module)

def clientConnectionLost(self, connector, reason):
    """
    서버 연결 끊김 시 호출
    """

    moduleCoordinator.ModuleCoordinator().putError("Connection lost to " + self.config['botnet'], self.module)

이렇게 하면 CLI에서 showlog 를 입력하여 접근할 수 있는 오류 버킷으로 오류가 전송됩니다.

로깅:

root@kitploit:~
# 팩토리에서 로그를 처리하기 위해 다음 메서드 생성 (해시와 config를 팩토리로 전달해야 함)
# 프로토콜 클래스에서 self.factory.putLog(data)로 호출
def putLog(self, log):
    """
    이벤트 핸들러에 로그 전달
    """
        
    moduleCoordinator.ModuleCoordinator().addEvent(moduleCoordinator.LOG_EVENT, log, self.hash, self.config)

# 정규 표현식을 적용하여 잠재적 악성코드를 포함한 URL 검색
# 프로토콜 클래스에서 self.factory.checkForURL(data)로 호출
def checkForURL(self, data):
    """
    이벤트 핸들러에서 URL 확인
    """
    
    moduleCoordinator.ModuleCoordinator().addEvent(moduleCoordinator.URL_EVENT, data, self.hash)

# 모듈이 다른 봇 및 조련사의 IP 번호를 감지해야 하는 경우 팩토리에 다음 메서드 구현
def addRelIP(self, data):
    """
    모니터링 중인 봇넷과 관련된 가능한 IP를
    이벤트 핸들러에 추가
    """
        
    moduleCoordinator.ModuleCoordinator().addEvent(moduleCoordinator.RELIP_EVENT, data, self.hash)

관련 IP 처리는 모듈이 지원할 프로토콜에 사용될 정규 표현식을 적용하여 수행됩니다. irc 모듈의 경우 코드는 다음과 같습니다:

root@kitploit:~
checkHost = data.split(':')[1].split(' ')[0].strip()
match = self.factory.expr.findall(checkHost)
if match:
    self.factory.addRelIP(data.split('@')[1].split(' ')[0].strip())

여기서 정규 표현식은 다음과 같습니다:

root@kitploit:~
self.expr = re.compile('!~.*?@')

2) 파일을 모듈 디렉토리로 드래그합니다. moduleManager가 자동으로 임포트하고 오류를 확인합니다.

  1. modules.conf에서 구성을 편집합니다.

  2. 모듈 이름을 예를 들어 irc, 파일 이름을 ircModule.py로 설정하고 이 모듈에 대한 구성 예제를 추가하여 웹 UI에 모듈을 업로드합니다.

XMPP 봇 방법

추적할 봇넷을 요청할 때 요청은 다음과 같이 그룹챗 조정 방으로 이루어집니다.

root@kitploit:~
sensorLoadReq

그러면 모든 센서가 자신의 ID와 큐 길이(모니터링 중인 봇넷 수)로 응답합니다.

root@kitploit:~
sensorLoadAck id=353f6650859547ed06597dbfa1dcfd88 queue=0

피더는 이 정보를 기반으로 가장 낮은 큐 길이를 가진 센서를 선택하고, 여러 센서가 동일한 경우 알파벳순으로 정렬된 센서 ID 중 가장 낮은 값을 가진 센서를 선택합니다.

피더가 센서를 선택하면 센서에게 개인 채팅 메시지를 보냅니다.

root@kitploit:~
startTrackReq config

여기서 config는 구성의 문자열 표현입니다. 예:

root@kitploit:~
module=irc botnet=irc.freenode.net etc..

그러면 센서는 구성 해시와 함께 확인 응답으로 응답합니다. 이 해시는 공유 채널에서 다른 로그와 봇넷 로그를 구별하는 데 사용됩니다. 확인 응답 예시:

root@kitploit:~
startTrackAck hash

아무도 이 봇넷을 모니터링하지 않는 경우 이 응답이 수신됩니다. 그렇지 않으면 봇넷이 이미 모니터링 중이거나 센서가 이 봇넷에 대한 모듈이 설치되지 않은 경우 startTrackNack이 수신됩니다. 악성코드 공유는 센서가 다음과 같은 메시지를 보내는 방식으로 이루어집니다:

root@kitploit:~
fileCaptured hash=353f6650... file content

여기서 콘텐츠는 Base64로 인코딩되며 파일 해시 값 바로 뒤에 옵니다.

RESTful 웹 API

API에 액세스하려면 소비자 키와 시크릿 키가 필요합니다. 이는 관리자가 생성할 수 있으며 OAuth를 사용하여 인증하는 데 사용됩니다. JSON 형식으로 데이터를 가져오기 위해 다음 URL을 사용할 수 있습니다:

root@kitploit:~
http://.../api/botnet 모든 모니터링된 봇넷 반환
http://.../api/botnet/botnethash 해시가 botnethash와 동일한 봇넷 반환
http://.../api/host/hostname host가 hostname과 동일한 모니터링된 모든 봇넷 반환
http://.../api/type/module 해당 모듈로 모니터링된 모든 봇넷 반환
http://.../api/botips/hash 해시 값으로 봇넷이 캡처한 모든 IP 반환
http://.../api/bologs/hash 해시 값으로 봇넷의 모든 로그 반환
http://.../api/bofiles/hash 해시 값으로 봇넷이 캡처한 파일 해시 반환
http://.../api/file/hash 지정된 해시의 파일을 캡처한 봇넷 정보 반환
http://.../api/ip/addr IP 번호 addr를 감지한 봇넷 정보 반환

현재 GET 요청만 가능합니다.

도구 다운로드