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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
WEASEL — 레드팀용 DNS 은닉 채널 임플란트. | Kitploit
도구/GitHubGitHub/facebookarchive/weasel
Encryption/Decryption ToolsPersistence MechanismsPost-ExploitationPenetration TestingCommand and ControlRed TeamingPayload DevelopmentDNS AnalysisArchived
GitHubfacebookarchive/weasel

WEASEL

레드팀용 DNS 은닉 채널 임플란트.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

WEASEL: 은밀한 DNS 비콘

WEASEL은 종속성이 없는 Python 3를 사용하는 소형 인메모리 임플란트입니다. 비콘 클라이언트는 호스트에 대한 소량의 식별 정보를 사용자가 제어하는 DNS 영역으로 전송합니다. WEASEL 서버는 클라이언트에게 미리 준비된 명령 또는 임의의 명령을 실행하도록 작업을 할당할 수 있습니다.

WEASEL은 1단계 페이로드로, 탐지하기 어렵고 소음이 많은 모든 기능을 갖춘 스테이지가 탐지되었을 때 접근 권한을 다시 확보하는 데 유용하도록 설계되었습니다.

상태

  • 실제 작전에서 성공적으로 사용되었으며 탐지를 회피했습니다.
  • 클라이언트는 서버와 세션을 초기화하고 양방향 통신을 설정할 수 있습니다.
  • 서버에는 완전한 기능의 CLI가 있습니다.
  • 클라이언트는 서버가 작업을 할당할 수 있는 여러 기능을 지원합니다.
  • 클라이언트는 축소 및 난독화 시 5.2KB입니다.
  • 자동 난독화가 부족하여 수동 수정이 필요합니다(클라이언트 README의 제한 사항 참조).
  • 서버는 다중 플레이어(동시 다중 운영자)를 지원하지 않습니다.

예제

자세한 지침은 클라이언트 README 및 서버 README의 사용법을 참조하세요.

서버 또는 클라이언트를 시작하려면 스크립트를 직접 실행하거나 Python 인터프리터에 전달하세요.

C2 도메인 각각에 server.py를 실행하는 호스트의 IP 주소를 가리키는 NS 레코드가 있는지 확인하세요.

요구 사항

WEASEL은 Python 3.6+가 필요합니다.

클라이언트는 자체 포함되어 있으며 표준 라이브러리만 사용하므로 macOS, Linux 등에서 실행할 수 있습니다.

서버는 server/requirements.txt에 포함된 pip의 몇 가지 종속성이 있습니다. 서버는 Linux에서 실행되어야 하지만 macOS 또는 기타 *nix에서 실행되지 못할 이유는 없습니다.

개발 중 테스트 / 실행

이 경우 비콘을 난독화하고 최소화할 필요가 없습니다. print 문은 유지됩니다. 위의 사용법과 마찬가지로 beacon.py의 servers에 있는 도메인에 대한 NS 레코드가 server.py의 IP 주소를 가리키는지 확인하세요.

서버 호스트에서:

sudo python3 server.py

피해자 호스트에서(서버와 동일할 수 있음):

python3 beacon.py

아키텍처

WEASEL을 사용하기 위해 이 내용을 이해할 필요는 없습니다.

비콘은 AAAA 쿼리와 응답을 사용하여 DNS를 통해 통신합니다. DNS 멀웨어 및 터널에서 사용되는 것으로 알려져 있기 때문에 TXT 레코드는 사용하지 않습니다. 블루 팀은 종종 큰 TXT 쿼리에 대해 경고하는 DNS 터널링 탐지를 가지고 있습니다.

클라이언트 측은 작동에 root가 필요하지 않으며, raw 소켓을 사용하지 않고, 잘못된 형식의 DNS 패킷을 생성하지 않습니다. DNS 요청을 하기 위해 일반 시스템 및 언어 제공 인터페이스를 사용합니다. 정보는 레코드 자체에 인코딩 및 암호화됩니다.

  • 단일 A 레코드(IPv4 주소)는 4바이트의 정보를 포함할 수 있습니다.
  • 단일 AAAA 레코드(IPv6 주소)는 16바이트의 정보를 포함할 수 있습니다.
  • 쿼리에 사용되는 CNAME 레코드 및 호스트 이름은 서브도메인당 최대 64바이트를 포함할 수 있으며 RFC에 따라 총 255바이트를 초과하지 않아야 합니다. 그러나 SANS DNS 탐지 지침에 따르면 52자보다 긴 서브도메인은 의심스럽습니다. 이러한 이유로 서브도메인을 52자(코드에서 구성 가능)로 제한하고 필요한 것보다 더 많은 서브도메인과 요청을 사용하지 않도록 합니다.
  • 응답에는 UDP 데이터그램의 크기 제한(65,507바이트)까지 여러 레코드가 포함될 수 있습니다.

