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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
vbSparkle — 부분 평가를 지원하는 VBScript 및 VBA 소스 간 디난독화 도구 | Kitploit
도구/GitHubGitHub/airbus-cert/vbsparkle
Defensive ToolsStatic Code Analysis (SAST)Code AnalysisReverse EngineeringMalware Analysis
GitHubairbus-cert/vbsparkle

vbSparkle

부분 평가를 지원하는 VBScript 및 VBA 소스 간 디난독화 도구

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

.NET NuGet NuGet Download

vbSparkle이란 무엇인가?

vbSparkle는 부분 평가(partial-evaluation)에 기반한 소스-투-소스 멀티 플랫폼 Visual Basic 난독화 해제 도구(deobfuscator) 로, 주로 VBScript 및 VBA(Office 매크로)로 작성된 악성 코드 분석에 중점을 둡니다.

네이티브 **C#**으로 작성되었으며 .Net Standard 라이브러리를 제공하고 Windows, Linux, MacOS 등에서 동작합니다.

VBScript 및 VBA의 파싱은 ANTLR 문법(grammar) 및 렉서(lexer) 파서를 통해 처리됩니다.

설정

패키지 관리자

Install-Package vbSparkle

.Net CLI

dotnet add package vbSparkle

사용 방법

라이브러리로 사용

프로젝트에 vbSparkle 라이브러리를 추가한 후에는 정적 클래스 VbPartialEvaluator의 PrettifyEncoded 함수를 호출하기만 하면 됩니다:

root@kitploit:~
string obfuscatedVB = "msgbox(chr(65)&chr(66)&(chr(67))"
string deobfuscated = VbPartialEvaluator.PrettifyEncoded(obfuscatedVB);

...는 MsgBox("ABC")를 반환합니다.

CLI로 사용

첨부된 프로젝트 vbSparkle.CLI는 vbSparkle을 CLI로 사용하는 예시입니다. 현재 예시는 인자로 경로를 받거나 StdIn으로 전체 바이너리를 받아 난독화가 해제된 결과를 반환합니다. 레일로드 다이어그램

웹 UI

첨부된 프로젝트 vbSparkle.Web은 Web UI에서 vbSparkle을 사용하는 예시입니다. 레일로드 다이어그램

왜 부분 평가 기반 VBScript 난독화 해제 도구를 작성하는가?

VBScript 및 VBA 코드 난독화는 공격자들 사이에서 널리 사용되며, 탐지 조치, 안티바이러스, 방화벽, EDR을 우회할 수 있게 하고 악성코드 분석을 더 어렵게 만듭니다.

따라서 시스템 침해의 가장 첫 단계에서 난독화된 VBScript를 흔히 볼 수 있습니다.

전형적인 VBScript 코드 난독화 기법은 스크립트를 난독화된 문자열로 캡슐화한 뒤, 디코딩/평가된 후 Execute("...code..." function) 함수를 통해 실행하는 것입니다.

예를 하나 살펴보겠습니다:

root@kitploit:~
Execute(chr( 456127/3833 ) & chr( 817650/7110 ) & chr( 759429/7671 ) & chr( 834138/7317 ) & chr( 57960/552 ) & chr( 2549-2437 ) & chr( 1078568/9298 ) & chr( 5143-5097 ) & chr( -8682+8783 ) & chr( 529-430 ) & chr( 673088/6472 ) & chr( 761682/6862 ) & chr( 302336/9448 ) & chr( 9427-9393 ) & chr( 410176/3944 ) & chr( -5271+5372 ) & chr( 796608/7376 ) & chr( 2896-2788 ) & chr( 318792/2872 ) & chr( 1076-1042 ) &  vbcrlf  ) 

여기서 공격자는 다음을 사용했습니다:

  • 문자열 문자를 평가하는 chr(CHAR_CODE) 함수 (예: chr(65) = "A")
  • 문자 값을 평가하기 위한 산술 연산 (예: 456127/3833)
  • 디코딩된 모든 문자를 조합하기 위한 문자열 연결 &
  • 디코딩된 스크립트를 실행하기 위한 Execute(..) 함수 호출

