Home > php, Reverse Engineering, wordpress > Reverse WordPress admin module

Reverse WordPress admin module

February 14th, 2011

Αυτό που με εξιτάρει περισσότερο στο τομέα του development είναι όταν έχω ένα πρόβλημα και η λύση είναι στο reverse ;)

Ας υποθέσουμε ότι χρειαζόμαστε να συνδέσουμε μια υπάρχουσα εφαρμογή με το wordpress χωρίς όμως να ξαναφτιάξουμε την εφαρμογή χρησιμοποιώντας τις βιβλιοθήκες του. Χρειαζόμαστε ένα plugin που να εμφανίζει ένα iframe με την εφαρμογή μας. Πολύ εύκολο για κάποιον που έχει ασχοληθεί με plugins στο wordpress. Το δύσκολο είναι πως θα καταλάβει η εφαρμογή, ότι ο χρήστης είναι συνδεμένος, ώστε να μην μπορεί κάποιος να την χρησιμοποιήσει χωρίς login.

Και κάπου εδώ ξεκινάει το reverse. Στα php application (open source), σε αντίθεση με τα executable application το reverse είναι πολύ απλή υπόθεση, γιατί το μόνο που χρειάζεται είναι υπομονή και πολλά echo ή file_put_contents.

Ξεκινώντας από την index.php στο wp-admin έχουμε ένα include στην admin.php όπου στην συνέχεια έχει μια κλήση στην function auth_redirect που βρίσκεται στην wp-includes/ pluggable.php. Στην function auth_redirect έχει μια κλήση στην wp_validate_auth_cookie όπου εκεί βρίσκεται ο έλεγχος για την εγκυρότητα του logged in. Ο έλεγχος βασίζεται σε ένα cookie όπου περιέχει 3 στοιχεία, το username το expires, και τέλος ένα hash value. Με κάποιο αλγόριθμο χρησιμοποιώντας το username κάποια salt και keys, και το encrypted password που έχει o user αποθηκευμένο στην db (mysql), παράγεται ένα hash value το οποίο στην συνέχεια συγκρίνεται με το hast value από το cookie.

Άρα χρειαζόμαστε 2 τιμές για να μπορέσουμε να κάνουμε την σύγκριση και στον δικό μας κώδικα. Η μία είναι το cookie και η δεύτερη η πρόσβαση στην db για να διαβάσουμε το encrypted password. Το cookie μπορούμε να το περάσουμε σαν argument στο iframe και το password μπορούμε να το διαβάσουμε αν γνωρίζουμε τα login/pass της mysql (connection string) και το username του χρήστη.

Φτιάχνουμε λοιπόν ένα plugin που το μόνο που έχει, είναι την εμφάνιση του iframe στην επιλογή ενός item menu.

<?php
/**
 * @package MyAdmin
 */
/*
Plugin Name: MyAdmin
Plugin URI: http://developstories.gr
Description:
Version: 1.0.0
Author: Thek
Author URI: http://socialwhale.com/thek27
License: GPLv2
*/
add_action('admin_menu', 'my_plugin_menu');

function my_plugin_menu() {
	add_menu_page('MyAdmin', MyAdmin', 'read', 'my_menu','my_view');
}

function my_view() {
	echo '<iframe src="/my-admin?auth_cookie='.$_COOKIE[AUTH_COOKIE].'&auth_key='.urlencode(base64_encode(AUTH_KEY.AUTH_SALT)).'" width="100%" height="500"></iframe>';
}
?>

Αν δούμε καλύτερα στο src του iframe περνάμε 2 μεταβλητές και όχι μόνο το cookie άλλα το AUTH_KEY και το AUTH_SALT όπου τα χρησιμοποιεί ο αλγόριθμος για την παραγωγή του hash value. Αυτά βρίσκονται στο wp-config.php. Για μεγαλύτερη ασφάλεια μπορούμε να τα κάνουμε copy/paste στον δικό μας αλγόριθμο χωρίς να τα περνάμε στο url.

Τώρα δεν μένει παρά να αντιγράψουμε τον κώδικα που παράγει το hast value, και στην συνεχεία να κάνουμε την σύγκριση.
Ο αλγόριθμος είναι βασισμένος σε 2 συνεχόμενα md5 hash values.

<?
list($username, $expiration, $hmac) = explode('|', $_GET['auth_cookie']);

$db->query('SELECT `user_pass` FROM `wp_users` WHERE `user_login`="'.addslashes($username).'" LIMIT 1');
if ($db->next()) {
	$pass_frag = substr($db->Record['user_pass'], 8, 4);
	$key = hash_hmac('md5', $username . $pass_frag . '|' . $expiration, base64_decode($_GET['auth_key']));
	$hash = hash_hmac('md5', $username . '|' . $expiration, $key);

	//$hash==$hmac
}
?>

php, Reverse Engineering, wordpress