Home

Awesome

VisualBasicObfuscator (obsoleted)

NOTICE: This repository is now obsoleted.

I'm working on releasing my second, way more reliable and advanced Visual Basic obfuscator that I have been using for a few years by now. This obfuscator therefore becomes outdated and will be no longer maintained.


Intro

Visual Basic Code universal Obfuscator intended to be used during penetration testing assignments. To be used mainly to avoid AV and mail filters detections as well as Blue Teams inspection tasks.

Here is a sample VirusTotal.com scan against malicious Word document with embedded RobustPentestMacro geared up with Empire-generated powershell stager:

No obfuscationObfuscated
15 / 589 / 58

There is still a huge area of improvement in testing which obfuscation techniques trigger what patterns, and work towards reducing such detection rate.


FEATURES

usage: obfuscate.py [-h] [-o OUTPUT] [-N | -g GARBAGE | -G | -C]
                    [-m MIN_VAR_LEN] [-r RESERVED] [-v | -q]
                    input_file

Attempts to obfuscate an input visual basic script in order to prevent curious
eyes from reading over it.

positional arguments:
  input_file            Visual Basic script to be obfuscated.

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file. Default: stdout
  -N, --normalize       Don't perform obfuscation, do only code normalization
                        (like long strings transformation).
  -g GARBAGE, --garbage GARBAGE
                        Percent of garbage to append to the obfuscated code.
                        Default: 12%.
  -G, --no-garbage      Don't append any garbage.
  -C, --no-colors       Dont use colors.
  -m MIN_VAR_LEN, --min-var-len MIN_VAR_LEN
                        Minimum length of variable to include in name
                        obfuscation. Too short value may break the original
                        script. Default: 5.
  -r RESERVED, --reserved RESERVED
                        Reserved word/name that should not be obfuscated (in
                        case some name has to be in original script cause it
                        may break it otherwise). Repeat the option for more
                        words.
  -v, --verbose         Verbose output.
  -q, --quiet           No unnecessary output.

Obfuscation example

Original form

Const MY_CONSTANTS = "Some super const"
Dim AnotherVariable As String

Sub MyTestSub(ByVal arg1 As String)
    ' The below real-world used query contains nested quotes/apostrophes
    ' That could confuse `removeComments` routine
    Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 " _
    & "WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' " _
    & "AND TargetInstance.SystemUpTime >= 200 AND " _
    & "TargetInstance.SystemUpTime < 320"

    Dim arr As Variant
    arr = Array(1, 2, 3, 4, 5, 6)   ' This is an inline comment

    Dim var1, var2
    var1 = "Testing Short string"
    var2 = "short"

    '
    ' This is a comment
    '
    Dim longString
    longString = "1. this is some very long string concatenated."
    longString = longString + "2. this is some very long string concatenated."
    longString = longString + "3. this is some very long string concatenated."
    longString = longString + "4. this is some very long string concatenated."

    longString = longString + "5. this is some very long string concatenated." _
    & "6. this is some very long string concatenated." _
    & "7. this is some very long string concatenated." _
    & "8. this is some very long string concatenated." _
    & "9. this is some very long string concatenated."

    Dim somecondition As Boolean
    somecondition = False
    If somecondition <> False Then
        Exit Sub
    End If

    MsgBox ("Test1(Constant): " & MY_CONSTANTS)
    MsgBox ("Test2(Query): " & Query)
    MsgBox ("Test3(var1 + var2): " & var1 & var2)
    MsgBox ("Test4(longString): " & longString)
    MsgBox ("Test5(Array's contents): " & Join(arr, ","))

End Sub

Sub test()
    MyTestSub (0)
End Sub

Obfuscated form:

Invocation - we have to specify that the macro is named test and therefore this Sub name shall not be mangled:

bash $ ./obfuscate.py -r test -v demo.vbs

Output (mind that Constants contents cannot be anyhow obfuscated, as they have to be known at compile time):

