webhacking/etc

xcz.kr 33번

qkqhxla1 2015. 3. 30. 21:36
<?
Function DecryptUID($a){
srand();
$s_vector_iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ECB), MCRYPT_RAND);
$s_key = "RED_SHOES_".ip2long($_SERVER['REMOTE_ADDR']);
$de_str = pack("H*", $a);
$out_str = mcrypt_decrypt(MCRYPT_3DES, $s_key, $de_str, MCRYPT_MODE_ECB, $s_vector_iv);
$CArray = explode("_",$out_str);
for($i = 0; $i < sizeof($CArray)-1; $i++){@$b .= chr($CArray[$i]^ (sizeof($CArray)-1) ^ 516);}
return @$b;
}
?>

라고 DecryptUID 함수가 힌트로 주어진다. 이게 뭔가 하니 qkqhxla으로 가입 후 로그인해보면 userid라는 쿠키값이 하나 주어지는데 위의 함수에서 $_SERVER['REMOTE_ADDR']; 부분을 내 아이피 주소로 바꾸고, echo DecryptUID("userid쿠키값"); 형태로 집어넣게 되면 내 아이디인 qkqhxla이 출력된다. admin페이지로 들어가보면 내가 ADMIN이 아니라고 뜬다. 그럼 쿠키값을 변경해서 ADMIN에 맞게 하면 될거라고 생각했다. 이 말뜻은 결국 저 위의 DecryptUID()에 맞는 EncryptUID()를 만들어야 한다는 소리이다.

echo DecryptUID(EncryptUID('ADMIN'));을 출력하면 ADMIN이 출력되야 한다는 소리이다.


거꾸로 코딩을 잘 하면 된다.... 요령.


decrypt의 반대로 encrypt한다. DecryptUID함수는 16진수 문자열을 받아서-> pack으로 변환한다

->mcrypt_decrypt()를 적용한다 ->_로 explode한다-> 반복문 내부에서 복잡한 xor연산을 한다.

그러면 우리가 만들 encrypt함수는.

거꾸로 raw한 문자열을 받아서 복잡한 xor연산을 한다-> _를 붙여준다 -> mcrypt_encrypt()를 한다-> pack대신 거꾸로 기능을 하는 함수를 알아서 만들어서 적용한다.-> 16진수로 잘 만들어준다.

이렇게 거꾸로 하면 된다.


설명은 간단하지만 php에 익숙하지 않고, mcrypt_decrypt실험하고 xor코드를 짜는게 빡세서 2시간 넘게 투자함...... 아래는 내가 짠 encrypt코드.

<?
Function DecryptUID($a){
srand();
$s_vector_iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ECB), MCRYPT_RAND);
$s_key = "RED_SHOES_".ip2long("내 외부 아이피 주소");
$de_str = pack("H*", $a);
$out_str = mcrypt_decrypt(MCRYPT_3DES, $s_key, $de_str, MCRYPT_MODE_ECB, $s_vector_iv);
$CArray = explode("_",$out_str);
for($i = 0; $i < sizeof($CArray)-1; $i++)
	{
		echo $i . " : " . $CArray[$i] . " " . sizeof($CArray) . "<br />";
		@$b .= chr($CArray[$i]^ (sizeof($CArray)-1) ^ 516);
	}
return @$b;
}

Function EncryptUID($a){
	srand();
	$s_vector_iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ECB), MCRYPT_RAND);
	$s_key = "RED_SHOES_".ip2long("본인 아이피 주소");

	$c = "";
	for($i = 0; $i < strlen($a); $i++)
	{
		$c .= ord($a[$i])^ strlen($a) ^ 516;
		$c .= "_";
	}
	echo $c . "<br />";

	$out_str = mcrypt_encrypt(MCRYPT_3DES, $s_key, $c, MCRYPT_MODE_ECB, $s_vector_iv);
	$b = "";
	for($i=0; $i<strlen($out_str); $i++)
		$b .= str_pad(dechex(ord($out_str[$i])),2,"0",STR_PAD_LEFT);
	return $b;
}

echo "enc = " . EncryptUID("ADMIN") . "                and " . DecryptUID(EncryptUID("ADMIN")) . "<br />";

?>

어떻게 이렇게 코딩을 하고 해당 쿠키값을 출력해보면 ADMIN의 encrypt된 쿠키값이 나와서 그걸 userid쿠키값에서 변경했는데.... admin페이지를 들어가니 비밀번호가 맞는지 확인하겠다고 한다.


admin의 비밀번호 관련해서는 딱 봐도 Profile의 비밀번호 바꾸는곳에서 바꿔야 한다.

프록시를 켜고, 아무 계정으로 로그인 후 비밀번호 바꾸는곳에서 제대로 된 비밀번호를 친다. 그러면 내가 비밀번호를 보낸 후 바뀌는 페이지로 요청이 한번 더 가는데, 그때의 쿠키값을 admin의 쿠키값으로 바꿔준다. 그다음에 아이디는 내 아이디 그대로놔두고, 비밀번호만 원하는 비밀번호로 바꾼 뒤, 캡쳐를 잘 입력해주고, 요청을 보낼때 다시 쿠키값을 admin의 쿠키값으로 바꿔주면 success!가 뜬다. 쿠키값을 다시 admin으로 바꿔준뒤 관리자페이지로 내가 바꾼 비밀번호를 입력하고 들어가면..