deepble
[Webhacking.kr] challenge old-6 본문
문제
문제 링크로 들어가면 다음과 같이 소스코드를 볼 수 있는 링크와 ID : guest, PW : 123qwe가 적혀있는 것을 확인할 수 있습니다.
따라서 소스코드 페이지에 들어가면 아래와 같이 소스코드 확인이 가능합니다.
아래는 소스코드 전체를 가져온 것입니다.
<?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>
분석
(전체 코드 중에서 html코드는 중요하지 않아 분석하지 않았습니다.)
먼저 php코드가 총 2개가 있는 것을 확인할 수 있습니다. 따라서 먼저 첫번째 php 코드를 분석하겠습니다.
첫 번째 PHP 코드
include "../../config.php";
config.php라는 외부 파일을 포함하고 있습니다. webhacking.kr 문제들 소스코드를 보면 많이 등장하므로 여기에 함수나 전역변수 등등이 담겨져있는 것 같습니다. (중요하지 않음)
if($_GET['view_source']) view_source();
GET에 view_source가 있을 경우 view_source()함수를 호출합니다. 해당 페이지에 소스코드를 보여주는 기능인 것 같습니다.
if(!$_COOKIE['user']){
if 조건문에 user라는 쿠키가 없을 때 아래의 if문들을 실행합니다.
$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 변수에는 'guest'를 val_pw 변수에는 '123qwe'로 설정합니다.
이후 for문을 이용하여 각각의 변수들을 base64로 20번 인코딩을 진행합니다.
$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);
인코딩 된 값들을 각각 1은 !, 2는 @, 3은 $, 4는 ^, 5는 &, 6은 *, 7은 (, 8은 )로 치환해줍니다.
Setcookie("user",$val_id,time()+86400,"/challenge/web-06/");
Setcookie("password",$val_pw,time()+86400,"/challenge/web-06/");
위에 과정을 거친(인코딩과 문자치환) val_id와 val_pw 변수를 각각 user와 password 쿠키 값으로 설정해줍니다. 또한 쿠키의 만료를 86400초로 설정하고, 쿠키 경로는 /challenge/web-06/으로 설정합니다.
echo("<meta http-equiv=refresh content=0>");
exit;
}
이후 meta태그를 이용하여 페이지를 새로고침 해줍니다. 쿠키 변경을 바로 적용하기 위함으로 보입니다.
두 번째 PHP 코드
$decode_id=$_COOKIE['user'];
$decode_pw=$_COOKIE['password'];
먼저 user와 password 쿠키에서 값을 가져온 후 각각을 decode_id와 decode_pw 변수에 저장합니다.
(첫 번째 소스코드에서 분석했을 때, user과 password쿠키는 각각 'guest'와 '123qwe'가 인코딩과 치환 후 저장된 쿠키입니다.)
$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);
decode_id와 decode_ pw 각각에서 특수문자를 숫자로 변경해주는 작업을 합니다.
(이 과정을 볼 때, 첫 번째 php 코드와 반대로 진행하는 것 같다고 느낄 수 있습니다.)
for($i=0;$i<20;$i++){
$decode_id=base64_decode($decode_id);
$decode_pw=base64_decode($decode_pw);
}
치환을 완료한 decode_id와 decode_ pw를 base64로 20번 디코딩을 진행합니다.
echo("<hr><a href=./?view_source=1 style=color:yellow;>view-source</a><br><br>");
echo("ID : $decode_id<br>PW : $decode_pw<hr>");
echo를 이용하여 화면에 view-source코드에 하이퍼링크를 걸어 ./?view_source=1로 이동할 수 있도록 출력하고 있습니다. 또한 ID : (decode_id에 저장된 값) 와 PW : (decode_pw에 저장된 값) 을 출력합니다. 따라서 첫번째 화면에서 보인 글자들이 각각 이러한 과정들을 거쳐 출력된 것이라 알 수 있습니다.
if($decode_id=="admin" && $decode_pw=="nimda"){
solve(6);
}
만약 decode_id가 admin이고, decode_pw가 nimda 일때, solve(6)함수를 출력하도록 합니다. 따라서 id와 pw가 각각 admin, nimda가 된다면 문제를 풀 수 있습니다.
분석정리
- 문제 사이트에 접속하면 'guest'와 '123qwe'를 id와 pw로 설정하여 [base64인코딩 20번 후 숫자를 문자로 치환]한 값을 'user', 'password'라는 쿠키로 설정합니다.
- 다음으로 사이트에서 'user'과 'password' 쿠키값을 가져와 [문자를 숫자로 치환한 후 base64디코딩 20번]한 값을 사이트 화면에 보이도록 설정합니다. 또한 변경된 값이 각각 admin과 nimda일 경우 문제가 풀립니다.
- 따라서 'user'과 'password' 쿠키값을 [문자를 숫자로 치환한 후 base64디코딩 20번]한 결과가 admin과 nimda여야 합니다.
- 그러면 admin과 nimda를 각각 [base64인코딩 20번 후 숫자를 문자로 치환]한 값을 사이트에 쿠키값으로 넣어 쿠키값 변조를 하면 문제가 풀리게 됩니다.
준비
1. EditThisCookie
먼저 문제를 풀기 위해 아래의 크롬 쿠키 관리자를 설치해야합니다.
https://chromewebstore.google.com/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg
EditThisCookie
EditThisCookie는 쿠키 관리자입니다. 이것을 이용하여 쿠키를 추가하고, 삭제하고, 편집하고, 찾고, 보호하거나 막을 수 있습니다!
chromewebstore.google.com
풀이
초기 쿠키값 확인
'user'와 'password'쿠키값을 각각 확인해보면 다음과 같습니다. 각 값이 의미는 guest와 123qwe를 base64 인코딩 20번 후 숫자를 문자로 치환한 값입니다.
파이썬 코드작성
분석정리 마지막에 말한 것 처럼 'admin'과 'nimda'를 각각 base64 인코딩 20번 후 숫자를 문자로 치환한 값을 쿠키값에 넣어야합니다. 따라서 아래의 파이썬 코드를 작성하여 각각 값을 id와 pw로 출력합니다. 설명은 아래와 같습니다.
1. base64인코딩을 위해 코드 처음부분에 포함해줍니다.
2. id와 pw 변수에 각각 admin과 nimda를 할당합니다.
3. for문을 이용하여 id와 pw 각각 20번 base64인코딩을 진행합니다. 여기서 .encode()는 문자열을 바이너리 형태로 변환하여 base64.b64encode로 base64인코딩을 합니다. 마지막으로 이 값을 .decode()를 이용하여 인코딩된 바이너리를 문자열로 변환해줍니다.
4. replace_cahrs는 숫자를 문자로 치환하는 함수로써 s를 입력받아 replacements에 규칙에 맞춰 문자열이 치환되는 규칙입니다.
5. id_replaced와 pw_replaced 변수에 각각 치환된 id와 pw 값을 저장해줍니다.
6. 마지막으로 id_replaced와 pw_replaced 값을 print해줍니다.
import base64
id = "admin"
pw = "nimda"
for _ in range(20):
id = base64.b64encode(id.encode()).decode()
pw = base64.b64encode(pw.encode()).decode()
def replace_chars(s):
replacements = {
"1": "!",
"2": "@",
"3": "$",
"4": "^",
"5": "&",
"6": "*",
"7": "(",
"8": ")"
}
for original, replacement in replacements.items():
s = s.replace(original, replacement)
return s
id_replaced = replace_chars(id)
pw_replaced = replace_chars(pw)
print("ID :", id_replaced)
print("PW :", pw_replaced)
파이썬 코드 결과값
쿠키 값 변경
앞에서 구한 값들을 각각 user와 password 쿠키에 넣어서 초록색 체크버튼을 누른 후 새로고침을 진행합니다.
그러면 문제가 풀리게 되고, 해당 사이트에 다시 들어가게 된다면 화면이 기존 ID, PW 값과 다르게 나타나는 것을 확인할 수 있습니다.
문제 완료 후 화면
'CTF > Webhacking.kr' 카테고리의 다른 글
[Webhacking.kr] challenge old-17 (0) | 2024.06.21 |
---|---|
[Webhacking.kr] challenge g00gle1 (0) | 2024.04.05 |
[Webhacking.kr] challenge old-3 (0) | 2024.04.02 |
[Webhacking.kr] challenge old-2 (0) | 2024.03.27 |
[Webhacking.kr] challenge old-1 (0) | 2024.03.27 |