D-Link DIR-615 router login script example

< ?php
	# To login to a D-Link DIR-615 router using PHP, used D-Link JavaScript source to make this
	# by dotpointer

	# NOTE: Make sure you have cURL extension loaded, 
	# also change url, username and password to match your router configuration.

	# change log:
	# 2012-12-26
	# 2013-04-05

	# url to router
	$baseurl = 'http://router/'; # ip address may be used instead, http://192.168.1.1/ for example

	# username and password
	$user = 'Admin';
	$pass = '123456'; # may be left '' if no password is set (default)

	# as PHP:s built-in array_merge does not do a real merge with overwriting of int-keys, we do it ourself
	function array_merge_keep_keys(/* dynamic */) {
		$result = array();
		foreach (func_get_args() as $arg) {
			if (!is_array($arg)) continue;
			foreach ($arg as $k => $v) {
				$result[$k] = $v;
			}
		}
		return $result;
	}

	# simple curling function to send and receive data
	function curl_do($c, $opt=array()) {

		# default setup
		$defopt = array(
			CURLOPT_COOKIESESSION	=> true,
			CURLOPT_URL		=> '',
			CURLOPT_RETURNTRANSFER 	=> true,	# return web page
			CURLOPT_HEADER         	=> false,	# don't return headers
			CURLOPT_FOLLOWLOCATION 	=> true,	# follow redirects
			CURLOPT_ENCODING       	=> "",		# handle all encodings
			CURLOPT_USERAGENT      	=> "test",	# who am i
			CURLOPT_AUTOREFERER    	=> true,	# set referer on redirect
			CURLOPT_CONNECTTIMEOUT 	=> 120,		# timeout on connect
			CURLOPT_TIMEOUT        	=> 120,		# timeout on response
			CURLOPT_MAXREDIRS      	=> 10,		# stop after 10 redirects
			CURLOPT_POST            => false,	# i am sending post data
			CURLOPT_SSL_VERIFYHOST	=> 0,		# don't verify ssl
			CURLOPT_SSL_VERIFYPEER	=> false,
			CURLOPT_VERBOSE		=> false,       # set to true to echo headers
		);

		# merge defaults and provided parameters to get the best mix
		$opt = array_merge_keep_keys($defopt, $opt);

		curl_setopt_array($c, $opt);
		$r = curl_exec($c);
		if (curl_errno($c)) {
		    	# could not connect to host?  then get out silently
		    	if (curl_errno($c) === 7) die();
			die('cURL-error: '.curl_error($c).' ('.curl_errno($c).')');

		}
		return $r;
	}

	# Equivalent to String.charCodeAt
	function charCodeAt($str, $i=0){
		return ord(substr($str, $i, 1));
	}

	# Equivalent to String.fromCharCode
	function fromCharCode($u) {
		return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-8', 'HTML-ENTITIES');
	}

	# warm up cURL
	$c = curl_init();

	# call for the salt
	$r = curl_do($c, array(CURLOPT_URL => $baseurl));

	# 1. Salt in hex, 8 chars long - looking for 'var salt = "92b3b656";'
	preg_match_all('/var salt = \"([a-z0-9]{8})\"/', $r,$matches);
	$salt = $matches[1][0];

	# 2.
	$pass = substr($pass,0,16);

	# 3. Pad the password to 16 chars.
	while (strlen($pass) < 16) {
		$pass .= fromCharCode(1);
	}

	# 4. Append the password to the salt and pad the result to 63 bytes.
	$input = $salt.$pass;
	while (strlen($input) < 63) {
		$input .= fromCharCode(1);
	}

	# 5. Append a 'U' for user login, or a '\x01' for admin login.
	$input .= fromCharCode(1);

	# 6. MD5 hash of the salt
	$hash = md5($input);

	# 7. Append the MD5 hash to the salt.
	$login_hash = $salt .= $hash;

	# 8. Send the login hash to the server.
	$r = curl_do($c, array(CURLOPT_URL => $baseurl.'post_login.xml?hash='.$login_hash));

	/*
		OK (?): <?xml version="1.0" encoding="UTF-8" standalone="yes"?><login>Basic/Internet.shtml</login>
		FAIL  : <?xml version="1.0" encoding="UTF-8" standalone="yes"?><login>error</login>
	*/

	if (strpos($r, '<login>Basic/Internet.shtml</login>') === false) {
		die('Login failed, response was: '.$r);
	}

	echo 'success';
	# $r = curl_do($c, array(CURLOPT_URL => $baseurl.'wifi_assoc.xml'));
	/* <?xml version="1.0" encoding="UTF-8" standalone="yes"?><wifi_assoc></wifi_assoc> */

	# further calls may be done with the connection $c from here
?>

This is a personal note. Last updated: 2013-04-05 13:09:01.



LinkedIn
Klebe.se

Don't forget to pay my friend a visit too. Joakim