问题
So I'm doing some CTF and one of the challenge is about php type juggling. The code looks something like this
if($_GET['var1'] == hash('md4', $_GET['var1']))
{
//print flag
}
So I was 80% sure that I need to pass in an integer so it'll be true but all I can manipulate is the url. I tried using python request to do it but still failed.
import requests
url = 'http://example.com'
params = dict(var1=0)
r = requests.get(url=url, params=params)
Is there any special case where php will treat the variable pass into GET array as int? Or there is other way to do so?
回答1:
The answer to this CTF can be found here https://medium.com/@Asm0d3us/part-1-php-tricks-in-web-ctf-challenges-e1981475b3e4
The general idea is to find a value which starts with 0e
and its hash also starts with 0e
. The page gives an example of 0e001233333333333334557778889
which produces a hash of 0e434041524824285414215559233446
This notation is called scientific notation. To understand why this kind of type juggling works you need to understand what both numbers are. If we convert from scientific notation to decimal it becomes obvious.
0e001233333333333334557778889
= 0×1012333333333333345577788890e434041524824285414215559233446
= 0×10434041524824285414215559233446
From primary school maths we know that anything multiplied by 0 is 0, which means both numbers are 0.
All input provided in the $_GET
or $_POST
superglobals is of type string.
Thanks to PHP's type juggling system both strings are treated as floating point numbers written in scientific notation and when cast to float they both equal 0.
来源:https://stackoverflow.com/questions/56487143/passing-integer-to-php-get-via-url