[Web] EasyPhp
문제가 총 3가지 이므로 나눠서 이야기 하겠습니다.
이 문제는 ?1=입력할값의 형태로 url에 값을 넣어야 하는데
입력한 값과 md5(입력한값) 같아야 합니다.
이럴때 php magic hash를 사용해야 하는데
원리는 이렇습니다.
if($str1 == md5($str))은 == 으로 값을 비교하기 때문에 느슨한 비교 연산자 입니다.
'3' == '3.0' 의 반환값은 True인 참 입니다. 하지만 '3' === '3.0'의 반환 값은 False인 거짓입니다.
이를 이용해서 값을 정하면 됩니다.
우리가 1.2e3이라는 부동소수점을 입력할때 1.2 * 10^3 이라는 값을 의미하는데
우리가 입력을 할때 0e + 어떤 값 이라고 입력을 하면 뭐든지 0 * 어떤값 의 형태가 되기 때문에 ==(느슨한 비교 연산자)에서는 참이 되는 것을 이용하는 것입니다.
0e215962017 , 0e9028856416420525 이런 값들은 md5를 해도 앞자리가 0e로 시작하게 됩니다.
http://3.16.68.122/Easy-php/?1=0e9028856416420525
↑ 1번 Flag
입력한 문자열 앞에 문자열 $salt를 결합한 후 해시값을 계산해서 같으면 flag를 출력해 주는 문제입니다.
하지만 입력하는 값은 2개가 달라야 합니다.
예를 들어 입력되는 값이 배열이 되는 경우에
$salt.$str이 배열일때 'test' . array('a', 'b')는 'testarray'로 들어가게 됩니다.
그렇다는 것은 test 자리인 $salt에 어떤값이 들어가도 양쪽에 똑같이 결합되기 때문에 배열로만 넣으면 참을 만들수 있습니다.
php에서 매개변수를 보낼때 a[ ] 이라고 전달을 하면 $_GET['a']에서 배열로 사용되게 됩니다.
그래서 2[]='a' , 3[]='b'로 입력하게 되면 다음과 같이 나오게 될것입니다.
2[]='a' $str2 = array(1) { [0]=> string(1) "a"}
3[]='b' $str3 = array(1) { [0]=> string(1) "b"}
그렇다면 값이 들어갈때 $salt의값과 array만 들어가게 되는것입니다.
http://3.16.68.122/Easy-php/?1=0e9028856416420525&2[]='a'&3[]='b'
↑ 1번,2번 Flag
이번 문제는 좀 난이도가 있어 보입니다.
일단 가장 중요한 FLAG 출력 부분에서는 참조연산자를 쓰는 것을 알수 있습니다.
그렇다는 것은 $res 에는 class 가 들어 가야 한다는 것을 알수 있는데...
$res는 다른거 뭐 없이 입력 한 값이 들어가는 변수 명이 였습니다.
그래서 unseriallize()와 stripslashes()를 피해가는 입력값을 찾는 찰나..
직렬화 데이터의 데이터 참조 라는 문구를 찾게 되었고,
php에서 값을 직렬화 해서 넣을수 있는 것 이였습니다.
그래서 위의 class Secrets를 넣어보기로 했습니다.
4=O:7:"Secrets":2:{s:4:"temp";N;s:4:"flag";R;2;} 를 추가 했습니다.
O는 class의 O // 7은 "Secrets"의 글자수 // 2는 내부의 값 2개
s는 문자열 // 4는 "temp"의 글자수 // N은 null값 // R은 참조값
↑ 1,2,3번 flag 전부 결합한 값
Flag : b00t2root{wh4t3v3r_17_74k3s_cuz_1_l0v3_th3_4dren4l1n3_1n_my_v31ns_932b315}
참고 자료 : http://www.1x1.jp/blog/2010/12/php_serialize_data_type.html