HackChang

[xcz.kr] Prob21 21번 문제 풀이 본문

W4RG4M3/W3B

[xcz.kr] Prob21 21번 문제 풀이

HackChang 2020. 7. 23. 20:00

Prob21

<html>
<head>
<link rel="shortcut icon" href="../images/favicon.ico" type="image/x-icon">
<title>Prob21</title>
</head>
<body style="background-image:url('../images/content-tail.gif');">
<b>Title</b></br>
<i>PHP Obfuscation Crack</i></br></br>
<b>Description</b></br>
<font size="2px">
<a href="prob_files/prob21.html" target="_blank">View source</a></br></br>
<?
${"\x47\x4c\x4f\x42\x41\x4c\x53"}["\x67\x61\x73y\x61\x72\x6b\x6e\x64"]="\x62";${"\x47\x4c\x4f\x42AL\x53"}["r\x77\x6cii\x69\x71\x66\x76\x66\x70"]="i";function h($a){${"\x47\x4cO\x42\x41L\x53"}["\x70x\x7a\x77\x65\x61h\x72\x75\x71\x6f\x6b"]="\x62";${${"\x47LO\x42\x41\x4c\x53"}["\x70\x78z\x77\x65\x61\x68\x72u\x71\x6f\x6b"]}="";${"GL\x4fB\x41\x4c\x53"}["u\x78\x6fi\x69i\x6b\x61pcv"]="\x62";for(${${"\x47\x4c\x4f\x42A\x4c\x53"}["r\x77\x6c\x69\x69i\x71\x66\x76fp"]}=0;${${"\x47\x4c\x4f\x42A\x4cS"}["\x72\x77l\x69i\x69\x71\x66\x76\x66\x70"]}<5;${${"G\x4c\x4f\x42\x41\x4c\x53"}["\x72\x77\x6ci\x69\x69qf\x76\x66\x70"]}++){$ydzorvqk="\x61";$gflrozo="\x62";${"\x47\x4cOB\x41\x4cS"}["\x65\x72p\x78\x7a\x6fz\x64\x65y"]="i";${$gflrozo}=${${"G\x4c\x4f\x42AL\x53"}["\x67\x61sy\x61\x72k\x6e\x64"]}+ord(substr(${$ydzorvqk},${${"\x47\x4c\x4f\x42ALS"}["\x65rp\x78\x7a\x6fz\x64e\x79"]},1));}return${${"\x47\x4c\x4fBA\x4cS"}["\x75x\x6fi\x69i\x6b\x61\x70\x63v"]};}$jbojdbertutk="\x4b\x45\x59";$vtefigaylx="mu\x6e";${"G\x4cOB\x41L\x53"}["\x68p\x63eeyx\x74o"]="\x61";$ktjmdjm="a";${"\x47\x4c\x4f\x42ALS"}["\x6d\x69mt\x65\x6du\x63\x79\x62\x70c"]="\x6d\x75\x6e";${$jbojdbertutk}="\x43o\x6e\x67\x72a\x74\x75\x6ca\x74\x69\x6f\x6es\x21</\x62r\x3e\x4be\x79\x20i\x73 ?????????????????????";${"GL\x4f\x42\x41\x4cS"}["\x67\x6d\x66i\x66\x62f\x6c"]="\x61";${${"G\x4c\x4f\x42AL\x53"}["\x6d\x69\x6d\x74em\x75c\x79\x62p\x63"]}=@$_GET["\x6b\x65y"];${"GL\x4f\x42A\x4c\x53"}["w\x76d\x63\x78\x73\x64\x73\x71b"]="x";@${$ktjmdjm}=explode("-",${$vtefigaylx});$gfxqkfxurga="\x78";$dlmordkk="\x61";for(${${"\x47\x4c\x4fBA\x4cS"}["w\x76\x64\x63\x78\x73\x64\x73\x71b"]}=0;${${"\x47\x4c\x4f\x42\x41LS"}["\x77v\x64\x63\x78s\x64\x73\x71\x62"]}<5;${$gfxqkfxurga}++){if(preg_match("/[^a-\x7a\x41-\x5a\x30-\x39]/",@${${"\x47\x4cOB\x41\x4c\x53"}["\x68pc\x65e\x79\x78\x74\x6f"]}[${${"\x47\x4cO\x42A\x4c\x53"}["\x77vd\x63\x78\x73ds\x71\x62"]}])){exit("\x45rr\x6f\x72!");}}if(is_numeric(substr(${${"\x47LO\x42\x41\x4c\x53"}["\x68p\x63e\x65y\x78to"]}[0],0,2))&&!is_numeric(substr(${${"\x47\x4c\x4f\x42\x41\x4cS"}["\x68\x70\x63ee\x79\x78t\x6f"]}[0],4,1))&&h(${${"\x47\x4c\x4f\x42\x41\x4c\x53"}["gm\x66\x69fbfl"]}[0])>312&&h(${${"\x47L\x4f\x42A\x4cS"}["h\x70\x63e\x65yx\x74\x6f"]}[0])<333&&!is_numeric(substr(${$dlmordkk}[1],0,1))&&is_numeric(substr(${${"\x47\x4c\x4fB\x41LS"}["hpc\x65ey\x78to"]}[1],3,2))){$qcpkjlbgy="\x61";${"G\x4c\x4f\x42\x41\x4c\x53"}["\x6f\x71\x6f\x74\x6a\x62\x76\x6e"]="\x61";${"G\x4cO\x42ALS"}["bb\x67h\x7a\x6f\x74"]="\x61";if(h(${${"\x47\x4c\x4f\x42\x41LS"}["b\x62g\x68z\x6ft"]}[1])>300&&h(${$qcpkjlbgy}[1])<326&&!is_numeric(substr(${${"GL\x4f\x42\x41\x4c\x53"}["hp\x63\x65\x65yx\x74o"]}[2],0,1))&&is_numeric(substr(${${"\x47LO\x42AL\x53"}["\x68\x70c\x65e\x79xt\x6f"]}[2],1,1))&&h(${${"GLO\x42\x41L\x53"}["o\x71o\x74\x6a\x62\x76n"]}[2])>349&&h(${${"\x47\x4c\x4fB\x41\x4cS"}["h\x70c\x65\x65\x79x\x74o"]}[2])<407){${"\x47L\x4fBA\x4cS"}["\x77\x73ju\x78\x77\x78bz\x6d\x73"]="\x61";${"\x47\x4cOB\x41\x4c\x53"}["o\x66\x76\x6d\x69\x61\x74\x63\x64ko"]="a";$oqhejquzit="a";if(!is_numeric(substr(${${"G\x4c\x4fBA\x4cS"}["\x77\x73\x6au\x78\x77\x78bz\x6d\x73"]}[3],0,2))&&is_numeric(substr(${$oqhejquzit}[3],2,3))&&h(${${"GL\x4f\x42\x41\x4c\x53"}["o\x66\x76\x6di\x61\x74\x63\x64\x6b\x6f"]}[3])>357&&h(${${"\x47\x4c\x4fBA\x4cS"}["hp\x63\x65ey\x78\x74\x6f"]}[3])<359){${"G\x4c\x4f\x42\x41L\x53"}["\x65rq\x71jp\x63t"]="\x61";${"G\x4c\x4fBAL\x53"}["ok\x67\x6f\x6e\x64\x66\x69\x64\x6b\x79"]="\x61";if(round((h(${${"G\x4c\x4f\x42A\x4c\x53"}["\x68\x70c\x65\x65y\x78t\x6f"]}[0])+h(${${"\x47\x4c\x4f\x42\x41L\x53"}["\x6fkg\x6f\x6ed\x66\x69\x64\x6b\x79"]}[1])+h(${${"\x47\x4c\x4f\x42AL\x53"}["h\x70c\x65e\x79\x78\x74\x6f"]}[2])+h(${${"\x47L\x4f\x42A\x4cS"}["h\x70\x63e\x65\x79\x78\x74o"]}[3]))/4)==h(${${"\x47L\x4f\x42ALS"}["\x65\x72\x71\x71\x6a\x70ct"]}[4])){$oaqqkxn="\x4b\x45\x59";exit(${$oaqqkxn});}}}}echo"\x57\x72ong\x20\x54.T";
?>
</font>
</body>
</html>