이 비콘은 낮고 느리며 대역폭이 적게 사용되도록 설계되었습니다. 어떤 호스트에 있는지 알려주고 필요에 따라 추가 스테이지를 시작할 수 있는 방법을 제공하며 그 이상은 아닙니다. 임의 명령 실행을 지원하지만 일반 대화형 셸이나 통신 채널로 사용하기 위한 것은 아닙니다.

WEASEL은 실행 상태로 두어 모든 기능을 갖춘(따라서 더 시끄러운) 스테이지가 탐지될 때 지속적인 액세스를 보장하는 1단계입니다.

지속성

WEASEL은 초기에 신뢰할 수 있는 발판/악용 벡터가 있는 가동 시간이 긴 서버를 대상으로 했습니다. 법의학 회피가 최우선 과제였습니다. 결과적으로 기본 지속성 기능이 없습니다.

선호하는 지속성 기술에 실행을 추가하여 지속성을 만들 수 있습니다. 이는 독자의 몫으로 남깁니다 :)

프로토콜 및 메시지 형식

클라이언트 요청

요청(클라이언트로부터) 은 다음과 같은 형식의 이름에 대한 단일 AAAA 쿼리입니다.

<preamble><data>.<stream>.<session>.domain.tld

프리앰블은 2바이트입니다. Preamble[0]은 해당 패킷의 시퀀스 번호입니다. Preamble[1]은 해당 스트림의 총 패킷 수입니다.

데이터는 50바이트(구성 가능)로 제한되며 페이로드를 포함합니다. 페이로드는 사용자 정의 알파벳으로 base32 인코딩됩니다.

페이로드 인코딩

먼저 모든 'w' 문자가 '-'로 대체됩니다.

다음으로 패딩 문자가 '='에서 'w'로 대체되어 DNS 문자 집합인 [a-z0-9] 및 [-]을 준수합니다.

패딩이 항상 문자열 끝에 있기 때문에 '='를 '-'로 직접 대체하지 않습니다. 호스트 이름이 '---'로 끝나는 것은 의심스럽고 DNS RFC에 위배됩니다. 이렇게 하면 문자열에 패딩이 있을 때 'www'로 끝나므로 덜 의심스럽고 RFC를 준수합니다.

서버 응답

응답(서버로부터) 은 하나 이상의 AAAA 응답으로 구성됩니다.

각 AAAA 응답은 socket.inet_ntop을 사용하여 IPv6 주소로 표현된 16바이트 암호화된 페이로드입니다. DNS 응답의 응답은 전송 중에 순서가 유지되지 않으므로 클라이언트 요청과 마찬가지로 순서가 지정되고 재조립됩니다.

전송 페이로드는 ^ 문자로 구분된 데이터 요소의 문자열입니다.

전송 형식

요청과 응답은 다음 형식을 따릅니다.

<type>|<data>

세션

세션은 오래 지속됩니다. 클라이언트는 비콘이 처음 실행될 때 세션을 시작하며, 해당 세션은 해당 클라이언트에서 비콘이 활성화된 전체 시간 동안 지속되어야 합니다. 비콘이 인메모리이며 지속적이지 않기 때문에 세션 데이터는 해당 Python 프로세스의 메모리에 저장됩니다. 비콘을 새로 호출할 때마다 새 세션이 시작됩니다.

세션을 시작하려면 클라이언트가 고유하게 식별되는 비데이터 프리앰블(이것이 새 세션임을 서버에 알리기 위해)을 사용하여 메시지를 작성합니다. 이 프리앰블은 32바이트 Diffie-Hellman 공개 키와 16바이트 임의 AES IV의 연결입니다.

서버는 이 메시지를 수신하고 자체 32바이트 공개 키로 응답합니다. 이 시점에서 클라이언트와 서버는 이 세션의 수명 동안 AES-128-CTR 모드를 사용하여 데이터 페이로드를 암호화하는 데 사용될 공유 세션 키를 설정했습니다. Diffie-Hellman 임시 교환은 각 클라이언트-서버 연결이 전방향 보안을 갖춘 고유한 세션 키를 사용하도록 보장합니다.

암호화의 취약점

여러 이유로 암호화는 의도적으로 취약합니다.

  • 우리는 일반적으로 강력한 암호화 시스템을 구축하는 방법을 거의 알지 못하고 자체 제작을 선호하는 실제 공격자를 모방하고 있습니다.
  • 비콘의 대역폭은 가능한 한 낮아야 하므로 DHE 교환을 매우 작게 유지해야 합니다.
  • 비귀속성이 중요하며 서버를 인증하지 않습니다.
  • 최첨단 암호화를 사용하면 대응자가 해독할 희망이 없어 재미가 없습니다.

