source: client/engine/RegistryLib.py @ f160ff2

test-python-scriptsticket-693
Last change on this file since f160ff2 was 7260bdc2, checked in by Antonio Emmanuel Guerrero Silva <aguerrero@…>, 9 months ago

refs #585 Libraries convert to Python3

  • Property mode set to 100644
File size: 6.1 KB
Line 
1import subprocess
2import os
3import re
4
5from engine.FileLib import *
6from engine.SystemLib import *
7
8def chntpw(*args):
9    chntpw_path = subprocess.check_output(['which', 'drbl-chntpw']).decode().strip()
10    if not chntpw_path:
11        chntpw_path = subprocess.check_output(['which', 'chntpw']).decode().strip()
12    subprocess.run([chntpw_path, '-e'] + list(args), timeout=5)
13
14def ogAddRegistryKey(path_mountpoint, str_hive, str_key):
15    # Variables locales.
16    FILE = ogGetHivePath(path_mountpoint, str_hive)
17    if not FILE:
18        return
19
20    # Añadir nueva clave.
21    chntpw(FILE, 'cd', str_key.rsplit('\\', 1)[0])
22    chntpw(FILE, 'nk', str_key.rsplit('\\', 1)[-1])
23    chntpw(FILE, 'q')
24    chntpw(FILE, 'y')
25
26def ogAddRegistryValue(path_mountpoint, str_hive, str_key, str_valuename, str_valuetype=''):
27    # Variables locales.
28    FILE = ogGetHivePath(path_mountpoint, str_hive)
29    if not FILE:
30        return
31
32    # Determine the value type.
33    if str_valuetype.upper() == 'STRING' or str_valuetype == '':
34        TYPE = 1
35    elif str_valuetype.upper() == 'BINARY':
36        TYPE = 3
37    elif str_valuetype.upper() == 'DWORD':
38        TYPE = 4
39    else:
40        ogRaiseError(OG_ERR_OUTOFLIMIT, str_valuetype)
41        return
42
43    # Add the registry value.
44    chntpw(FILE, 'cd', str_key.rsplit('\\', 1)[0])
45    chntpw(FILE, 'nv', str_valuename.rsplit('\\', 1)[-1], TYPE)
46    chntpw(FILE, 'q')
47    chntpw(FILE, 'y')
48
49def ogDeleteRegistryKey(path_mountpoint, str_hive, str_key):
50    # Variables locales.
51    FILE = ogGetHivePath(path_mountpoint, str_hive)
52    if not FILE:
53        return
54
55    # Delete the registry key.
56    subprocess.run(['chntpw', FILE], input=f"cd {str_key.rsplit('\\', 1)[0]}\ndk {str_key.rsplit('\\', 1)[-1]}\nq\ny\n".encode(), timeout=5)
57
58def ogDeleteRegistryValue(path_mountpoint, str_hive, str_valuename):
59    # Variables locales.
60    FILE = ogGetHivePath(path_mountpoint, str_hive)
61    if not FILE:
62        return
63
64    # Delete the registry value.
65    chntpw(FILE, 'cd', str_valuename.rsplit('\\', 1)[0])
66    chntpw(FILE, 'dv', str_valuename.rsplit('\\', 1)[-1])
67    chntpw(FILE, 'q')
68    chntpw(FILE, 'y')
69
70def ogGetHivePath(path_mountpoint, str_hive):
71    # Variables locales.
72    FILE = None
73
74    # Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
75    FILE = ogGetPath(f"/{path_mountpoint}/Windows/System32/config/{str_hive}")
76    if not FILE:
77        FILE = ogGetPath(f"/{path_mountpoint}/Users/{str_hive}/NTUSER.DAT")
78    if not FILE:
79        FILE = ogGetPath(f"/{path_mountpoint}/winnt/system32/config/{str_hive}")
80    if not FILE:
81        FILE = ogGetPath(f"/{path_mountpoint}/Documents and Settings/{str_hive}/NTUSER.DAT")
82    if FILE and os.path.isfile(FILE):
83        return FILE
84    else:
85        ogRaiseError(OG_ERR_NOTFOUND, f"{path_mountpoint} {str_hive}")
86        return None
87   
88def ogGetRegistryValue(path_mountpoint, str_hive, str_valuename):
89    # Variables locales.
90    FILE = ogGetHivePath(path_mountpoint, str_hive)
91    if not FILE:
92        return
93
94    # Devolver el dato del valor de registro.
95    chntpw_cmd = f'''
96        chntpw "{FILE}" << EOT 2> /dev/null | awk '/> Value/ {{
97            if (index($0, "REG_BINARY") > 0) {{
98                data=""
99            }} else {{
100                getline
101                data=$0
102            }}
103        }}
104        /^:[0-9A-F]+ / {{
105            data=data""substr($0, 9, 48)
106        }}
107        END {{
108            print data
109        }}'
110        cd {str_valuename.rsplit('\\', 1)[0]}
111        cat {str_valuename.rsplit('\\', 1)[-1]}
112        q
113        EOT
114    '''
115    subprocess.run(chntpw_cmd, shell=True, timeout=5)
116   
117def ogListRegistryKeys(path_mountpoint, str_hive, str_key):
118    # Variables locales.
119    FILE = ogGetHivePath(path_mountpoint, str_hive)
120    if not FILE:
121        return
122
123    # Devolver la lista de claves de registro.
124    chntpw_cmd = f'''
125        chntpw "{FILE}" << EOT 2> /dev/null | awk 'BEGIN {{FS="[<>]"}} $1~/^  $/ {{print $2}}'
126        ls {str_key}
127        q
128        EOT
129    '''
130    subprocess.run(chntpw_cmd, shell=True, timeout=5)
131
132def ogListRegistryValues(path_mountpoint, str_hive, str_key):
133    # Variables locales.
134    FILE = ogGetHivePath(path_mountpoint, str_hive)
135    if not FILE:
136        return
137
138    # Devolver la lista de valores de registro.
139    chntpw_cmd = f'''
140        chntpw "{FILE}" << EOT 2> /dev/null | awk 'BEGIN {{FS="[<>]"}} $1~/REG_/ {{print $2}}'
141        ls {str_key}
142        q
143        EOT
144    '''
145    subprocess.run(chntpw_cmd, shell=True, timeout=5)
146
147def ogSetRegistryValue(path_mountpoint, str_hive, str_valuename, str_data):
148    # Variables locales.
149    FILE = ogGetHivePath(path_mountpoint, str_hive)
150    if not FILE:
151        return
152
153    # Fichero temporal para componer la entrada al comando "chntpw".
154    tmpfile = "/tmp/chntpw$$"
155    try:
156        # Comprobar tipo de datos del valor del registro.
157        with open(tmpfile, 'w') as f:
158            f.write(f"ls {str_valuename.rsplit('\\', 1)[0]}\nq\n")
159        output = subprocess.check_output(['chntpw', FILE], input=open(tmpfile, 'rb'), stderr=subprocess.DEVNULL).decode()
160        if f"BINARY.*<{str_valuename.rsplit('\\', 1)[-1]}>" in output:
161            # Procesar tipo binario (incluir nº de bytes y líneas de 16 parejas hexadecimales).
162            if not re.match(r'^([0-9A-F]{2} )*$', str_data):
163                ogRaiseError(OG_ERR_FORMAT, f'"{str_data}"')
164                return
165            n = len(str_data) + 1
166            with open(tmpfile, 'w') as f:
167                f.write(f"cd {str_valuename.rsplit('\\', 1)[0]}\ned {str_valuename.rsplit('\\', 1)[-1]}\n{int(n/3)}\n")
168                for i in range(0, n, 48):
169                    f.write(f":{i//3:05x}  {str_data[i:i+48]}\n")
170                f.write("s\nq\ny\n")
171        else:
172            # Cambiar el dato del valor de registro para cadenas y bytes.
173            with open(tmpfile, 'w') as f:
174                f.write(f"cd {str_valuename.rsplit('\\', 1)[0]}\ned {str_valuename.rsplit('\\', 1)[-1]}\n{str_data}\nq\ny\n")
175       
176        # Aplicar cambios.
177        subprocess.run(['chntpw', FILE], input=open(tmpfile, 'rb'), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
178    finally:
179        os.remove(tmpfile)
Note: See TracBrowser for help on using the repository browser.