PDA

View Full Version : character conversion -- what function is this??



djr33
09-22-2006, 12:24 AM
I'm writing a page as an addition to my forum and I need to have a login on it.
The passwords are encrypted using the md5() function, then stored in the database. To login, it takes the submitted password, then uses the md5() on that and compares it to the stored value in the database. If it's a match, then the passwords were as well. Fairly standard procedure.

I've had success doing this before, but I just ran into trouble when using a password that had a symbol in it.

For testing purposes, I tried using the password:
!@#$%^&*()?abc123
and the result was:
&`#33;@#&`#036;%^&*()?abc123
(NOTE: ignore the backticks-- ````, between the &/#. If I don't put something in there, the board displays the character (ie-- #33 becomes !, etc.)

What I can't do, however, is match that encoding. All I need to do to verify the password is:
if ($dbpassstored == md5(encodefunction($sentpass))) {}

But I don't know what "encodefunction" is.

So, can someone tell me what I could use to get that result?
I already tried htmlentities() and urlencode(), but the results are different.

Thanks.

codeexploiter
09-22-2006, 05:52 AM
This is a program that i used to test your condition. Plz check this out i think you've missed something in your posing especially you haven't mentioned you used htmlentities() on your password.

If you apply md5() along it won't give you this result &`#33;@#&`#036;%^&*()?abc123


<?php
//this program doesn't use database as you mentioned in your post. But i think you can find some fairly good idea from this program

//The password given for the testing purpose
$pass = "!@#$%^&*()?abc123";

//Display the value if we call the htmlentities()
echo "Value of $pass after applying htmlentities function : " .htmlentities($pass) ."<br><br>\n";
$htmlpass = htmlentities($pass);
//The output value you mentioned in your posting will be the output
//&`#33;@#&`#036;%^&amp;*()?abc123

//Applying hashing function on the password that has already been applied the HTML encoding
$pass_stored = md5($htmlpass);

//displaying the finaal password you stored in your db
echo "The password stored in your database: $pass_stored <br>\n";

//You want to check a user entered password is matching with the password stored
//I am assuming that we are dealing with this one password here

//The password from the user
$sent_password = "!@#$%^&*()?abc123";

//Applying html encoding on it
$sent_password = htmlentities($sent_password);

//applying hashing on the HTML encoded password from the user and comparing it with the password
//that is in DB already hashed and HTML encoded
if($pass_stored == md5($sent_password))
echo "Passwords are matching<br>\n";
else
echo "Passwrods are not matching<br>\n";

?>


If i run the above code I am getting an output Passwords are matching.

html_entity_decode() is the opposite of htmlentities() in that it converts all HTML entities to their applicable characters from string. If thats what you are looking for.

djr33
09-22-2006, 06:40 AM
I know what md5 does, but the problem is that the password must match BEFORE it's put through the md5 function.

htmlentities didn't match the output that the forum gave when it encoded the password. (I added an echo to see what it output right before going through the md5() function.)

So... not sure how to get it to match that.



To rephrase, without all the extra info, what I need is to know which function makes
!@#$%^&*()?abc123
into:
&`#33;@#&`#036;%^&amp;*()?abc123

(ignore the backticks-- ```, as above)


A simpler way to look at it is that I need a function that when ! is input, the output is &#33 ;

Twey
09-22-2006, 08:44 AM
It doesn't really matter. As with MD5, all you need to know in order to use it in this case is that it will always return the same value for a given string.

codeexploiter
09-22-2006, 08:54 AM
checkout the mb_convert_encoding() in php

djr33
09-22-2006, 10:19 AM
Twey, I don't understand your response.
the problem is that in my script the input to md5 differs from the input to md5 in the forum's script, so the outputs differ, because the inputs differ.

codeexploiter, I get an error (undefined function) when calling that, and looking it up on php.net just gives info on converting from various character sets to each other.
Do you have a suggestion of which to use?

Twey
09-22-2006, 01:37 PM
Oh, I see, sorry. My misjudgement.
(NOTE: ignore the backticks-- ````, between the &/#. If I don't put something in there, the board displays the character (ie-- #33 becomes !, etc.)Try .

The output certainly looks like urlencode(), but this could well be a search/replace operation. The only way to be sure of what's going on is to look up what happens in the board's code.

djr33
09-23-2006, 12:37 AM
The board's code is insanely complex. There are dozens of pages, each with about 500 lines of code (or more).
I tried looking it up, but the only part I found was where it was converted to md5. The value is, at that point, stored as part of an array called "$input" and I coudln't find where anything was done to it. That's the interesting thing.... if there is a search/replace operation, I don't see the function, as it isn't where it should be.
The forum is all one page, index.php which then uses includes based on the operation to generate the pages. However, I can't find anything to do with the encoding on either the index page or the included page (Usercp.php), so it must be in one of the other included pages, but, again, it's a maze.

As for urlencode, the output I get from that is %21 for the !. It encodes for urls, not html. So... space=%20, not &nbsp; etc. Any ideas?



Ah, [b] works well. Thanks.

Twey
09-23-2006, 02:07 PM
The board's code is insanely complex. There are dozens of pages, each with about 500 lines of code (or more).This is why we have grep :)
$ grep -r '$input' /var/www/localhost/boarddir
As for urlencodeI meant htmlentities(). >.<

djr33
09-24-2006, 12:21 AM
htmlentities() doesn't encode an exclamation point, just quotes, ampersands, and other things that would affect the code. Since ! has no html function, it ignores that.

Grep? What's that?

blm126
09-24-2006, 03:59 AM
grep is a *nix command. It uses regular expressions I believe. You can probably get a version for Mac. Also some code editors provide a similiar tool(mine does).

djr33
09-24-2006, 04:22 AM
What does it do, and how would I go about using it?
I use both mac and pc (windows, not linux, sorry), by the way.

EDIT: Ok, got that answer with google... it searches for stuff that matches a string. Cool.
However, not sure how to run it on the server. The code you gave, Twey, isn't php and gives an error. Is there another way to run that on my server?

djr33
09-24-2006, 06:20 AM
Well, alright. I did some more searching, and I've found the part where it's converted. That's the good news. The bad news is that it's not just a function, but rather a search and replace and a complex one at that.

If you can help me figure out what this does, and immitate it on a smaller scale for a password, that would be great.


On the index.php page, before anything else, there is this line:
$ibforums->input = $std->parse_incoming();
Which calls the function parse_incoming() found on functions.php:
/*-------------------------------------------------------------------------*/
// Makes incoming info "safe"
/*-------------------------------------------------------------------------*/

function parse_incoming()
{
global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_CLIENT_IP, $REQUEST_METHOD, $REMOTE_ADDR, $HTTP_PROXY_USER, $HTTP_X_FORWARDED_FOR;
$return = array();

if( is_array($HTTP_GET_VARS) )
{
while( list($k, $v) = each($HTTP_GET_VARS) )
{
if( is_array($HTTP_GET_VARS[$k]) )
{
while( list($k2, $v2) = each($HTTP_GET_VARS[$k]) )
{
$return[$k][ $this->clean_key($k2) ] = $this->clean_value($v2);
}
}
else
{
$return[$k] = $this->clean_value($v);
}
}
}

// Overwrite GET data with post data

if( is_array($HTTP_POST_VARS) )
{
while( list($k, $v) = each($HTTP_POST_VARS) )
{
if ( is_array($HTTP_POST_VARS[$k]) )
{
while( list($k2, $v2) = each($HTTP_POST_VARS[$k]) )
{
$return[$k][ $this->clean_key($k2) ] = $this->clean_value($v2);
}
}
else
{
$return[$k] = $this->clean_value($v);
}
}
}

//----------------------------------------
// Sort out the accessing IP
// (Thanks to Cosmos and schickb)
//----------------------------------------

$addrs = array();

foreach( array_reverse( explode( ',', $HTTP_X_FORWARDED_FOR ) ) as $x_f )
{
$x_f = trim($x_f);

if ( preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $x_f ) )
{
$addrs[] = $x_f;
}
}

$addrs[] = $_SERVER['REMOTE_ADDR'];
$addrs[] = $HTTP_PROXY_USER;
$addrs[] = $REMOTE_ADDR;

//header("Content-type: text/plain"); print_r($addrs); print $_SERVER['HTTP_X_FORWARDED_FOR']; exit();

$return['IP_ADDRESS'] = $this->select_var( $addrs );

// Make sure we take a valid IP address

$return['IP_ADDRESS'] = preg_replace( "/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/", "\\1.\\2.\\3.\\4", $return['IP_ADDRESS'] );

$return['request_method'] = ( $_SERVER['REQUEST_METHOD'] != "" ) ? strtolower($_SERVER['REQUEST_METHOD']) : strtolower($REQUEST_METHOD);

return $return;
}
That, as is shown in the first line of code, is then the value in $index.

Now, in Usercp.php, where the actual password change is executed,
$pass = trim($ibforums->input['pass']);
//lines ommitted
$md5_pass = md5($pass);
//insert into database, etc.


So, what I need is to be able to immitate this.

I know that the parse_incoming() function takes all incoming data-- get, post, cookies, sessions, etc.-- and converts it to a "safe" format. I also understand that it returns this as an array, which is later stored into the $ibforums->input array.

I need to do the same conversion, but with a value, $password, instead of all incoming data, and return the "safe" version of that $password.

Thanks for any help.

Among other things, one thing I really don't understand is preg_replace()... what is this? It replaces based on patterns, as it says on php.net, but how the heck does the first parameter work?

Also, if any of the functions in the parse_incoming() function aren't standard, I can find them for you in the source of one of the pages. I haven't checked all of them yet.



EDIT: Ok, as I thought, some of those are custom functions. Here's one--
function clean_value($val)
{
global $ibforums;

if ($val == "")
{
return "";
}

$val = str_replace( "&#032;", " ", $val );

if ( $ibforums->vars['strip_space_chr'] )
{
$val = str_replace( chr(0xCA), "", $val ); //Remove sneaky spaces
}

$val = str_replace( "&" , "&amp;" , $val );
$val = str_replace( "<!--" , "&#60;&#33;--" , $val );
$val = str_replace( "-->" , "--&#62;" , $val );
$val = preg_replace( "/<script/i" , "&#60;script" , $val );
$val = str_replace( ">" , "&gt;" , $val );
$val = str_replace( "<" , "&lt;" , $val );
$val = str_replace( "\"" , "&quot;" , $val );
$val = preg_replace( "/\n/" , "<br>" , $val ); // Convert literal newlines
$val = preg_replace( "/\\\$/" , "&#036;" , $val );
$val = preg_replace( "/\r/" , "" , $val ); // Remove literal carriage returns
$val = str_replace( "!" , "&#33;" , $val );
$val = str_replace( "'" , "&#39;" , $val ); // IMPORTANT: It helps to increase sql query safety.

// Ensure unicode chars are OK

if ( $this->allow_unicode )
{
$val = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $val );
}

// Strip slashes if not already done so.

if ( $this->get_magic_quotes )
{
$val = stripslashes($val);
}

// Swop user inputted backslashes

$val = preg_replace( "/\\\(?!&amp;#|\?#)/", "&#092;", $val );

return $val;
}

blm126
09-24-2006, 06:26 AM
$std->clean_value That is the function doing the real work.You can ignore the regular expressions(preg_*) for what you want.

djr33
09-24-2006, 06:33 AM
Ok, right. Sorry, for some reason, I thought there was more to the parse_incoming function.

As for clean_value, how can I ignore the preg_replace functions? They're doing a lot, right? I just don't quite understand what they're doing....

blm126
09-24-2006, 12:19 PM
in clean value, yes the preg_replace functions are important, but in parse_incoming they just validate the IP address. If you are connecting the to the forum software just use that function(by passing in the values to check) if not copy and paste to the rescue. Remeber though you should handle slashes yourself and remove that part from the function, and probably the unicode part also.

djr33
09-24-2006, 01:08 PM
I can just copy the function. That's easy. But I'd also like to know what it's doing (mainly the preg_replace, but, I've looked at the other thread about regular expressions, and I'm beginning to understand).

Right, I meant the preg_replace functions in clean_value.

As for slashes/unicode.... wouldn't I need those for it to match? The password needs to match the password on the forum, so it would need those parts, I'd think.

I guess at this point, I get what's going on, but just wanted to check because I don't know what is going on in some of that function, to be sure it wasn't doing anything I wouldn't expect (though not sure what that would be).

Thanks.

blm126
09-24-2006, 02:55 PM
Yes you do need to handle slashes/unicode the same way,but you won't have access to the config variables to check so you may need to hardcode what it should do.

djr33
09-24-2006, 09:44 PM
Ah, ok, right.

Thanks.

djr33
10-04-2006, 03:27 AM
$val = preg_replace( "/\\\(?!&amp;#|\?#)/", "\", $val );


How is this line valid? "\" means escape the quote... so the string would never end... right???


EDIT: Nevermind. The board is stripping things from the code. Now I get it.