Webhacking.kr 6번 문제풀이

Hevton·2020년 9월 7일
0
post-custom-banner

100점짜리고, 기존 문제들에 비해 다소 난이도가 낮다. 우선 문제를 열고 view-source를 클릭해보면,

<?php
include "../../config.php";
if($_GET['view_source']) view_source();
if(!$_COOKIE['user']){
  $val_id="guest";
  $val_pw="123qwe";
  for($i=0;$i<20;$i++){
    $val_id=base64_encode($val_id);
    $val_pw=base64_encode($val_pw);
  }
  $val_id=str_replace("1","!",$val_id);
  $val_id=str_replace("2","@",$val_id);
  $val_id=str_replace("3","$",$val_id);
  $val_id=str_replace("4","^",$val_id);
  $val_id=str_replace("5","&",$val_id);
  $val_id=str_replace("6","*",$val_id);
  $val_id=str_replace("7","(",$val_id);
  $val_id=str_replace("8",")",$val_id);

  $val_pw=str_replace("1","!",$val_pw);
  $val_pw=str_replace("2","@",$val_pw);
  $val_pw=str_replace("3","$",$val_pw);
  $val_pw=str_replace("4","^",$val_pw);
  $val_pw=str_replace("5","&",$val_pw);
  $val_pw=str_replace("6","*",$val_pw);
  $val_pw=str_replace("7","(",$val_pw);
  $val_pw=str_replace("8",")",$val_pw);

  Setcookie("user",$val_id,time()+86400,"/challenge/web-06/");
  Setcookie("password",$val_pw,time()+86400,"/challenge/web-06/");
  echo("<meta http-equiv=refresh content=0>");
  exit;
}
?>
<html>
<head>
<title>Challenge 6</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }
</style>
</head>
<body>
<?php
$decode_id=$_COOKIE['user'];
$decode_pw=$_COOKIE['password'];

$decode_id=str_replace("!","1",$decode_id);
$decode_id=str_replace("@","2",$decode_id);
$decode_id=str_replace("$","3",$decode_id);
$decode_id=str_replace("^","4",$decode_id);
$decode_id=str_replace("&","5",$decode_id);
$decode_id=str_replace("*","6",$decode_id);
$decode_id=str_replace("(","7",$decode_id);
$decode_id=str_replace(")","8",$decode_id);

$decode_pw=str_replace("!","1",$decode_pw);
$decode_pw=str_replace("@","2",$decode_pw);
$decode_pw=str_replace("$","3",$decode_pw);
$decode_pw=str_replace("^","4",$decode_pw);
$decode_pw=str_replace("&","5",$decode_pw);
$decode_pw=str_replace("*","6",$decode_pw);
$decode_pw=str_replace("(","7",$decode_pw);
$decode_pw=str_replace(")","8",$decode_pw);

for($i=0;$i<20;$i++){
  $decode_id=base64_decode($decode_id);
  $decode_pw=base64_decode($decode_pw);
}

echo("<hr><a href=./?view_source=1 style=color:yellow;>view-source</a><br><br>");
echo("ID : $decode_id<br>PW : $decode_pw<hr>");

if($decode_id=="admin" && $decode_pw=="nimda"){
  solve(6);
}
?>
</body>
</html>

이런 코드가 나온다. 대강 해석해보면 user 쿠키값이 없으면 id의 guest값과 pw의 123qwe값을 20번 Base64 인코딩 한 뒤에 각각 특별한 치환작업을 해주고, 이 값을 각각 user, password 쿠키에 저장한다. 실제로 쿠키를 확인해보면 엄청나게 긴 문자열이 저장되어 있을 것이다. 그리고 이 쿠키값을 읽어들여서 다시 아까의 방식으로 디코딩 해준 뒤 이 문자들을 메인화면에 띄워준다. 그러니까 이 소스에 나온 guest, 123qwe 값은 인코딩 - 디코딩을 거쳐 다시 guest, 123qwe로 메인화면에 나오게 된 것. 그리고 아래 소스를 더 보면, 디코딩된 id 가 admin이고 pw가 nimda일 경우 문제를 해결했음을 뜻하는 함수를 호출한다. 즉 이 인코딩 방식 그대로 구현해준 뒤에 admin과 nimda 문자열을 인코딩 시켜준 후 그 값을 쿠키값에 저장해주면된다.

참고로 여기서 쓰인 인코딩 방식은 BASE64 방식이다.
BASE64방식은 인코딩 과정에서 '남은 문자열을 패딩처리'하는, 즉 부족한 bit 수를 패딩처리했다는 뜻으로 = 인코딩 값 마지막에 주로 붙어있곤 하죠. 인코딩 값 뒤에 = 가 붙어있으면 그냥 BASE64방식이라고 바로 의심해 볼 수 있습니다. 그렇다고 = 가 항상 붙는 것은 아니고, BASE64는 인코딩 과정에서 문자열을 나누고 치환하는데, 이 과정에서 부족한 bit 수를 0으로 채워 패딩처리했다는 의미로 =를 추가합니다.(=는 경우에 따라 0개~2개까지 추가됩니다.)

여튼 BASE64의 방식에 대해서 알고 있지 않아도 풀 수 있기 때문에 이정도로 넘어갑니다.. 대충 이렇다는 뜻..!
저는 문제의 암호화 방식을 java로 코드를 짰습니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Base64;

public class base64 {
    public static void main(String args[])
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        // Base64 인코더 객체 생성
        Base64.Encoder encoder = Base64.getEncoder();

        byte[] id_encode_result, pw_encode_result;

        try {
            id_encode_result = br.readLine().getBytes();
            pw_encode_result = br.readLine().getBytes();


            for(int i = 0; i < 20; i++)
            {
                id_encode_result = encoder.encode(id_encode_result);
                pw_encode_result = encoder.encode(pw_encode_result);
            }

            String id = new String(id_encode_result);
            String pw = new String(pw_encode_result);

            id = id.replace("1","!")
                    .replace("2", "@")
                    .replace("3","$")
                    .replace("4","^")
                    .replace("5","&")
                    .replace("6","*")
                    .replace("7","(")
                    .replace("8",")");

            pw = pw.replace("1","!")
                    .replace("2", "@")
                    .replace("3","$")
                    .replace("4","^")
                    .replace("5","&")
                    .replace("6","*")
                    .replace("7","(")
                    .replace("8",")");

            bw.write("id : "+id+"\n");
            bw.write("pw : "+pw+"\n");
            bw.flush(); br.close(); bw.close();

        }catch (Exception e){

        }
    }
}

요렇게 하고 admin, nimda 를 입력해주면 어마어마하게 긴 문자가 출력이 됩니다. 이걸 복사해서 쿠키값 user, password에 각각 넣어주면 끄읏.

고생하셨습니다

profile
놀만큼 놀았다.
post-custom-banner

0개의 댓글