Hack sbicapsec.com to run on Firefox

`AG_BACKQUOTE_TURN_ON`

www.sbicapsec.com is State Bank of India’s online share trading portal. This is a good portal but their site’s code quality is amazingly of low quality, dare I say, crappy. SBI being a public sector government institute, we can rest assured that the code quality or bugs in it would not get fixed soon, if ever.

Anyway as of now if you try using this portal in Firefox or Chrome, then maybe you will endup with a screen like this.

sbicapsec.com after login in Firefox. Notice no applet running, instead we have weird “:10”.

Notice the weird “:10” character in the screenshot, instead of the Java Applet.

Fixing sbicapsec.com to run in Firefox

Don’t worry the “hack” here is not illegal. This is used merely as an expression for making things work the way you want it which requires a lot of technical trickery to get it right.

The following has been tested in Firefox 13 and 14 in Mac OSX and Windows XP. You are free to try this as you may want it though. Also this should work in Chrome too.

Now let’s get into fixing this in few simple steps:-

  1. For your sake, open this blog page in your Firefox browser.
  2. Install GreaseMonkey browser extension. You may need to restart your browser.
  3. Install my GreaseMonkey user script by clicking on the link here – AppVersion Patch for SBICAPSEC.
  4. Click on Install button in the dialog box that you get.

That is it! You should now get the applet after login.

Fixed sbicapsec.com, after login.

How the fix works (for the technically inclined)

This section is for geeks, who would like to know how the script works. Also it is better to understand this, so that you understand, there is no malicious code in my script.

What is wrong in sbicapsec.com’s site? (Root cause)

The portal’s JS code assumes that `navigator.appVersion` will always return a string which will have a semi-colon (;). In fact that is true for IE and Chrome (in Mac OSX version only), but not for others. After this failure everything goes down like dominoes.

The popup we get after login has a `frameset` with three frames. The second one is the one which is supposed to present the Java applet. The layout of that page is roughly as below:-

[code lang=”html”]
<body>

<applet>
<param>
<param>
<param>

</applet>
</body>
[/code]

It seems the devs there had a requirement to set the `width` and `height` of the `applet` based on user screen’s dimension. For this they modified the code to use JS to dynamically generate the upper `applet` tag.

[code lang=”html”]
<body>

<script>
// This script will generate the upper applet tag with appropriate width and height.
</script>
<param>
<param>
:10
<param>

</applet>
</body>
[/code]

It is in the above `script` tag where it reads `navigator.appVersion` and tries to split it by `;` and then read the other part. When that errors out, so does the code following it. That code is supposed to write the upper `applet` tag. So, at the end we are left with many `param` tags and a dangling `</applet>` tag. The weird `:10` characters are written between two `param` tags.

From the way they have written the JS code, it seems the devs did not visualize the html page as a tree of blocks, instead for them it was a file stream; like the kind when you use your Java or C++ file output stream. The `script` block above uses `document.write()` to write the opening `applet` tag, instead of using JS to directly manipulate the DOM objects. I wonder how these devs can layout a page, who visualize it as a stream of characters? And, this is just a fraction of the real code, who knows what else is inside. It seems SBI needs to seriously train its devs. All this makes me loose faith over the security and reliability of their site.

Anyway, enough of the rant, back to the topic. The patch script I wrote will, simply try to do what there code was meant to do, add the `applet` tag. Because of the dangling `applet` end tag, I was unable to wrap my `applet` around the existing `param` tags. So, instead I detached all the `param` tags, emptied the parent (this reference was stored before detaching `param`), then added `param` tags inside the newly create `applet` tag and finally added the `applet` inside the previous parent of `param` tags.

I also tried using other techniques but they did not work. The first one was directly modifying `navigator.appVersion` to return a string with `;`, but it seems you cannot modify them. The second options was to replace existing `String.split()` function with my own version. In my version I would always return an array of at least length two, so that the code does not error out. Anyway this too did not work out since GreaseMonkey scripts are ran after the page is executed. GreaseMonkey does provide an option to run our scripts at the beginning too, but according to docs that is not supported inside frames.

Anyway, all’s well that ends well. 🙂

