mirror of https://github.com/secdev/scapy.git
Fix VBS fallback
This commit is contained in:
parent
afec3130e3
commit
40ad5b67b1
|
@ -58,7 +58,7 @@ def _exec_query_ps(cmd, fields):
|
|||
yield l
|
||||
l=[]
|
||||
|
||||
def _vbs_exec_code(code):
|
||||
def _vbs_exec_code(code, split_tag="@"):
|
||||
if not WINDOWS:
|
||||
return
|
||||
tmpfile = tempfile.NamedTemporaryFile(suffix=".vbs", delete=False)
|
||||
|
@ -71,7 +71,9 @@ def _vbs_exec_code(code):
|
|||
# skip 3 first lines
|
||||
ps.stdout.readline()
|
||||
for line in ps.stdout:
|
||||
yield line
|
||||
data = line.replace("\n", "").split(split_tag)
|
||||
for l in data:
|
||||
yield l
|
||||
os.unlink(tmpfile.name)
|
||||
|
||||
def _vbs_get_iface_guid(devid):
|
||||
|
@ -92,7 +94,12 @@ _VBS_WMI_FIELDS = {
|
|||
"Win32_NetworkAdapter": {
|
||||
"InterfaceIndex": "Index",
|
||||
"InterfaceDescription": "Description",
|
||||
"GUID": "DeviceID",
|
||||
}
|
||||
}
|
||||
|
||||
_VBS_WMI_REPLACE = {
|
||||
"Win32_NetworkAdapterConfiguration": {
|
||||
"line.IPAddress": "\"{\" & Join( line.IPAddress, \", \" ) & \"}\"",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,16 +110,20 @@ _VBS_WMI_OUTPUT = {
|
|||
}
|
||||
|
||||
def _exec_query_vbs(cmd, fields):
|
||||
if not WINDOWS:
|
||||
return
|
||||
"""Execute a query using VBS. Currently Get-WmiObject queries are
|
||||
supported.
|
||||
|
||||
"""
|
||||
if not WINDOWS:
|
||||
return
|
||||
assert len(cmd) == 2 and cmd[0] == "Get-WmiObject"
|
||||
if not(len(cmd) == 2 and cmd[0] == "Get-WmiObject"):
|
||||
return
|
||||
|
||||
fields = [_VBS_WMI_FIELDS.get(cmd[1], {}).get(fld, fld) for fld in fields]
|
||||
parsed_command = "WScript.Echo " + " & \" @ \" & ".join("line.%s" % fld for fld in fields
|
||||
if fld is not None)
|
||||
# The IPAddress is an array: convert it to a string
|
||||
for key,val in _VBS_WMI_REPLACE.get(cmd[1], {}).items():
|
||||
parsed_command = parsed_command.replace(key, val)
|
||||
values = _vbs_exec_code("""Set wmi = GetObject("winmgmts:")
|
||||
Set lines = wmi.InstancesOf("%s")
|
||||
On Error Resume Next
|
||||
|
@ -120,8 +131,8 @@ Err.clear
|
|||
For Each line in lines
|
||||
%s
|
||||
Next
|
||||
""" % (cmd[1], "\n ".join("WScript.Echo line.%s" % fld for fld in fields
|
||||
if fld is not None))).__iter__()
|
||||
""" % (cmd[1], parsed_command), "@")
|
||||
|
||||
while True:
|
||||
yield [None if fld is None else
|
||||
_VBS_WMI_OUTPUT.get(cmd[1], {}).get(fld, lambda x: x)(
|
||||
|
@ -132,7 +143,6 @@ Next
|
|||
def exec_query(cmd, fields):
|
||||
"""Execute a system query using PowerShell if it is available, and
|
||||
using VBS/cscript as a fallback.
|
||||
|
||||
"""
|
||||
if conf.prog.powershell is None:
|
||||
return _exec_query_vbs(cmd, fields)
|
||||
|
@ -171,8 +181,10 @@ def win_find_exe(filename, installsubdir=None, env="ProgramFiles"):
|
|||
return path
|
||||
|
||||
|
||||
def is_new_release():
|
||||
def is_new_release(ignoreVBS=False):
|
||||
release = platform.release()
|
||||
if conf.prog.powershell is None and not ignoreVBS:
|
||||
return False
|
||||
try:
|
||||
if float(release) >= 8:
|
||||
return True
|
||||
|
@ -211,6 +223,9 @@ import platform
|
|||
|
||||
def is_interface_valid(iface):
|
||||
if "guid" in iface and iface["guid"]:
|
||||
# Fix '-' instead of ':'
|
||||
if "mac" in iface:
|
||||
iface["mac"] = iface["mac"].replace("-", ":")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -225,6 +240,7 @@ def get_windows_if_list():
|
|||
query = exec_query(['Get-NetAdapter'],
|
||||
['InterfaceDescription', 'InterfaceIndex', 'Name',
|
||||
'InterfaceGuid', 'MacAddress']) # It is normal that it is in this order
|
||||
|
||||
else:
|
||||
query = exec_query(['Get-WmiObject', 'Win32_NetworkAdapter'],
|
||||
['Name', 'InterfaceIndex', 'InterfaceDescription',
|
||||
|
@ -388,7 +404,7 @@ pcapdnet.open_pcap = lambda iface,*args,**kargs: _orig_open_pcap(pcapname(iface)
|
|||
|
||||
_orig_get_if_raw_hwaddr = pcapdnet.get_if_raw_hwaddr
|
||||
pcapdnet.get_if_raw_hwaddr = lambda iface, *args, **kargs: (
|
||||
ARPHDR_ETHER, mac2str(IFACES.dev_from_pcapname(pcapname(iface)).mac.replace('-', ':'))
|
||||
ARPHDR_ETHER, mac2str(IFACES.dev_from_pcapname(pcapname(iface)).mac)
|
||||
)
|
||||
get_if_raw_hwaddr = pcapdnet.get_if_raw_hwaddr
|
||||
|
||||
|
|
|
@ -147,3 +147,62 @@ emulate_main_input(data)
|
|||
from ctypes import wintypes
|
||||
data = ["#AUTOCOMPLETE{scapy.config.conf.vers}", "assert _ == scapy.config.conf.version"]
|
||||
emulate_main_input(data)
|
||||
|
||||
############
|
||||
############
|
||||
+ Windows arch unit tests
|
||||
|
||||
= Test PowerShell availability
|
||||
from scapy.config import conf
|
||||
assert conf.prog.powershell != None
|
||||
|
||||
= Test all VBS fallback
|
||||
import mock
|
||||
from scapy.config import conf
|
||||
|
||||
ps_ip = get_ip_from_name(conf.iface.name)
|
||||
ps_if_list = get_windows_if_list()
|
||||
ps_read_routes = read_routes()
|
||||
|
||||
# Turn on VBS mode
|
||||
conf.prog.powershell = None
|
||||
|
||||
# Test get_ip_from_name
|
||||
assert get_ip_from_name(conf.iface.name) == ps_ip
|
||||
|
||||
# Test get_windows_if_list
|
||||
|
||||
def is_in_if_list(i, list):
|
||||
for j in list:
|
||||
if j["guid"] == i["guid"] and j["name"] == i["name"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
vbs_if_list = get_windows_if_list()
|
||||
_correct = True
|
||||
for i in ps_if_list:
|
||||
if not is_in_if_list(i, vbs_if_list):
|
||||
_correct = False
|
||||
break
|
||||
|
||||
assert _correct
|
||||
|
||||
# Test read_routes
|
||||
|
||||
def is_in_route_list(i, list):
|
||||
for j in list:
|
||||
#Ignore all empty IP
|
||||
if j[4] == '' or i[4] == '':
|
||||
return True
|
||||
if j[2] == i[2] and j[4] == i[4] and j[3].guid == i[3].guid:
|
||||
return True
|
||||
return False
|
||||
|
||||
vbs_read_routes = read_routes()
|
||||
_correct = True
|
||||
for i in ps_read_routes:
|
||||
if not is_in_route_list(i, vbs_read_routes):
|
||||
_correct = False
|
||||
break
|
||||
|
||||
assert _correct
|
||||
|
|
Loading…
Reference in New Issue