Const MY_CONSTANTS="Some super const"
Dim H5AyJRiT As String
Sub LdzqEiHkpovt(ByVal arg1 As String)
K8fqa=onOrpZJSZL("Aq0oV8IwZBFohAVdSO6+TJjg8124pPFV0K9zUbqn0FD4q9xWwLr1VWiukEpQooxWoBBRCQ==") _
& onOrpZJSZL("EuqkUgCucEii6dFXmODzXbik8VU4hYBYaI3RSep3F0yIoVRf2qdRXaC8cF2g4sBVMLVhXSrsnVOC9+9aoK/cFw==") _
& onOrpZJSZL("EKhhEYinVF5gsvxV4rD0V6ptPFGgvXNeoPMiXbCp8hGyU1YDoBQQQg==") _
& onOrpZJSZL("iKdUXmCy/FXisPRXqm08UaC9c16g8yJdsKnyEahC1go=")
Dim arr As Variant
arr=Array(3256/3256,293-291,-1964+1967,-2979+2983,1678-1673,342-336)
Dim var1,var2
var1=onOrpZJSZL(Chr(Int("&H69"))&Chr(&H4f)&Chr(Int("&H50"))&Chr(Int("&H51"))&"X"&Chr(55)&Chr(Int("&H69"))&Chr(Int("111"))&Chr(Int("56"))&Chr(Int("120"))&Chr(&H47)&Chr(&H61)&Chr(&H36)&Chr(-209+289)&Chr(Int("120"))&Chr(Int("&H53"))&Chr(113)&Chr(Int("&H4f"))&Chr(76)&"Q"&Chr(Int("84"))&Chr(114)&"q"&Chr(&H74)&Chr(88)&Chr(70)&Chr(-2196+2285)&Chr(Int("&H3d")))
var2=Chr(Int("115"))&Chr(Int("104"))&Chr(111)&"r"&Chr(1900-1784)
Dim oAQ96qYI As String
oAQ96qYI=Chr(&H4c)&Chr(56)&Chr(Int("&H79"))&Chr(112)&Chr(111)&Chr(76)&Chr(Int("48"))&Chr(Int("&H50"))&Chr(78645/749)&Chr(&H45)&Chr(&H49)&Chr(110)&Chr(Int("78"))&Chr(Int("97"))&Chr(2431-2328)&Chr(&H52)&Chr(-1842+1955)&Chr(3538-3458)&"7"&Chr(Int("104"))&Chr(121)
Dim ChtxGWGe As String
ChtxGWGe=Chr(1513-1429)&Chr(80)&Chr(Int("69"))&Chr(121)&Chr(Int("122"))&Chr(&H41)&Chr(Int("&H73"))&Chr(Int("&H31"))&Chr(Int("&H76"))&"l"&"k"&Chr(Int("&H33"))&Chr(Int("67"))&Chr(&H42)&Chr(51)&Chr(&H78)&Chr(&H37)&Chr(&H71)&Chr(878-766)&Chr(2660-2571)&Chr(Int("71"))&Chr(Int("&H58"))&Chr(77)&Chr(113)&Chr(78276/1186)
Dim E1X9VVBEe
E1X9VVBEe=onOrpZJSZL("sEBxR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=")
E1X9VVBEe=E1X9VVBEe+onOrpZJSZL("skBRR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=")
E1X9VVBEe=E1X9VVBEe+onOrpZJSZL("skBxR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=")
E1X9VVBEe=E1X9VVBEe+onOrpZJSZL("sEJRR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=")
E1X9VVBEe=E1X9VVBEe+onOrpZJSZL("sEJxR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=") _
& onOrpZJSZL("skJRR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=") _
& onOrpZJSZL("skJxR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=") _
& onOrpZJSZL("sEBTR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=") _
& onOrpZJSZL("sEBzR7ih0higdXdQsqvyEernUFv4iNxVquLwTLqtXFboid1Uoq1wXKKvUlw=")
Dim EKyef8cVxSrr As Boolean
Dim v9yzH As String
v9yzH="t"&Chr(Int("&H62"))&Chr(Int("57"))&"r"&Chr(&H57)&Chr(Int("&H61"))&Chr(Int("&H4c"))&"W"&Chr(Int("&H6b"))&Chr(109)&"x"&Chr(108)&Chr(Int("50"))&Chr(115)&Chr(&H6e)&"P"&Chr(&H36)&Chr(80)&Chr(86)&Chr(Int("108"))&Chr(Int("&H74"))
EKyef8cVxSrr=False
If EKyef8cVxSrr<>False Then
Exit Sub
End If
Dim P0HBOB As String
P0HBOB=Chr(-1358+1446)&Chr(-3235+3316)&Chr(27010/365)&"7"&Chr(Int("&H6c"))&Chr(75)&"R"&Chr(6462-6396)&Chr(Int("&H57"))&Chr(86)&Chr(Int("106"))&Chr(99)&Chr(49)&Chr(&H56)&Chr(52496/772)&Chr(&H64)&"s"&Chr(Int("&H66"))&Chr(8944-8832)&Chr(Int("&H63"))&Chr(Int("104"))&Chr(72)&Chr(&H43)&Chr(Int("107"))&Chr(Int("&H4b"))&Chr(-1162+1278)&Chr(3073-2984)&"e"
MsgBox ("Test1(Constant): " & MY_CONSTANTS)
MsgBox (onOrpZJSZL(Chr(105)&Chr(79)&Chr(75840/948)&Chr(Int("&H51"))&Chr(Int("&H58"))&"z"&Chr(-344+420)&"E"&Chr(Int("48"))&"E"&Chr(55)&"g"&Chr(2905-2789)&Chr(-294+412)&Chr(&H6b)&Chr(Int("89"))) & K8fqa)
MsgBox (onOrpZJSZL(Chr(&H69)&Chr(79)&Chr(80)&Chr(&H51)&Chr(895-807)&Chr(6451-6396)&Chr(&H71)&"M"&Chr(Int("&H63"))&Chr(&H45)&Chr(114)&Chr(-1738+1843)&Chr(&H4e)&Chr(Int("&H56"))&"Q"&Chr(&H43)&Chr(283938/2558)&Chr(Int("78"))&"D"&Chr(86)&Chr(85)&"b"&Chr(Int("&H6f"))&Chr(Int("66"))&"W"&"A"&Chr(111)&Chr(61)) & var1 & var2)
MsgBox (onOrpZJSZL(Chr(105)&"O"&Chr(Int("80"))&Chr(2870-2789)&Chr(&H58)&Chr(2709-2662)&Chr(Int("&H43"))&Chr(79)&Chr(Int("88"))&Chr(Int("69"))&Chr(196601/2209)&Chr(Int("&H71"))&Chr(&H34)&Chr(Int("&H39"))&"N"&Chr(3900/39)&Chr(Int("&H75"))&Chr(113)&Chr(-1542+1591)&"c"&Chr(Int("86"))&Chr(189417/1839)&Chr(&H3d)&"=") & E1X9VVBEe)

' Cut for brevity. One can see the rest of this output in 'demo-obfuscated.vbs'
' [...]

TODO:


KNOWN BUGS:


☕ Show Support ☕

This and other projects are outcome of sleepless nights and plenty of hard work. If you like what I do and appreciate that I always give back to the community, Consider buying me a coffee (or better a beer) just to say thank you! 💪


Author

   Mariusz Banach / mgeeky, 21
   <mb [at] binary-offensive.com>
   (https://github.com/mgeeky)