How to Reset the Root Password of MySql in Linux

I am posting this for my future reference. Also it my help passers by.

If you are using CentOS 6 (maybe others too). To reset the root password use the following steps:-

  1. sudo service mysqld stop
  2. sudo service mysqld startsos
  3. mysql -u root
  4. Now you will be at mysql prompt. Here type:-
    1. UPDATE mysql.user SET Password=PASSWORD(‘NewPassHere’) WHERE User=’root’;
    2. FLUSH PRIVILEGES;
    3. quit;
  5. sudo service mysqld restart

Script that notifies via email when your server has updates

If you are the administrator of a server then you definitely understand the importance of keeping your system updated always.

The following script will send you a mail whenever your server needs an update. The content of the mail will list out all the available updates.

The script

[code lang=”shell”]
#!/bin/bash
# Author: AppleGrew
# Site: www.applegrew.com
# License: GPL v2

yum check-update > /tmp/checkupdate.log
if [[ $? == 100 ]]
then
mail -s "New YUM updates available" -r admin@example.com $MAILTO < /tmp/checkupdate.log
fi
[/code]

Notes:

  • This script has been tested on CentOS 6 but should run on all RedHat based systems.
  • In the above script, change admin@example.com to any valid email id which your server is authorized to send. This the email id for the ‘From’ field. For example you can not set this to (say) someone@gmail.com. Since Google did not authorize your server to send emails on behalf of gmail.com.

Installation notes

  • Copy this script to some directory in your server and give it execute permission.
  • Now schedule a cron job for this script. You can set this job for any user, since this script does not need root privileges.
  • In the cronjob make sure to set the MAILTO environment variable. The script uses this variable to determine the recipient of the notification.

Example cronjob

[code lang=”plain”]
MAILTO=yourmail@email.com
0 0 * * * /home/user1/checkupdate.sh
[/code]

Access Ext3/Ext2 file system on Mac OSX Lion (10.7)

On Mac if you want to access ext3/etx2 filesystems, which are used by Linux systems, you will find lots of links on net but all are pretty outdate and they don’t work for Lion. So, here is the updated version, which works. At least for me. 😉

You will need two softwares:-

  1. OSXFuseDownload link
  2. Fuse-ext2Download link

Download and install them in the sequence shown above.

Fuse-ext2 needs MacFuse to run, but this is no longer maintained and does not work on Lion. OSXFuse is the next generation MacFuse, but Fuse-ext2 is not meant to work with this. Fortunately OSXFuse includes “MacFUSE Compatibility Layer”. Just make sure to select this option when installing OSXFuse and you are good to go.

When both of them are installed, then try plugging in ext3 or etx2 partitioned disk and they should get automatically mounted, just like any other disk. Note, after installing them you may or may not need to restart your system.

PS. You will be able to read the disks but not write to it. As of now write option is not reliable.

Create your own Cyberoam client in Python!

This is a very old post. Reposting it since while migrating it from blogger.com to here it got lost. Found it recently. Not sure how relevant or correct is this now.


Cyberthon updated to version 2.5 by Vinit and Siddhartha Sahu:-
Get the latest code from https://github.com/siddharthasahu/Cyberthon-enhanced.
Cyberthon updated to version 1.2:-
Added a new feature in this version. Now Cyberthon won’t exit ever, once started, even when it can’t connect to Cyberoam server. If liked its old behavior then set never_quit to False
Code fixed now. Sorry, I didn’t notice before (for 2 months since posting it here) that the code here was not working. I think it is fixed now. The problem was that the tabs were being expaded here differently. So, I just ran expand cyberthon.py command to expand all tabs in it beforehand.

My college uses the software Cyberoam for controlling the bandwidth and timing allocated to us for surfing the internet. If you don’t know what is it then visit here. So, to access the internet we all need to install the client software and login via that. But I don’t like to install it because it feels like a college spy on my computer, you may find it irrational but I can’t help being a paranoid. I have always used the web login page of Cyberoam but it is not a very good solution, first because I will always need to keep the browser open. (The Cyberoam page refreshes at a specific time periodically. If it fails to do so then you get logged out.) Second problem is that on my Linux platform if I work from console mode then I can’t login because no browser can run without GUI support (I know of Lynx but I haven’t been able to use it for it.)