스크립트 실행 과정을 따라가 보면:

  • 456127/3833 => 119
  • chr(119) => "w"
  • 817650/7110 => 115
  • chr(115) => "s"
  • "w" & "s" => "ws"
  • Execute("ws.....

다음은 원본 스크립트입니다: wscript.echo "hello"

대규모 스크립트의 경우 수동 난독화 해제는 매우 어렵고 시간이 많이 소요됩니다. VBScript에서 흔히 쓰이는 난독화 해제 기법 중 하나는 단순히 Execute() 함수를 WScript.Echo(로 교체한 다음 스크립트를 실행하여 출력을 얻는 것입니다.

이 마지막 기법은 간단하지만 몇 가지 단점이 있습니다:

  • 스크립트를 안전하게 실행하려면 최소한 하나의 VM / 샌드박스가 필요합니다;
  • 이 기법의 자동화는 위험하고 비결정적입니다;
  • 전체 코드와 그 부작용을 이해하는 것이 불가능합니다;
  • 실행 환경에 따라 일부 조건부 작업이 누락될 수 있습니다;

그리고 이 프로젝트가 시작되었을 당시에는 이 두 기법 외에 대안이 없었습니다.

Visual Basic 부분 평가기 작성

부분 평가는 새로운 개념이 아니며, 주로 컴파일러가 사전 컴파일(pre-compilation) 과정에서 코드 최적화를 위해 사용합니다 (예: https://en.wikipedia.org/wiki/Partial_evaluation).

부분 평가기(partial evaluator)는 프로그램(주제 프로그램(subject program)이라 함)과 해당 프로그램에 대한 일부 입력을 읽고, 제공된 입력에 의존하는 프로그램 부분만 평가합니다. 이러한 모든 부분이 평가되면 나머지 프로그램(잔여 프로그램(residual program)이라 함)이 출력으로 생성됩니다.

예를 들어, 사전 컴파일 과정은 다음 주제 코드를 변환합니다:

root@kitploit:~
var1 = 3*3 
var2 = sin(arg1)
var3 = var1 + func_xx(2 * var1 + var2)

다음과 같은 잔여 코드로 변환합니다:

root@kitploit:~
var2 = sin(arg1)
var3 = 9 + func_xx(18 + var2)

컴파일 전에 코드가 부분 평가되어 성능을 최적화합니다.

이 과정이 코드를 단순화하고 불필요한 연산을 제거한다는 것을 알 수 있습니다. 난독화는 코드 실행에 불필요한 코드와 연산을 추가하여 코드를 숨기므로 이 점이 흥미롭습니다.

초기 샘플을 단계별로 검사해 보면:

  • 산술 연산(예: 456127/3833)은 부분 평가할 수 있습니다: 부작용이 없습니다
  • chr(119)는 부분 평가할 수 있습니다: 119는 상수이고 네이티브 함수이므로 부작용이 없습니다
  • "w" & "s"는 부분 평가할 수 있습니다: 상수 문자 연결이므로 부작용이 없습니다
  • "Execute("는 알려진 부작용(스크립트 실행)이 있으므로, 함수의 부작용을 관리/에뮬레이션할 수 있는 경우가 아니면 평가되지 않습니다

해당 샘플을 부분 평가하면 다음과 같은 결과가 나옵니다: Execute("wscript.echo ""hello""" & vbCrLf)

그런데 그거 아세요? 방금 우리 샘플의 난독화를 해제했습니다.

이론은 좋지만, 실제로는?

음, 실제로는 훨씬 더 복잡합니다:

  • 부분 평가기를 구현하려면 파서가 필요합니다.
  • 파서를 얻으려면 렉서와 문법이 필요합니다.

다행히 ANTLR은 구조화된 텍스트나 바이너리 파일을 읽고, 처리하고, 실행하거나, 변환하기 위한 강력한 파서 생성기입니다. 언어, 도구, 프레임워크를 구축하는 데 널리 사용되는 것으로 알려져 있습니다. ANTLR은 문법으로부터 파스 트리를 구축할 수 있는 파서를 생성하고, 관심 있는 구문의 인식에 쉽게 대응할 수 있게 해주는 리스너 인터페이스(또는 비지터)도 생성합니다.

ANTLR은 렉서, 파서, 트리 파서, 그리고 결합된 렉서-파서를 생성할 수 있습니다. 파서는 트리 파서로 추가 처리할 수 있는 파스 트리 또는 추상 구문 트리를 자동으로 생성할 수 있습니다. ANTLR은 렉서, 파서, 트리 파서를 지정하기 위한 단일하고 일관된 표기법을 제공합니다.

기본적으로 ANTLR은 문법을 읽고 해당 문법으로 정의된 언어에 대한 인식기(recognizer)를 생성합니다 (즉, 입력 스트림을 읽고 입력 스트림이 문법에 지정된 구문을 따르지 않으면 오류를 생성하는 프로그램).

언어로 유용한 작업을 수행하기 위해 문법의 문법 요소에 액션을 첨부할 수 있습니다. 이러한 액션은 인식기가 생성되는 프로그래밍 언어로 작성됩니다. 인식기가 생성될 때 액션은 인식기 소스 코드의 적절한 지점에 삽입됩니다.

기본적인 작동 방식

ANTLR 덕분에 Ulrich Wolffgang이 작성한 기존 문법을 사용하여 AST, 렉서, 파서의 첫 번째 버전을 빠르고 쉽게 생성할 수 있었습니다.

VB 문법의 레일로드 다이어그램 샘플: 레일로드 다이어그램

이 문법은 일부 특정 Visual Basic 구문(인라인 코드, 일부 연산자 문제)과 완전히 호환되지 않았으며, 완전한 VBS 및 VBA 호환 문법을 제공하려면 몇 가지 변경이 필요했습니다. 수정된 문법은 여기에서 확인할 수 있습니다: Visual Basic Grammar

다음 코드 조각의 시각적 파스 트리 예시입니다:

root@kitploit:~
Msgbox("Hello world " & Chr(33), vbCritical, "The Title")

파스 트리 샘플

파서와 AST가 생성되면 이를 사용하여 코드를 탐색할 수 있습니다:

root@kitploit:~
using Antlr4.Runtime;
using System.Linq;

namespace vbSparkle
{
    public class PartialEvaluator
    {
        public static string Prettify(string script)
        {
            var inputStream = new AntlrInputStream(script);

            // Create the lexer
            var lexer = new VBScriptLexer(inputStream);

            // Instanciate of common token from lexer
            var commonTokenStream = new CommonTokenStream(lexer);

            // Create the parser
            var parser = new VBScriptParser(commonTokenStream);

            // Get the start rule (root element of our AST) 
            VBScriptParser.StartRuleContext stContext = parser.startRule();

            // Instanciate the visitor
            VbAnalyser analyser = new VbAnalyser();

            // Visit the AST
            analyser.Visit(stContext);

            // Root AST element of a vbScript being a "Module", we get it
            var module = analyser.Modules.FirstOrDefault();

            // Then we partially evaluate our module
            string result = module.Prettify(partialEvaluation: true);
            return result;
        }
    }
}

비지터는 AST를 순회하며 각 노드의 부분 평가기/프리티파이어를 생성하는 역할을 담당합니다. 이들은 재귀적으로 평가하는 역할을 담당합니다: 작업 흐름

예를 들어, 다음은 VbModule 평가기를 인스턴스화하는 우리의 비지터입니다:

root@kitploit:~
    public class VbAnalyser
    {
        public List<VbModule> Modules { get; set; } = new List<VbModule>();

        internal void Visit(VBScriptParser.StartRuleContext stContext)
        {
            var moduleContext = stContext.module();

            VbModule module = new VbModule(this, moduleContext);
            Modules.Add(module);
        }
    }

다음은 Prettify 함수가 있는 노드의 예시입니다:

root@kitploit:~
    public class VbOnGotoStatement : VbStatement<VBScriptParser.OnGoToStmtContext>
    {
        public VBValueStatement OnValue { get; set; }
        public VBValueStatement[] GotoValues { get; set; }

        public VbOnGotoStatement(IVBScopeObject context, VBScriptParser.OnGoToStmtContext bloc)
            : base(context, bloc)
        {
            OnValue = VBValueStatement.Get(context, bloc.valueStmt().First());
            GotoValues = bloc.valueStmt().Skip(1).Select(v => VBValueStatement.Get(context, v)).ToArray();
        }

        public override DExpression Prettify(bool partialEvaluation = false)
        {
            return new DCodeBlock($"On {OnValue.Prettify(partialEvaluation)} Goto {string.Join(", ", GotoValues.Select(v=> v.Prettify(partialEvaluation)))}");
        }
    }

생성자 VbOnGotoStatement(를 통해 노드를 방문하면 하위 노드를 재귀적으로 방문하여 각각의 비지터 인스턴스를 생성합니다. 그런 다음 Prettify 메서드가 호출되면 하위 요소도 동일한 부분 평가 수준으로 프리티파이 처리됩니다.

크레딧

  • 이 프로젝트는 Airbus CERT의 저작권 아래 있으며 Apache 2.0 라이선스로 배포됩니다.
도구 다운로드