암호화 체계의 알려진 문제는 다음과 같습니다.

  1. Diffie-Hellman 계수 p는 RFC 3526 그룹 5를 처음 32바이트로 자른 것입니다. 이는 공개 키와 개인 키를 32바이트로 제한할 뿐만 아니라 그룹 5는 이미 더 이상 사용되지 않으며 권장되지 않습니다. 이 잘못된 결정을 "그룹 1"이라고 부릅니다.
  2. 지수 a에 대해 CSPRNG 대신 random.randint()를 사용합니다.
  3. UUID 대신 os.urandom()의 소량 데이터를 세션 ID 및 스트림 ID 생성에 사용하므로 충돌이 발생할 가능성이 높습니다. 사용 중이 아닌 ID를 얻을 때까지 재시도하여 이를 처리합니다.
  4. AES-CTR 암호는 모든 스트림에 대해 동일한 IV(세션 키처럼 오래 지속됨)로 다시 초기화됩니다. 즉, 여러 스트림에 걸쳐 동일한 위치에 있는 동일한 평문이 동일한 암호문을 생성합니다.
  5. AES-CTR에서 IV는 올바르게 논스라고 불리지만 우리 구현에서는 숫자를 한 번 사용하지 않으므로 그렇게 부르는 것은 무례할 수 있습니다.

스트림

클라이언트와 서버 간에 전송되는 각 메시지는 일반적인 DNS 은닉 채널 탐지의 52바이트 제한 아래에 머물기 위해 최대 50바이트 패킷으로 패킷화되어야 합니다. 특정 메시지의 모든 패킷은 동일한 스트림의 일부입니다. 메시지 == 스트림입니다.

스트림은 2바이트 임의 16진수로 식별됩니다. 클라이언트 요청 형식을 기억하세요. <preamble><data>.<stream>.<session>.domain.tld

스트림의 각 패킷에 대한 2바이트 프리앰블에는 시퀀스 번호와 해당 스트림의 총 패킷 수가 있습니다. 이를 통해 서버는 모든 것이 도착했을 때 알 수 있습니다.

DNS를 통해 UDP로 이 모든 작업을 수행하기 때문에 데이터그램이 도착하는 순서에 대한 보장이 없습니다. 이것이 WEASEL이 많은 비콘의 여러 스트림을 추적하고 시퀀싱, 재조립 및 추적을 처리해야 하는 이유입니다.

각 스트림은 페이로드를 암호화/복호화하기 위해 전역적으로 공유되는 AES-128-CTR 암호를 다시 초기화합니다.

페이로드는 스트림이 완료된 경우에만(모든 패킷이 도착한 경우) 복호화될 수 있습니다. base32가 아니었다면 패킷이 누락된 경우에도 메시지의 일부를 복호화할 수 있지만(AES-CTR은 스트림 암호이기 때문에) base32로 부분 스트림을 디코딩할 수 없습니다. 어쩔 수 없습니다. DNS 클라이언트의 특성상 요청은 응답을 받을 때까지 여러 번(일반적으로 2~4회) 이루어지므로 각 패킷이 클라이언트에 의해 적어도 두 번 전송되어야 하므로 스트림의 모든 패킷을 수신할 확률이 높습니다. 패킷이나 스트림이 손실되더라도 큰 문제는 아닙니다. 비콘은 나중에 다시 체크인할 것이며 그때는 상황이 더 나을 것입니다.

WEASEL 커뮤니티에 참여하세요

기여 방법은 CONTRIBUTING 파일을 참조하세요.

라이선스

WEASEL은 MIT 라이선스이며, LICENSE 파일에서 확인할 수 있습니다.

도구 다운로드
Type의미 (송신자)AKA데이터
0확인됨ACK임의 16진수
1체크인 (클라이언트)PING임의 16진수
2자신을 종료 (서버), 자신을 종료 중 (클라이언트)FIN
3초기화 메시지 (클라이언트)SYN`version
4재연결 (서버)RST
5콜백 간격 설정 (서버)초
6네트워크 인터페이스 데이터 가져오기eth0 1.2.3.4/24\neth1 fe80:::/64\n...
8임의 Python3 코드 평가 (서버), 첫 400바이트 출력 반환 (클라이언트)EVALpython3 원라이너 스크립트
9임의 명령 실행 (서버), 첫 400바이트 출력 반환 (클라이언트)EXECbash 명령