xcz.kr의 21번째 문제는 PHP Obfuscation Crack이다. PHP의 난독화와 관련된 Web 문제다.
문제에서 주어진 난독화 코드다. 구글링으로 "PHP Obfuscation decode"를 검색해서 난독화를 해제했다.
관련 사이트: www.unphp.net/
난독화된 부분도 정리가 안 되어 있어서 일단 개행에 맞도록 정리를 했다.
<?
${"GLOBALS"}["gasyarknd"]="b";
${"GLOBALS"}["rwliiiqfvfp"]="i";
function h($a)
{
${"GLOBALS"}["pxzweahruqok"]="b";
${${"GLOBALS"}["pxzweahruqok"]}="";
${"GLOBALS"}["uxoiiikapcv"]="b";
for(${${"GLOBALS"}["rwliiiqfvfp"]}=0;${${"GLOBALS"}["rwliiiqfvfp"]}<5;${${"GLOBALS"}["rwliiiqfvfp"]}++) {
$ydzorvqk="a";
$gflrozo="b";
${"GLOBALS"}["erpxzozdey"]="i";
${$gflrozo}=${${"GLOBALS"}["gasyarknd"]}+ord(substr(${$ydzorvqk},${${"GLOBALS"}["erpxzozdey"]},1));
}
return${${"GLOBALS"}["uxoiiikapcv"]};
}
$jbojdbertutk="KEY";
$vtefigaylx="mun";
${"GLOBALS"}["hpceeyxto"]="a";
$ktjmdjm="a";
${"GLOBALS"}["mimtemucybpc"]="mun";
${$jbojdbertutk}="Congratulations!</br>Key is ?????????????????????";
${"GLOBALS"}["gmfifbfl"]="a";
${${"GLOBALS"}["mimtemucybpc"]}=@$_GET["key"];
${"GLOBALS"}["wvdcxsdsqb"]="x";
@${$ktjmdjm}=explode("-",${$vtefigaylx});
$gfxqkfxurga="x";
$dlmordkk="a";
for(${${"GLOBALS"}["wvdcxsdsqb"]}=0;${${"GLOBALS"}["wvdcxsdsqb"]}<5;${$gfxqkfxurga}++) {
if(preg_match("/[^a-zA-Z0-9]/",@${${"GLOBALS"}["hpceeyxto"]}[${${"GLOBALS"}["wvdcxsdsqb"]}])) {
exit("Error!");
}
}
if(is_numeric(substr(${${"GLOBALS"}["hpceeyxto"]}[0],0,2))&&!is_numeric(substr(${${"GLOBALS"}["hpceeyxto"]}[0],4,1))&&h(${${"GLOBALS"}["gmfifbfl"]}[0])>312&&h(${${"GLOBALS"}["hpceeyxto"]}[0])<333&&!is_numeric(substr(${$dlmordkk}[1],0,1))&&is_numeric(substr(${${"GLOBALS"}["hpceeyxto"]}[1],3,2))) {
$qcpkjlbgy="a";
${"GLOBALS"}["oqotjbvn"]="a";
${"GLOBALS"}["bbghzot"]="a";
if(h(${${"GLOBALS"}["bbghzot"]}[1])>300&&h(${$qcpkjlbgy}[1])<326&&!is_numeric(substr(${${"GLOBALS"}["hpceeyxto"]}[2],0,1))&&is_numeric(substr(${${"GLOBALS"}["hpceeyxto"]}[2],1,1))&&h(${${"GLOBALS"}["oqotjbvn"]}[2])>349&&h(${${"GLOBALS"}["hpceeyxto"]}[2])<407) {
${"GLOBALS"}["wsjuxwxbzms"]="a";
${"GLOBALS"}["ofvmiatcdko"]="a";
$oqhejquzit="a";
if(!is_numeric(substr(${${"GLOBALS"}["wsjuxwxbzms"]}[3],0,2))&&is_numeric(substr(${$oqhejquzit}[3],2,3))&&h(${${"GLOBALS"}["ofvmiatcdko"]}[3])>357&&h(${${"GLOBALS"}["hpceeyxto"]}[3])<359) {
${"GLOBALS"}["erqqjpct"]="a";
${"GLOBALS"}["okgondfidky"]="a";
if(round((h(${${"GLOBALS"}["hpceeyxto"]}[0])+h(${${"GLOBALS"}["okgondfidky"]}[1])+h(${${"GLOBALS"}["hpceeyxto"]}[2])+h(${${"GLOBALS"}["hpceeyxto"]}[3]))/4)==h(${${"GLOBALS"}["erqqjpct"]}[4])) {
$oaqqkxn="KEY";
exit(${$oaqqkxn});
}
}
}
} echo"Wrong T.T";
?>
하지만 정리를 해도 변수도 복잡하고, 중복되는 부분도 있어서 다시 정리를 했다.
<?
function h($a)
{
$b = "";
for($i = 0; $i < 5; $i++) {
$b = $b + ord(substr($a,$i,1));
}
return$b;
}
$KEY = "Congratulations!</br>Key is ?????????????????????";
$mun = @$_GET["key"];
@$a = explode("-",$mun);
for($x = 0; $x<5; $x++) {
if(preg_match("/[^a-zA-Z0-9]/",@$a[$x])) {
exit("Error!");
}
}
if(is_numeric(substr($a[0],0,2)) && !is_numeric(substr($a[0],4,1)) && h($a[0]) > 312 && h($a[0]) < 333 && !is_numeric(substr($a[1],0,1)) && is_numeric(substr($a[1],3,2))) {
if(h($a[1]) > 300 && h($a[1]) < 326 && !is_numeric(substr($a[2],0,1)) && is_numeric(substr($a[2],1,1)) && h($a[2]) > 349 && h($a[2]) < 407) {
if(!is_numeric(substr($a[3],0,2)) && is_numeric(substr($a[3],2,3)) && h($a[3]) > 357 && h($a[3]) < 359) {
if(round((h($a[0]) + h($a[1]) + h($a[2]) + h($a[3])) / 4) == h($a[4])) {
exit($KEY);
}
}
}
} echo"Wrong T.T";
?>
최종적으로 정리된 코드다. 이를 분석하자.
function h($a)
{
$b = "";
for($i = 0; $i < 5; $i++) {
$b = $b + ord(substr($a,$i,1));
}
return$b;
}
h 함수다. 문자열을 입력받고 인덱스 0부터 4까지 문자의 아스키코드 값을 차례로 한 글자씩 넣고 이를 더하고 있다.
$mun = @$_GET["key"];
@$a = explode("-",$mun);
GET 방식으로 key 값이 입력되고, 키 값이 explode 함수로 인해 '-'를 기준으로 분할되어 $a에 배열 형태로 저장된다. 아래의 설명은 explode() 함수에 대한 것이다. 궁금하신 분들은 열어보길 바란다.
explode( delimiter, string [, limit] )
for($x = 0; $x<5; $x++) {
if(preg_match("/[^a-zA-Z0-9]/",@$a[$x])) {
exit("Error!");
}
}
preg_match 함수에 의해 우리가 입력받는 키 값은 영어 대소문자, 숫자로 이루어져야 함을 알 수 있다.
if(is_numeric(substr($a[0],0,2)) && !is_numeric(substr($a[0],4,1)) && h($a[0]) > 312 && h($a[0]) < 333 && !is_numeric(substr($a[1],0,1)) && is_numeric(substr($a[1],3,2))) {
if(h($a[1]) > 300 && h($a[1]) < 326 && !is_numeric(substr($a[2],0,1)) && is_numeric(substr($a[2],1,1)) && h($a[2]) > 349 && h($a[2]) < 407) {
if(!is_numeric(substr($a[3],0,2)) && is_numeric(substr($a[3],2,3)) && h($a[3]) > 357 && h($a[3]) < 359) {
if(round((h($a[0]) + h($a[1]) + h($a[2]) + h($a[3])) / 4) == h($a[4])) {
exit($KEY);
}
}
}
} echo"Wrong T.T";
- $a[0]: 각 자리 아스키코드 값의 합이 312 초과 333 미만
- $a[1]: 각 자리 아스키코드 값의 합이 300 초과 326 미만
- $a[2]: 각 자리 아스키코드 값의 합이 349 초과 407 미만
- $a[3]: 각 자리 아스키코드 값의 합이 357 초과 359 미만
- $a[0]부터 $a[3] 아스키코드 값 합의 평균을 반올림하면 $a[4] 아스키코드 값의 합과 같다.
이를 종합해 키 값을 GET 방식으로 전송해 플래그 값을 구할 수 있다.
[xcz.kr #18] Web Basic - 150 points (0) | 2021.02.23 |
---|---|
[xcz.kr #32] Easy Trick - 100 points (0) | 2021.02.17 |
댓글 영역