Recently I thought of investigating the working of the web login page of Cyberoam. After bringing up the login page of Cyberoam I changed the value of attribute method of form tag to GET from POST. So after filling-up the username and password when I hit enter key, there it was all the details that are sent from my browser to Cyberoam server in my browser address bar. I thought of simulating the POST action using a Python code. It required only a pinch of Python to do this. I tried the following Python code to simulate that and it worked, as it should. You too can try the following code and login to Cyberoam.

Code:

[code lang=”python” wraplines=”false”]
import urllib
urllib.urlopen("http://192.168.5.10:8090/corporate/servlet/CyberoamHTTPClient","mode=191&isAccessDenied=null&url=null&message=&username=YourUserName&password=YourPassword&saveinfo=saveinfo&login=Login")[/code]

Be sure to substitute YourUserName and YourPasswordfor your username and password respectively. The above will get you logged in but won’t keep you logged it because you need to re-post the login data at every (usually) 3 minutes. So, I got down to work again. Below is quick and dirty shell script to get around this problem. Note the above code has been distorted and compressed into single line and passed via piping to Python in script below.

Code:

[code lang=”bash” wraplines=”false”]
while [[ 1 == 1 ]]
do
printf "%s\n%s\n" "import urllib" "urllib.urlopen(\"http://192.168.5.10:8090/corporate/servlet/CyberoamHTTPClient\",\"mode=191&isAccessDenied=null&url=null&message=&username=YourUserName&password=YourPassword&saveinfo=saveinfo&login=Login\")" |python
sleep 3m
done[/code]

Again in the above code do replace YourUserName and YourPassword for your actual username and password respectively. Well now it was working great. 🙂 As usual I was again not satisfied because how will I know if I have logged in successfully or not? The only way for that was by parsing the returned page after logging-in for the message. I noticed that returned page’s source code contained…

[code lang=”html”][/code]

Please notice the part message. The value after that is the message I was seeking. So, all I needed is to parse this page for the value of attribute src of the tag frame. Also, note this very string also contains some more very useful values, viz. – loginstatus and liverequesttime. I noticed that value of loginstatus becomes true when logged in otherwise it remains false, and the value of liverequesttimegiave the time (in seconds) in which to re-post the login data.

The HTML parsing class in the Python script (which I wrote) below is based on the code from the great HTML parsing tutorial located here. Note the script uses the zenity command to display GUI dialog boxes. If you do not have this installed or simply don’t want to display GUI dialog boxes then start the script with -nogui argument. If you want the script to remain completely silent then use the -silent argument. I call this script Cyberthon (=Cyberoam+Python) 😉

Requirement(s):-
1) Python 2.5 (may work with previous versions, but not tested)
2) Zenity (needed to show the dialog boxes, use -nogui switch if you want the messages to appear on the console.)
Code:

[code lang=”python” wraplines=”false”]#!/usr/bin/python
#!/usr/bin/python

#Program Name: Cyberthon (Python Cyberoam Client)
#Coder AppleGrew
#License GPL
#Version 1.2
cyberroamIP = "192.168.5.10" #The IP of the Cyberoam site.
cyberroamPort = "8090" #Set to "" if not using.
username = "your_username" #Your username
passwordFile = "/home/you/.passwd" #Path file containing a single string, your password.
sleeptime = 0 #in minutes or set to 0, it will then parse this value from the cyberoam returned page dynamically.
never_quit = True #Once started cyberthon will never, even when the cyberoam server cannot be connected.

import sys

silent = False
nogui = False
for arg in sys.argv:
if "-silent" == arg:
silent = True
if "-nogui" == arg:
nogui = True

#Parsing and logging in too.
import sgmllib

class MyCyberroamParser(sgmllib.SGMLParser):
"A simple parser class."

def parse(self, s):
"Parse the given string ‘s’."
self.feed(s)
self.close()

def __init__(self, verbose=0):
"Initialise an object, passing ‘verbose’ to the superclass."