이번 문제는 php난독화를 푸는 문제인 것 같다.

아래 소스보기를 누르면 아래와 같은 소스가 나온다.

해당 인코딩을 우선 바꿔보도록 하겠다.

 

https://www.percederberg.net/tools/text_converter.html

 

swiss converter tool | percederberg.net

Quick encoding, decoding, escaping & unescaping of UTF-8, base64, hexadecimal, JSON, quoted-printable, HTTP POST, XML and more.

www.percederberg.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"}["hpchpceeyxto"]}[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";
?>

나름 깔끔하게 정리가 됐다.

소스분석은 아래 접은글에서 하도록 하겠다.

더보기

함수 h는 문자 5개를 아스키코드로 변환해서 더한다.

GET방식으로 key를 받고, 이 값을 mun이라는 변수에 넣는다.

여기서 mun의 변수에 들어있는 값을 -를 기준으로 잘라 a변수에 넣는다.

 

다음 반복문에서는 5번을 반복하면서 a라는 변수에 숫자나 문자인 것만 담겨진다.

 

그 후 아래 조건문을 만족해야 키 값을 알 수 있게 되는데

 

첫 번째 조건문

 

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

 

첫 번째는 a[0]의 첫 번째 글자와 두 번째 글자는 숫자여야한다.

두 번째는 a[0]의 다섯 번째 글자는 문자여야한다.

