• 문제경로
  • 문제풀이

 

 

 

[문제경로]

https://webhacking.kr/challenge/web-11/

 

Challenge 26

 

webhacking.kr

 

 

 

[문제풀이]

문제에 접속하면 view-source라는 하이퍼링크가 있어서

source code를 확인했다.

 

 

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 26</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }    
a { color:lightgreen; }
</style>
</head>
<body>
<?php
// 만약 id에 "admin"이라는 문자열이 포함되어 있다면 "no!"를 출력하고 스크립트를 종료한다.
  if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); }
// 그렇지 않으면, id를 URL 디코딩한다.
  $_GET['id'] = urldecode($_GET['id']);
// 만약 id가 "admin"과 정확히 일치한다면 solve(26) 함수를 호출한다.
  if($_GET['id'] == "admin"){
    solve(26);
  }
?>
<br><br>
<a href=?view_source=1>view-source</a>
</body>
</html>

사용자로부터 'id'라는 GET 매개변수를 받아와

id에 'admin'이라는 문자열이 포함되어 있으면

"no"를 출력하고 종료된다.

그렇지 않은 경우에는 'id'를 url 디코딩하고

"admin" 문자열과 비교하여 일치하면

solve(26) 함수를 호출하며

문제가 풀리는 구조이다.

 

즉 "admin"이라는 문자열을 url 인코딩해서 'id' 값으로 집어넣으면

url 디코딩 되며 "admin"과 일치하여 문제가 해결될 것이다. 

 

 

url 인코딩 표를 참조해서

"admin"이라는 문자열을 다음과 같이 인코딩했다.

"%61%64%6d%69%6e"

 

 

url 인코딩한 값을 id에 넣어 전송했지만

"no!"라고 화면에 표시된다.

 

 

"%61%64%6d%69%6e" 이 문자열이

처음부터 "admin"으로 인식되는 것이니

다음과 같이 한 번 더 인코딩을 해서 id 값에 집어넣었다.

"%25%36%31%25%36%34%25%36%64%25%36%39%25%36%65"

문제가 해결되었다.

 

 

 

 

Reference:

https://www.eso.org/~ndelmott/url_encode.html

'Wargame & CTF > Webhacking.kr' 카테고리의 다른 글

[Webhacking.kr] old-10  (0) 2024.04.13
[Webhacking.kr] old-06  (0) 2024.04.10
[Webhacking.kr] old-16  (0) 2023.09.22
[Webhacking.kr] old-15  (0) 2023.09.17
[Webhacking.kr] old-17  (0) 2023.09.17
  • 문제경로
  • 문제풀이

 

 

 

[문제경로]

https://webhacking.kr/challenge/web-06/

 

https://webhacking.kr/challenge/web-06/

 

webhacking.kr

 

 

 

[문제풀이]

문제 페이지에 접속하면

기본으로 설정된 ID, PW와 view-source 하이퍼링크를 볼 수 있다.

 

 

<?php
include "../../config.php";
if($_GET['view_source']) view_source();

// 만약 사용자 쿠키가 설정되지 않았다면, id와 pw가 default 값으로 설정된다.
if(!$_COOKIE['user']){
  $val_id="guest";
  $val_pw="123qwe";
  
  // id와 pw를 20번씩 base64로 인코딩한다.
  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
// 쿠키로부터 id와 pw를 디코딩한다.
$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);

// id와 pw를 base64로 20번 디코딩한다.
for($i=0;$i<20;$i++){
  $decode_id=base64_decode($decode_id);
  $decode_pw=base64_decode($decode_pw);
}

// 사용자의 id와 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>");

// 디코딩된 id와 pw가 "admin", "nimda"와 일치한다면 solve(6) 함수를 호출한다.
if($decode_id=="admin" && $decode_pw=="nimda"){
  solve(6);
}
?>
</body>
</html>

view-source 하이퍼링크를 클릭해서 code를 확인했다.

 

코드를 해석해 보면 

사용자 쿠키가 설정되지 않았기에

id와 pw가 "guest", "123qwe"으로 설정되고

20번 base64 인코딩 및 특정 문자로 치환하는 과정을 거쳐서 

쿠키값으로 들어오게 된다.

그리고 다시 반대로 쿠키값을 숫자로 치환하고

20번 디코딩하는 과정을 거쳐

문제 페이지에 이를("guest", "123qwe") 출력하고 있음을 알 수 있다.

마지막에는 id와 pw의 값이 "admin", "nimda"와 일치하는지 확인하여

일치한다면 solve(6) 함수를 호출해 문제가 해결되는 것처럼 보인다. 

 

즉 문제를 해결하기 위해서는 id와 pw의 값에 "admin", "nimda"가 들어가면 될 것 같다.

이를 20번 인코딩, 치환 과정을 거쳐서 쿠키에 집어넣어 보자

 

 

// admin 인코딩 및 치환
var a = 'admin';
for (var i = 0; i < 20; i++) {
    a = btoa(a);
}
a = a.replaceAll('1', '!');
a = a.replaceAll('2', '@');
a = a.replaceAll('3', '$');
a = a.replaceAll('4', '^');
a = a.replaceAll('5', '&');
a = a.replaceAll('6', '*');
a = a.replaceAll('7', '(');
a = a.replaceAll('8', ')');
// nimda 인코딩 및 치환
var a = 'nimda';
for (var i = 0; i < 20; i++) {
    a = btoa(a);
}
a = a.replaceAll('1', '!');
a = a.replaceAll('2', '@');
a = a.replaceAll('3', '$');
a = a.replaceAll('4', '^');
a = a.replaceAll('5', '&');
a = a.replaceAll('6', '*');
a = a.replaceAll('7', '(');
a = a.replaceAll('8', ')');

id와 pw의 값을 온라인 base64 도구를 이용해

20번 수작업으로 인코딩하고 값을 치환할 수 있겠지만

힘든 작업이기에 이 과정을 수행하여 출력하는 javascript 코드를 짜보았다. 

 

 

개발자 도구의 콘솔창에서

javascript 코드를 실행하여

결과 값이 출력되었다.

 

 

해당 값을 개발자 도구의

쿠키 설정 부분에 입력했다.

 

 

그리고 문제 페이지를 새로고침 했더니

문제가 해결되었다.

'Wargame & CTF > Webhacking.kr' 카테고리의 다른 글

[Webhacking.kr] old-10  (0) 2024.04.13
[Webhacking.kr] old-26  (0) 2024.04.13
[Webhacking.kr] old-16  (0) 2023.09.22
[Webhacking.kr] old-15  (0) 2023.09.17
[Webhacking.kr] old-17  (0) 2023.09.17

+ Recent posts