상세 컨텐츠

본문 제목

[xcz.kr #21] PHP Obfuscation Crack - 300 points

WebHacking/xcz.kr

by bing_su 2021. 2. 23. 18:22

본문

반응형
SMALL

xcz.kr의 21번째 문제는 PHP Obfuscation Crack이다. PHP의 난독화와 관련된 Web 문제다.

문제에서 주어진 난독화 코드다. 구글링으로 "PHP Obfuscation decode"를 검색해서 난독화를 해제했다.

관련 사이트: www.unphp.net/

 

UnPHP - The Online PHP Decoder

UnPHP easily handles simple obfuscation methods that chain functions like eval(), gzinflate(), str_rot13(), str_replace() and base64_decode() View Output

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] )

  • 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 미만

  • index 0 ) 숫자
  • index 1 ) 숫자
  • index 2 ) 
  • index 3 ) 
  • index 4 ) 숫자 X

- $a[1]: 각 자리 아스키코드 값의 합이 300 초과 326 미만

  • index 0 ) 숫자 X
  • index 1 )
  • index 2 )
  • index 3 ) 숫자
  • index 4 ) 숫자

- $a[2]: 각 자리 아스키코드 값의 합이 349 초과 407 미만

  • index 0 ) 숫자 X
  • index 1 ) 숫자

- $a[3]: 각 자리 아스키코드 값의 합이 357 초과 359 미만

  • index 0 ) 숫자 X
  • index 1 ) 숫자 X
  • index 2 ) 숫자 
  • index 3 ) 숫자
  • index 4 ) 숫자

- $a[0]부터 $a[3] 아스키코드 값 합의 평균을 반올림하면 $a[4] 아스키코드 값의 합과 같다.

이를 종합해 키 값을 GET 방식으로 전송해 플래그 값을 구할 수 있다.

반응형
LIST

'WebHacking > xcz.kr' 카테고리의 다른 글

[xcz.kr #18] Web Basic - 150 points  (0) 2021.02.23
[xcz.kr #32] Easy Trick - 100 points  (0) 2021.02.17

관련글 더보기

댓글 영역