세 번째, 네 번째 는 a[0]의 값은 312보다 크며, 333보다는 작아야한다.

다섯 번째는 a[1]의 첫 번째 글자가 문자여야한다. 

여섯 번째는 a[1]의 네 번째 글자와 다섯 번째 글자는 숫자여야한다.

 

두 번째 조건문

 

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

 

첫 번째, 두 번째는 a[1]의 값은 300보다 크며, 326보다는 작아야한다.

세 번째는 a[2]의 첫 번째 글자는 문자여야한다.

네 번째는 a[2]의 두 번째 글자는 숫자여야한다.

다섯 번째는 a[2]의 값은 349보다 크며, 407보다 작아야한다.

 

세 번째 조건문 

 

if(!is_numeric(substr($a[3],0,2)) && is_numeric(substr($a[3],2,3)) && h($a[3])>357 && h($a[3])<359){

 

첫 번째는 a[3]의 첫 번째 글자와 두 번째 글자는 문자여야한다.

두 번째는 a[3]의 세 번째 글자 ~ 다섯 번째 글자는 숫자여야한다.

세 번째, 네 번째는 a[3]의 값은 357보다 크고, 359보다 작다.

 

네 번째 조건문

 

if(round((h($a[0])+h($a[1])+h($a[2])+h($a[3]))/4) == h($a[4])){

 

원소(a[0]~a[3](아스키) 합의 평균(/4)이 a[4]의 값(아스키)가 같아야 한다. 

분석을 바탕으로 글자를 생각해보면 다음과 같다.

 

a[0] 0~9 0~9 ? ? a~Z 312 < a[0] < 333
a[1] a~Z ? ? 0~9 0~9 300 < a[1] < 326
a[2] a~Z 0~9 ? ? ? 349 < a[2] < 407
a[3] a~Z a~Z 0~9 0~9 0~9 357 < a[3] < 359
round(a[0]+a[1]+a[2]+a[3]) / 4 == a[4]

0 - 48 , Z - 90

 

'11111' 일경우 245가 나온다.

 

29a1A-d1859-h9x79-aa776-a332a 라는 문자를 만들었고,

인증을 해서 클리어를 했다.

Comments