tenable / pyTenable

Python Library for interfacing into Tenable's platform APIs
https://pytenable.readthedocs.io
MIT License
355 stars 175 forks source link

Problem importing a policy #205

Closed rs904c closed 4 years ago

rs904c commented 4 years ago

I have a Scan Policy XML file that uploads just fine in the SC GUI, but using the pyTenable SC.policies.import_policy function, it gives an error. I did further testing by exporting the policy file via the SC GUI, and tried using the pyTenable SC.policies.import_policy function. Again it failed.

Details: SCAsSM.policies.import_policy("OS Discovery Scan Policy", PrivateSCUploadedFileHandle)

DEBUG:tenable.sc.TenableSC:{"method": "POST", "url": "https://192.168.214.5:443/rest/file/upload", "params": {}, "body": {}} DEBUG:urllib3.connectionpool:https://192.168.214.5:443 "POST /rest/file/upload HTTP/1.1" 200 199 DEBUG:tenable.sc.TenableSC:{"method": "POST", "url": "https://192.168.214.5:443/rest/file/upload", "params": {}, "body": {}} DEBUG:urllib3.connectionpool:https://192.168.214.5:443 "POST /rest/file/upload HTTP/1.1" 200 175 DEBUG:tenable.sc.TenableSC:{"method": "POST", "url": "https://192.168.214.5:443/rest/policy/import", "params": {}, "body": {"name": "OS Discovery Scan Policy", "filename": "I35qOu"}} DEBUG:urllib3.connectionpool:https://192.168.214.5:443 "POST /rest/policy/import HTTP/1.1" 403 269 ERROR:tenable.errors.APIError:POST https://192.168.214.5:443/rest/policy/import >> None:403 {"type":"regular","response":"","error_code":146,"error_msg":"Policy Import failed.\nFatal Error 4: Start tag expected, '<' not found Line: 1, Column: 1\nUploaded Nessus Policy contains malformed XML. There were 1 XML error(s).\n","warnings":[],"timestamp":1589201769}

I did try to open the file with and without binary mode, neither worked, after passing the file handle. So, I can't tell if this is a problem with pyTenable, the API, or something I'm doing.

SteveMcGrath commented 4 years ago

If it helps, here is the test thats run for every push to master:

https://github.com/tenable/pyTenable/blob/master/tests/sc/test_policies.py#L403-L404

And here is the policy file:

https://github.com/tenable/pyTenable/blob/master/tests/test_files/sc_policy.xml

rs904c commented 4 years ago

Cool, let me test with that and get back to you.

rs904c commented 4 years ago

Thank you

rs904c commented 4 years ago

I got the same error with your policy too. Now, I'm wondering if this issue is with SC 5.14.1. I'm going to try with an earlier version of SC.

SteveMcGrath commented 4 years ago

are you creating the file object in binary mode or string mode?

rs904c commented 4 years ago

I'm creating the file in binary mode.

rs904c commented 4 years ago

I just tried this with SC 5.12, and got the same error.

SteveMcGrath commented 4 years ago

Just tested:

>>> from tenable.sc import TenableSC
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> with TenableSC('tenablesc.home.cugnet.net', username='XXX', password='XXX') as sc:
...     with open('sc_policy.xml', 'rb') as policy:
...         sc.policies.import_policy('Example Policy Import', policy)
...
DEBUG:tenable.sc.TenableSC:{"method": "GET", "url": "https://tenablesc.home.cugnet.net:443/rest/system", "params": {}, "body": {}}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): tenablesc.home.cugnet.net:443
DEBUG:urllib3.connectionpool:https://tenablesc.home.cugnet.net:443 "GET /rest/system HTTP/1.1" 200 None
DEBUG:tenable.sc.TenableSC:{"method": "POST", "url": "https://tenablesc.home.cugnet.net:443/rest/token", "params": "REDACTED", "body": "REDACTED"}
DEBUG:urllib3.connectionpool:https://tenablesc.home.cugnet.net:443 "POST /rest/token HTTP/1.1" 200 286
DEBUG:tenable.sc.TenableSC:{"method": "POST", "url": "https://tenablesc.home.cugnet.net:443/rest/file/upload", "params": {}, "body": {}}
DEBUG:urllib3.connectionpool:https://tenablesc.home.cugnet.net:443 "POST /rest/file/upload HTTP/1.1" 200 180
DEBUG:tenable.sc.TenableSC:{"method": "POST", "url": "https://tenablesc.home.cugnet.net:443/rest/policy/import", "params": {}, "body": {"name": "Example Policy Import", "file
name": "czA5cS"}}
DEBUG:urllib3.connectionpool:https://tenablesc.home.cugnet.net:443 "POST /rest/policy/import HTTP/1.1" 200 None
{'id': '1000004', 'name': 'Example Policy Import', 'description': 'Nessus Policy exported from SecurityCenter', 'tags': '', 'createdTime': '1589215994', 'modifiedTime': '1589
215994', 'generateXCCDFResults': 'false', 'context': '', 'auditFiles': [], 'preferences': {'abort_generic_webapp_if_login_fails': 'no', 'arp_ping': 'yes', 'av_grace_period':
'0', 'cert_expiry_warning_days': '60', 'check_crl': 'no', 'combo_arg_values': 'one value', 'description': 'Nessus Policy exported from SecurityCenter', 'disable_dns_resolutio
n': 'no', 'display_unreachable_hosts': 'no', 'enable_file_scanning': 'no', 'enable_filescan_programdata': 'no', 'enable_filescan_programfiles': 'no', 'enable_filescan_program
filesx86': 'no', 'enable_filescan_systemroot': 'no', 'enable_filescan_userprofiles': 'no', 'enum_domain_users_end_uid': '1200', 'enum_domain_users_start_uid': '1000', 'enum_l
ocal_users_end_uid': '1200', 'enum_local_users_start_uid': '1000', 'enumerate_all_ciphers': 'yes', 'fast_network_discovery': 'yes', 'filescan_custom_dir': '', 'generateXCCDFR
esults': 'no', 'generic_webapp_tests': 'no', 'generic_webapp_tests_max_time': '5', 'host_whitelist': '', 'http_param_pollution': 'no', 'hydra_add_other_accounts': 'yes', 'hyd
ra_always_enable': 'no', 'hydra_cisco_logon_pw': '', 'hydra_client_id': '', 'hydra_empty_passwords': 'yes', 'hydra_exit_on_success': 'no', 'hydra_ldap_dn': '', 'hydra_login_a
s_pw': 'yes', 'hydra_logins_file': '', 'hydra_parallel_tasks': '16', 'hydra_passwords_file': '', 'hydra_postgresql_db_name': '', 'hydra_proxy_test_site': '', 'hydra_timeout':
 '30', 'hydra_web_page': '', 'hydra_win_account_type': 'Local accounts', 'hydra_win_pw_as_hash': 'no', 'icmp_ping': 'yes', 'icmp_ping_retries': '2', 'icmp_unreach_means_host_
down': 'no', 'local_portscan.netstat_ssh': 'yes', 'local_portscan.netstat_wmi': 'yes', 'log_live_hosts': 'no', 'log_whole_attack': 'no', 'max_checks_per_host': '5', 'max_host
s_per_scan': '30', 'max_simult_tcp_sessions_per_host': '', 'max_simult_tcp_sessions_per_scan': 'unlimited', 'modbus_end_reg': '16', 'modbus_start_reg': '0', 'name': 'Example
Policy Import', 'network_receive_timeout': '5', 'network_type': 'Mixed (use RFC 1918)', 'only_portscan_if_enum_failed': 'yes', 'ping_the_remote_host': 'yes', 'portscan_range'
: '1-5,7,9,11,13,15,17-25,27,29,31,33,35,37-39,41-59,61-224,242-248,256-268,280-287,308-322,333,344-700,702,704-707,709-711,721,723,729-731,737,740-742,744,747-754,758-765,76
7,769-777,779-783,786,787,799-801,808,810,828,829,847,848,860,871,873,886-888,898,900-904,911-913,927,950,953,975,989-1002,1005,1008,1010,1012,1023-1036,1040,1042,1045,1047-1
112,1114-1117,1119,1120,1122-1127,1139,1154,1155,1161,1162,1167-1170,1178,1180,1181,1183-1188,1192,1194,1199-1231,1233-1286,1288-1774,1776-2028,2030,2032-2035,2037,2038,2040-
2065,2067-2083,2086,2087,2089-2152,2155,2159-2167,2170-2177,2180,2181,2190,2191,2199-2202,2207,2213,2220-2224,2232-2246,2248-2255,2260,2273,2279-2289,2294-2311,2313-2371,2381
-2824,2826-2854,2856-3096,3098-3403,3405-3545,3547-3707,3709-3765,3767-3800,3802,3845-3871,3875,3876,3885,3900,3928,3929,3939,3959,3970,3971,3984-3987,3994,3996-4036,4040-404
2,4045,4080,4081,4092,4096-4100,4105,4111,4114,4132-4134,4138,4141-4145,4154,4160,4199-4201,4242,4274,4300,4321,4333,4343-4351,4353-4358,4369,4400,4442-4457,4480,4500,4501,45
45-4547,4555,4557,4559,4567-4569,4600,4601,4658-4662,4665,4672,4711,4747,4752,4800-4802,4827,4837-4839,4848,4849,4868,4869,4885,4888,4894,4899,4950,4983,4987-4989,4998,5000-5
011,5020-5025,5031,5042,5050-5057,5060,5061,5064-5066,5069,5071,5081,5093,5099-5102,5108,5137,5145,5150-5152,5154,5165,5168,5177,5178,5190-5193,5200-5203,5222,5223,5225,5226,
5232,5236,5250,5251,5264,5265,5269,5272,5282,5300-5311,5314,5315,5321,5347,5351-5355,5400-5432,5435,5444,5454-5456,5461-5463,5465,5485,5500-5504,5510,5520,5521,5530,5540,5550
,5553-5556,5566,5569,5595-5605,5631,5632,5666,5673-5680,5688,5690,5713-5717,5720,5727,5729,5730,5741,5742,5745,5746,5755,5757,5766-5768,5771,5800-5803,5813,5858,5859,5881,588
2,5888,5889,5900-5903,5968,5969,5977-5979,5987-5991,5997-6073,6080,6085,6100-6112,6123,6129,6141-6150,6175-6177,6200,6253,6255,6257,6270,6284,6300,6321,6322,6343,6346,6347,63
73,6382,6389,6400-6402,6404-6406,6443,6455,6456,6471,6500-6503,6505-6510,6543,6547-6550,6558,6566,6580-6582,6588,6620,6621,6623,6628,6631,6660,6665-6670,6672,6673,6680,6688,6
699-6701,6714,6723,6767,6768,6776-6778,6788-6790,6831,6841,6842,6850,6881-6889,6891,6900,6901,6939,6961-6966,6969,6970,6998-7015,7020,7021,7030,7070,7080,7099-7101,7111,7121,
7144,7161,7170,7174,7200,7201,7205,7210,7211,7269,7273,7280,7281,7283,7300-7308,7320,7323,7326,7391,7392,7395,7426-7431,7437,7461,7464,7491,7500,7501,7505,7510,7511,7544,7545
,7560,7566,7570,7575,7580,7585,7588,7597,7624,7626,7627,7633,7634,7648-7651,7666,7674-7676,7743,7775-7779,7781,7786,7789,7797,7798,7800,7801,7845,7846,7875,7902,7913,7932,793
3,7938,7955,7967,7979,7980,7999-8005,8007-8010,8019,8022,8028,8030,8032,8033,8044,8060,8074,8077,8080-8083,8088-8090,8098,8100,8115,8116,8118,8121-8123,8129-8132,8160,8161,81
80-8194,8199-8201,8204-8208,8216,8224,8225,8245,8300,8302,8310,8311,8351,8376-8380,8383,8390,8400-8403,8416,8417,8431,8443-8445,8450,8473,8484,8500,8530,8554,8555,8649,8733,8
763-8765,8786,8787,8804,8834,8863,8864,8866,8875,8880,8887-8894,8900,8901,8910,8911,8954,8987,8989,8999-9002,9006,9009,9020-9026,9043,9050,9080,9090,9091,9099-9103,9110,9111,
9131,9152,9160-9164,9200-9207,9210,9211,9216,9217,9281-9285,9287,9292,9321,9343,9344,9346,9359,9370,9374,9390-9393,9396,9397,9400,9418,9433,9443,9495,9500,9535-9537,9593-9595
,9600,9612,9704,9747,9753,9797,9800-9802,9872,9875,9876,9888,9889,9898-9901,9909,9911,9943,9945,9950-9952,9990-10012,10051,10067,10080-10083,10101-10103,10113-10116,10128,101
67,10168,10202-10204,10252,10260,10288,10607,10616,10617,10626,10628,10666,10752,10990,11000,11001,11111,11201,11211,11223,11319-11321,11367,11371,11600,11720,11751,11965,119
67,11999-12006,12076,12109,12168,12172,12174,12223,12321,12345,12346,12361,12362,12468,12701,12753,12754,13160,13223,13224,13324,13325,13666,13701,13702,13705,13706,13708-137
18,13720-13722,13724,13782,13783,13818-13822,14001,14002,14033,14034,14141,14145,14149,14194,14237,14238,14936,14937,14942,15000,15104,15126,15345,15363,15858,16360,16361,163
67,16368,16384,16660,16661,16959,16969,16991,17007,17185,17219,17300,17770-17772,17990,18000,18181-18187,18190,18241,18264,18463,18769,18888,18889,19191,19194,19226,19283,193
15,19398,19410-19412,19540,19541,19638,19726,20000,20001,20005,20011,20012,20020,20031,20034,20168,20200,20202,20203,20221,20222,20670,20999,21000,21064,21065,21071,21227,213
00,21317,21490,21544,21554,21590,21700,21800,21845-21849,22000-22003,22222,22273,22289,22305,22321,22370,22555,22800,22951,23456,23945,24000-24006,24242,24249,24345-24347,243
86,24554,24677,24678,24922,25000-25009,25378,25445,25544,25793,25867,25901,25903,26000,26208,26260-26264,26274,26740,26900,27000-27010,27015-27050,27345,27374,27444,27500,275
04,27665,27901,27910,27960,27961,27999,28001,28017,28070,28431,28910,29559,29760,29891,30001,30002,30100-30102,30303,30999,31333,31335,31337-31339,31416,31457,31554,31556,316
20,31666,31765,31785-31787,31789-31791,32000,32123,32261,32666,32768-32780,32786,32787,32896,33270,33331,33434,33567,33568,33911,34012,34249,34324,34567,34952,36079,36794,368
65,37475,37651,38037,38201,38292,38293,39213,39681,40001,40412,40421-40426,40841-40843,41002,41080,41111,41170,41443,41508,41794,41795,42508-42510,42800,43118,43188-43190,443
21,44322,44333,44334,44337,44442,44443,44818,45000,45054,45678,45966,47000,47262,47557,47624,47806,47808,47891,48000-48003,48556,49400,50000-50004,50013,50123,50505,50776,510
51,51210,53001,54320,54321,54345,56768,57341,59595,60008,60177,60179,61439-61441,61446,62078,65000,65301,65534', 'provided_creds_only': 'yes', 'reduce_connections_on_congesti
on': 'no', 'report_paranoia': 'Normal', 'report_superseded_patches': 'yes', 'report_verbosity': 'Normal', 'request_windows_domain_info': 'yes', 'reverse_lookup': 'no', 'safe_
checks': 'yes', 'scan_malware': 'no', 'scan_netware_hosts': 'no', 'scan_network_printers': 'no', 'scan_ot_devices': 'no', 'scan_unresponsive_hosts': 'no', 'scan_webapps': 'no
', 'silent_dependencies': 'yes', 'smtp_domain': 'example.com', 'smtp_from': 'nobody@example.com', 'smtp_to': 'postmaster@[AUTO_REPLACED_IP]', 'snmp_scanner': 'yes', 'ssh_nets
tat_scanner': 'yes', 'ssl_prob_ports': 'Known SSL ports', 'start_cotp_tsap': '8', 'stop_at_first_flaw': 'per CGI', 'stop_cotp_tsap': '8', 'stop_scan_on_disconnect': 'no', 'sv
c_detection_on_all_ports': 'yes', 'syn_firewall_detection': 'Automatic (normal)', 'syn_scanner': 'yes', 'tcp_firewall_detection': 'Automatic (normal)', 'tcp_ping': 'yes', 'tc
p_ping_dest_ports': 'built-in', 'tcp_scanner': 'no', 'test_default_oracle_accounts': 'no', 'test_embedded_web_servers': 'no', 'test_local_nessus_host': 'yes', 'thorough_tests
': 'no', 'try_all_http_methods': 'no', 'udp_ping': 'no', 'udp_scanner': 'no', 'unscanned_closed': 'no', 'url_for_rfi': 'http://rfi.nessus.org/rfi.txt', 'use_kernel_congestion
_detection': 'no', 'user_agent_string': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', 'verify_open_ports': 'no', 'webcrawl_exclude_regex': '/server_privi
leges\\.php|logout', 'webcrawl_follow_dynamic_pages': 'no', 'webcrawl_max_depth': '6', 'webcrawler_max_pages': '1000', 'webcrawler_start_page': '/', 'win_known_bad_hashes': '
', 'win_known_good_hashes': '', 'wmi_netstat_scanner': 'yes', 'wol_mac_addresses': '', 'wol_wait_time': '5', 'yarascan_rules_file': ''}, 'families': [{'id': '42', 'name': 'Po
rt scanners', 'count': '8', 'plugins': [{'id': '10180', 'name': 'Ping the remote host', 'description': 'Nessus was able to determine if the remote host is alive using one or
more of the following ping types :\n\n  - An ARP ping, provided the host is on the local subnet     and Nessus is running over Ethernet.\n\n  - An ICMP ping.\n\n  - A TCP pin
g, in which the plugin sends to the remote host     a packet with the flag SYN, and the host will reply with     a RST or a SYN/ACK.\n\n  - A UDP ping (e.g., DNS, RPC, and NT
P).'}, {'id': '11219', 'name': 'Nessus SYN scanner', 'description': "This plugin is a SYN 'half-open' port scanner.  It shall be reasonably quick even against a firewalled ta
rget. \n\nNote that SYN scans are less intrusive than TCP (full connect) scans against broken services, but they might cause problems for less robust firewalls and also leave
 unclosed connections on the remote target, if the network is loaded."}, {'id': '14272', 'name': 'Netstat Portscanner (SSH)', 'description': "Nessus was able to run 'netstat'
 on the remote host to enumerate the open ports.\n\nSee the section 'plugins options' about configuring this plugin.\n\nNote: This plugin will run on Windows (using netstat.e
xe) in the event that the target being scanned is localhost."}, {'id': '14274', 'name': 'Nessus SNMP Scanner', 'description': "This plugin runs an SNMP scan against the remot
e machine to find open ports.\n\nSee the section 'plugins options' to configure it."}, {'id': '34220', 'name': 'Netstat Portscanner (WMI)', 'description': "Using the WMI inte
rface, Nessus was able to run 'netstat' on the remote host to enumerate the open ports."}]}], 'status': '0', 'groups': [], 'canUse': 'true', 'canManage': 'true', 'creator': {
'id': '1', 'username': 'steve', 'firstname': 'Steve', 'lastname': 'McGrath'}, 'owner': {'id': '1', 'username': 'steve', 'firstname': 'Steve', 'lastname': 'McGrath'}, 'ownerGr
oup': {'id': '0', 'name': 'Full Access', 'description': 'Full Access group'}, 'targetGroup': {'id': -1, 'name': '', 'description': ''}, 'policyTemplate': {'id': '1', 'name':
'Advanced Scan', 'description': 'Configure a scan without using any recommendations.'}}
DEBUG:tenable.sc.TenableSC:{"method": "DELETE", "url": "https://tenablesc.home.cugnet.net:443/rest/token", "params": "REDACTED", "body": "REDACTED"}
DEBUG:urllib3.connectionpool:https://tenablesc.home.cugnet.net:443 "DELETE /rest/token HTTP/1.1" 200 100
rs904c commented 4 years ago