sgmllib.SGMLParser.__init__(self, verbose)
self.required_entities = [‘message’,’loginstatus’,’liverequesttime’]
self.frames_attr = []
self.in_required_entity = False
self.current_entity = ""
self.entity_values = {}

def do_frame(self, attributes):
for name, value in attributes:
if name == "src":
self.frames_attr.append(value)

def unknown_entityref(self,ref):
self.current_entity = ref
if ref in self.required_entities:
self.in_required_entity=True

def handle_data(self, data):
"Try to get the value of entity &message. Used in 2nd pass of parsing."

if self.in_required_entity:
self.entity_values[self.current_entity] = data[1:] #To remove the preceeding =
self.in_required_entity = False

def get_src(self,index=-1):
"Return the list of src targets."
if index == -1:
return self.frames_attr
else:
return self.frames_attr[index]

import urllib, sgmllib,time,commands,os

pf = open(passwordFile)
passwd = pf.readline()
pf.close()
if passwd[-1] == ‘\n’: #Removing terminating newline character.
passwd = passwd[:-1]

cyberroamAddress = cyberroamIP
if cyberroamPort != "":
cyberroamAddress = cyberroamAddress+":"+cyberroamPort

sec2sleep = 60*sleeptime
lastmsg = ""
msgChanged = True
lastMsgWasFailMsg = False
sec2sleepOnError = 6
while True:
try:
# Logging in and fetching the Cyberroam login page.
f = urllib.urlopen("http://"+cyberroamAddress+"/corporate/servlet/CyberoamHTTPClient","mode=191&isAccessDenied=null&url=null&message=&username="+username+"&password="+passwd+"&saveinfo=saveinfo&login=Login")
sec2sleepOnError = 6
except IOError, (errno, strerror):
if not silent:
print "Connection to Cyberoam server timed out. Error(%s): %s" % (errno, strerror)

if sec2sleepOnError > 30:
if not silent:
if nogui:
print "Quitting program."
else:
if never_quit:
if not lastMsgWasFailMsg:
os.popen(‘zenity –info –text="Failed to connect to server, but I am NOT quitting." –title="Cyberthon" >/dev/null’)
lastMsgWasFailMsg = True
else:
commands.getoutput(‘zenity –info –text="Could not connect to the server. Quitting program." –title="Cyberthon"’)
if not never_quit:
sys.exit(1)
else:
sec2sleepOnError = 6

if not silent:
print "Retrying in %s seconds" % sec2sleepOnError

time.sleep(sec2sleepOnError)
sec2sleepOnError = sec2sleepOnError*2
continue

s = f.read()

# Try and process the page.
# The class should have been defined first, remember.
myparser = MyCyberroamParser()
myparser.parse(s)

# Get the the src targets. It contains the status message. And then parse it again for entity &message.
qindex = myparser.get_src(1).index(‘?’)
srcstr = myparser.get_src(1)[:qindex+1]+’&’+myparser.get_src(1)[qindex+1:]

myparser.parse(srcstr)

message = myparser.entity_values[‘message’]
if lastmsg != message or lastMsgWasFailMsg:
lastmsg = message
msgChanged = True
lastMsgWasFailMsg = False

if (not silent) and msgChanged:
msgChanged = False

msg=”
i=0
while i < len(message): #Converting hex nos. to characters. t=message[i] if message[i]==’%’: no=int(message[i+1:i+3],16) t=chr(no) i=i+2 msg=msg+t i=i+1 message = "" for x in msg:#Changing all + to space. if x == ‘+’: x = " " message=message+x if nogui: print message else: os.popen(‘zenity –info –text="From Cyberoam: ‘+message+’" –title="Cyberthon" >/dev/null’)

if myparser.entity_values[‘loginstatus’].lower()!="true":
break;

if sleeptime==0:
sec2sleep = int(myparser.entity_values[‘liverequesttime’])
time.sleep(sec2sleep)
[/code]

Please copy the file very carefully. A single extra space here and there may throw Python haywire, making it throw up all sorts of nasty syntax errors. Paste the contents of this code in a file and name it – Cyberthon.py.