OpenVAS Scanner 23.32.3
nasl_smb.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
15
16#include "nasl_smb.h"
17
18#include "../misc/plugutils.h"
19#include "base/hosts.h"
21
22#include <arpa/inet.h>
23#include <errno.h>
24#include <gvm/base/logging.h>
25#include <gvm/base/networking.h>
26#include <netinet/in.h>
27#include <stdbool.h>
28#include <stdio.h>
29#include <string.h>
30#include <sys/socket.h>
31#include <unistd.h>
32
33#define IMPORT(var) char *var = get_str_var_by_name (lexic, #var)
34
35#undef G_LOG_DOMAIN
39#define G_LOG_DOMAIN "lib nasl"
40
51{
52 char *version = smb_versioninfo ();
53 tree_cell *retc;
54 (void) lexic;
55
56 if (!version)
57 return NULL;
58
60 retc->x.str_val = strdup (version);
61 retc->size = strlen (version);
62 return retc;
63}
64
79{
80 struct script_infos *script_infos = lexic->script_infos;
81 struct in6_addr *host = plug_get_host_ip (script_infos);
82 char *ip;
83 char *username = get_str_var_by_name (lexic, "username");
84 char *password = get_str_var_by_name (lexic, "password");
85 char *share = get_str_var_by_name (lexic, "share");
86
87 tree_cell *retc;
88 SMB_HANDLE handle = 0;
89 int value;
90
91 if ((host == NULL) || (username == NULL) || (password == NULL)
92 || (share == NULL))
93 {
94 g_message ("nasl_smb_connect: Invalid input arguments");
95 return NULL;
96 }
97
98 ip = addr6_as_str (host);
99 if ((strlen (password) == 0) || (strlen (username) == 0) || (strlen (ip) == 0)
100 || (strlen (share) == 0))
101 {
102 g_message ("nasl_smb_connect: Invalid input arguments");
103 g_free (ip);
104 return NULL;
105 }
106
108 value = smb_connect (ip, share, username, password, &handle);
109 g_free (ip);
110
111 if (value == -1)
112 {
113 g_message ("nasl_smb_connect: SMB Connect failed");
114 return NULL;
115 }
116
117 retc->x.i_val = handle;
118 return retc;
119}
120
132tree_cell *
134{
135 SMB_HANDLE handle = (SMB_HANDLE) get_int_var_by_name (lexic, "smb_handle", 0);
136 int ret;
137 tree_cell *retc;
138
140
141 ret = smb_close (handle);
142 if (ret == 0)
143 {
144 retc->x.i_val = 1;
145 return retc;
146 }
147 else
148 return NULL;
149}
150
162tree_cell *
164{
165 SMB_HANDLE handle = (SMB_HANDLE) get_int_var_by_name (lexic, "smb_handle", 0);
166 char *filename = get_str_var_by_name (lexic, "filename");
167
168 if (!filename)
169 {
170 g_message ("smb_file_SDDL failed: Invalid filename");
171 return NULL;
172 }
173
174 if (!handle)
175 {
176 g_message ("smb_file_SDDL failed: Invalid smb_handle");
177 return NULL;
178 }
179
180 tree_cell *retc;
181 char *buffer = NULL;
182
183 buffer = smb_file_SDDL (handle, filename);
184
185 if (buffer == NULL)
186 return NULL;
187
189 retc->size = strlen (buffer);
190 retc->x.str_val = strdup (buffer);
191 return retc;
192}
193
205tree_cell *
207{
208 SMB_HANDLE handle = (SMB_HANDLE) get_int_var_by_name (lexic, "smb_handle", 0);
209 char *filename = get_str_var_by_name (lexic, "filename");
210
211 if (!filename)
212 {
213 g_message ("smb_file_owner_sid failed: Invalid filename");
214 return NULL;
215 }
216
217 if (!handle)
218 {
219 g_message ("smb_file_owner_sid failed: Invalid smb_handle");
220 return NULL;
221 }
222
223 tree_cell *retc;
224 char *buffer;
225
226 buffer = smb_file_OwnerSID (handle, filename);
227
228 if (buffer == NULL)
229 return NULL;
230
232 retc->size = strlen (buffer);
233 retc->x.str_val = strdup (buffer);
234 return retc;
235}
236
248tree_cell *
250{
251 SMB_HANDLE handle = (SMB_HANDLE) get_int_var_by_name (lexic, "smb_handle", 0);
252 char *filename = get_str_var_by_name (lexic, "filename");
253
254 if (!filename)
255 {
256 g_message ("smb_file_group_sid failed: Invalid filename");
257 return NULL;
258 }
259
260 if (!handle)
261 {
262 g_message ("smb_file_group_sid failed: Invalid smb_handle");
263 return NULL;
264 }
265
266 tree_cell *retc;
267 char *buffer;
268
269 buffer = smb_file_GroupSID (handle, filename);
270
271 if (buffer == NULL)
272 return NULL;
273
275 retc->size = strlen (buffer);
276 retc->x.str_val = strdup (buffer);
277 return retc;
278}
279
291tree_cell *
293{
294 SMB_HANDLE handle = (SMB_HANDLE) get_int_var_by_name (lexic, "smb_handle", 0);
295 char *filename = get_str_var_by_name (lexic, "filename");
296
297 if (!filename)
298 {
299 g_message ("smb_file_trustee_rights failed: Invalid filename");
300 return NULL;
301 }
302
303 if (!handle)
304 {
305 g_message ("smb_file_trustee_rights failed: Invalid smb_handle");
306 return NULL;
307 }
308
309 tree_cell *retc;
310 char *buffer;
311
312 buffer = smb_file_TrusteeRights (handle, filename);
313
314 if (buffer == NULL)
315 return NULL;
316
318 retc->size = strlen (buffer);
319 retc->x.str_val = strdup (buffer);
320 return retc;
321}
322
335
336tree_cell *
338{
339 struct script_infos *script_infos = lexic->script_infos;
340 struct in6_addr *host_ip = plug_get_host_ip (script_infos);
341 gvm_host_t *gvm_host = NULL;
342 char *argv[7], *unicode, target[2048], *c;
343 tree_cell *retc;
344 GString *string = NULL;
345 int sout, ret;
346 GError *err = NULL;
347 bool krb5 = false;
348 bool calculate_host = false;
349 char first_kdc[INET6_ADDRSTRLEN] = {0};
350 const char *delimiter;
351
352 IMPORT (host);
353 IMPORT (username);
354 IMPORT (password);
355 IMPORT (realm);
356 IMPORT (kdc);
357
358 IMPORT (cmd);
359 krb5 = kdc != NULL;
360
361 if ((username == NULL) || (password == NULL) || (cmd == NULL))
362 {
363 g_message ("win_cmd_exec: Invalid input arguments");
364 return NULL;
365 }
366
367 if (host == NULL)
368 {
369 calculate_host = true;
370 host = addr6_as_str (host_ip);
371 if (krb5)
372 {
373 gvm_host = gvm_host_from_str (host);
374 g_free (host);
375 host = gvm_host_reverse_lookup (gvm_host);
376 g_free (gvm_host);
377 }
378 }
379 if (host == NULL)
380 {
381 g_message ("win_cmd_exec: host must not be empty.");
382 return NULL;
383 }
384 if ((strlen (password) == 0) || (strlen (username) == 0)
385 || strlen (host) == 0)
386 {
387 g_message ("win_cmd_exec: Invalid input arguments");
388 if (calculate_host)
389 g_free (host);
390 return NULL;
391 }
392
393 /* wmiexec.py uses domain/username format. */
394 if ((c = strchr (username, '\\')))
395 *c = '/';
396 if (strchr (username, '/') == NULL)
397 {
398 snprintf (target, sizeof (target), "%s/%s:%s@%s", realm, username,
399 password, host);
400 }
401 else
402 {
403 snprintf (target, sizeof (target), "%s:%s@%s", username, password, host);
404 }
405 if (calculate_host)
406 g_free (host);
407
408 argv[0] = "impacket-wmiexec";
409 if (krb5 == false)
410 {
411 argv[1] = target;
412 argv[2] = cmd;
413 argv[3] = NULL;
414 }
415 else
416 {
417 delimiter = strchr (kdc, ',');
418 if (delimiter != NULL)
419 {
420 strncpy (first_kdc, kdc, delimiter - kdc);
421 }
422 else
423 {
424 strncpy (first_kdc, kdc, sizeof (first_kdc) - 1);
425 }
426 argv[1] = "-k";
427 argv[2] = "-dc-ip";
428 argv[3] = first_kdc;
429 argv[4] = target;
430 argv[5] = cmd;
431 argv[6] = NULL;
432 }
433 ret = g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL,
434 NULL, NULL, NULL, &sout, NULL, &err);
435 if (ret == FALSE)
436 {
437 g_warning ("win_cmd_exec: %s", err ? err->message : "Error");
438 if (err)
439 g_error_free (err);
440 return NULL;
441 }
442
443 string = g_string_new ("");
444 while (1)
445 {
446 char buf[4096];
447 size_t bytes;
448
449 bytes = read (sout, buf, sizeof (buf));
450 if (!bytes)
451 break;
452 else if (bytes > 0)
453 g_string_append_len (string, buf, bytes);
454 else
455 {
456 g_warning ("win_cmd_exec: %s", strerror (errno));
457 g_string_free (string, TRUE);
458 close (sout);
459 return NULL;
460 }
461 }
462 close (sout);
463
464 if (g_str_has_prefix (string->str, "[-]"))
465 {
466 g_warning ("win_cmd_exec: %s", string->str);
467 g_string_free (string, TRUE);
468 return NULL;
469 }
470 else if ((unicode = strstr (string->str, "\xff\xfe")))
471 {
472 /* UTF-16 case. */
473 size_t length, diff;
474 err = NULL;
475 char *tmp;
476
477 diff = unicode - string->str + 1;
478 tmp = g_convert (unicode + 2, string->len - diff, "UTF-8", "UTF-16", NULL,
479 &length, &err);
480 if (!tmp)
481 {
482 g_warning ("win_cmd_exec: %s", err->message);
483 g_string_free (string, TRUE);
484 g_error_free (err);
485 return NULL;
486 }
487 g_free (string->str);
488 string->len = length;
489 string->str = tmp;
490 }
491
493 retc->x.str_val = string->str;
494 retc->size = string->len;
495 return retc;
496}
struct struct_lex_ctxt lex_ctxt
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
u_short length
tree_cell * nasl_smb_file_owner_sid(lex_ctxt *lexic)
Obtain File Owner SID.
Definition nasl_smb.c:206
tree_cell * nasl_smb_file_SDDL(lex_ctxt *lexic)
Obtain Security Descriptor in SDDL format.
Definition nasl_smb.c:163
tree_cell * nasl_smb_file_trustee_rights(lex_ctxt *lexic)
Obtain File Trustee SID with Access Mask.
Definition nasl_smb.c:292
#define IMPORT(var)
Definition nasl_smb.c:33
tree_cell * nasl_smb_versioninfo(lex_ctxt *lexic)
Get a version string of the SMB implementation.
Definition nasl_smb.c:50
tree_cell * nasl_smb_close(lex_ctxt *lexic)
Close SMB service handle.
Definition nasl_smb.c:133
tree_cell * nasl_smb_connect(lex_ctxt *lexic)
Connect to SMB service and return a handle for it.
Definition nasl_smb.c:78
tree_cell * nasl_smb_file_group_sid(lex_ctxt *lexic)
Obtain File Group SID.
Definition nasl_smb.c:249
tree_cell * nasl_win_cmd_exec(lex_ctxt *lexic)
Execute the command in windows.
Definition nasl_smb.c:337
Protos for NASL SMB API.
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
@ CONST_INT
Definition nasl_tree.h:79
struct TC tree_cell
API protos describing the interface of a smb interface implementation.
int smb_close(SMB_HANDLE)
Close the connection handle for SMB service.
char * smb_file_GroupSID(SMB_HANDLE, const char *)
Obtain the SID of the Group for a given file/path.
char * smb_versioninfo(void)
Return version info for SMB implementation.
char * smb_file_OwnerSID(SMB_HANDLE, const char *)
Obtain the SID of the Owner for a given file/path.
int smb_connect(const char *, const char *, const char *, const char *, SMB_HANDLE *)
Establish connection to a SMB service.
char * smb_file_TrusteeRights(SMB_HANDLE, const char *)
Obtain the Trustee SID and their rights for a given file/path.
long int SMB_HANDLE
char * smb_file_SDDL(SMB_HANDLE, const char *)
Obtain Windows file rights in SDDL format.
struct in6_addr * plug_get_host_ip(struct script_infos *args)
Definition plugutils.c:371
Header file for module plugutils.
int size
Definition nasl_tree.h:99
long int i_val
Definition nasl_tree.h:104
union TC::@332262321161220155002104006201360276211317150140 x
char * str_val
Definition nasl_tree.h:103
Host information, implemented as doubly linked list.
Definition hosts.c:37
Define a string struct for storing the response.
struct script_infos * script_infos