I figured out the problem, it was me. Most uploads, like for license files, and the plugins and feeds, you have to open the file, then pass that through the SC.files.upload function, like below: PrivateFileHandle=open(PrivateFullFilename,'rb') PrivateSCUploadedFileHandle=SCAsAdmin.files.upload(PrivateFileHandle)

The resulting variable PrivateSCUploadedFileHandle is passed to the sc functions (for licenses and plugin updates.)
But not this case. You have to pass the PrivateFileHandle to sc.policies.import_policy. Also, I noticed if you do the 2nd function of SC.files.upload, it messing things up and the import_policy will fail even when passing the PrivateFileHandle.

I would it expect it to handle files the same way each time and do the SC.files.upload every time.

Why the inconsistency?

SteveMcGrath commented 4 years ago

in what situations are you having to manually upload the file, then pass the handler? The reality should be the opposite. In cases where there is a method available, it should handle you passing the file object and it will transparently upload the file object and store the identifier that SC assigns it.

rs904c commented 4 years ago

I'm doing the following for posts involving license register, and feed processing. PrivateFileHandle=open(PrivateFullFilename,'rb') PrivateSCUploadedFileHandle=SCAsAdmin.files.upload(PrivateFileHandle) .post("config/license/register" .post("feed/sc/process"

SteveMcGrath commented 4 years ago

In those cases, you're making raw method calls. Those aren't "pythonized" for you yet. My approach in these cases is similar to this:

with TenableSC('hostname', username='admin', password='password') as sc:
    with open(filename, 'rb') as license:
        sc.post('config/license/register', json={
            'filename': sc.files.upload(license)
        })