xcz.kr의 18번째 문제는 Web Basic이다. 이름에서도 알 수 있듯이 Web 문제다.
문제 화면에서는 별 다른 설명 없이 페이지 소스를 보도록 되어 있어서 페이지 소스를 살펴봤다.
이를 살펴보면 변수명이 I, i로 이루어진 복잡한 문자열이다. 따라서 익숙한 변수로 치환해서 코드를 다시 작성했다.
<?
$key = "Congratulations!</br>Key is ??????????????????";
$cookie = @$_COOKIE['c'];
$G = @$_GET['g'];
$P = @$_POST['p'];
if(empty($cookie) || empty($G) || empty($P)){exit ('wrong T.T');}
$A = $G . $cookie;
$B = $P;
function test($a){
$b = '';
for($i=0; $i < strlen($a); $i++){
$b = $b . ' - ' . ord(substr($a,$i,1));
}
return $b;
}
if(test($A)==" - 103 - 105 - 118 - 101 - 109 - 101 - 112 - 97 - 115 - 115 - 119 - 111 - 114 - 100" || test($B) == " - 107 - 101 - 121 - 112 - 108 - 122 - 33"){
echo $key;
}
else{
echo 'wrong T.T';
}
?>
이제 동작하는 방식과 어떻게 키를 얻어낼 수 있는지 살펴보자.
c 값을 쿠키에서 받아와서 $cookie 변수에 저장된다.
$cookie = @$_COOKIE['c'];
GET 방식으로 g를 받고, $G에 대입한다.
$G = @$_GET['g'];
POST 방식으로 p를 받고, $P에 대입한다.
$P = @$_POST['p'];
만약 변수 $cookie, $G, $P 중 하나라도 비어있으면 에러 문구가 뜨면서 실행이 멈춘다.
if(empty($cookie) || empty($G) || empty($P)){exit ('wrong T.T');}
GET 방식으로 받은 g의 값과 cookie 변수의 값을 이은 문자열이 변수 $A에 저장된다.
(여기서 '.'은 문자열 연결 연산자로, 문자열들을 붙여서 하나로 연결하는 역할을 한다.)
$A = $G . $cookie;
POST 방식으로 받은 p가 변수 $B에 저장된다.
$B = $P;
먼저, substr()은 문자열의 일부분을 추출하는 함수이다. substr(string, start, [length]) 형식으로 사용한다. string은 추출할 문자열을 뜻하고, start는 추출 시작 위치, length는 추출할 문자의 개수를 의미한다. (이때 length 값이 없으면 문자열의 끝까지 추출한다.) ord() 함수는 문자의 ASCII 코드 값을 추출하는 함수다.
이를 종합하면 test 함수의 인자로 받은 문자열을 한 글자씩 ASCII 값을 구하고, '-'로 이어붙인다고 할 수 있다. 그리고 이렇게 이어 붙인 문자열이 변수 $b에 저장되며 반환된다고 할 수 있다.
function test($a){
$b = '';
for($i=0; $i < strlen($a); $i++){
$b = $b . ' - ' . ord(substr($a,$i,1));
}
return $b;
}
$A의 값은 "givemepassword", $B의 값은 "keyplz!"여야 키 값을 준다.
if(test($A)==" - 103 - 105 - 118 - 101 - 109 - 101 - 112 - 97 - 115 - 115 - 119 - 111 - 114 - 100" || test($B) == " - 107 - 101 - 121 - 112 - 108 - 122 - 33"){
echo $key;
}
else{
echo 'wrong T.T';
}
Tip) 메모장에서 NumLock 키를 킨 상태에서 alt를 누르고 오른쪽의 넘버패드를 이용해 알고 싶은 아스키코드 값을 적고 alt를 떼면 원하는 아스키코드에 맞는 문자가 출력된다. Ex) alt + 65 = 'A'
요약하자면 key 값이 출력되는 Logic은 아래와 같다.
1. GET 방식으로 "giveme" 값을 담은 변수 g를 전송한다.
GET 방식에 대한 설명은 여기서 조금 더 볼 수 있다. URL 주소 뒤에 전송하고자 하는 데이터를 추가하면 된다.
2. cookie 변수에 "password" 값을 가진 c 값을 추가한다.
document.cookie를 사용해 c=password라는 쿠키 값을 갱신했다. alert 창을 이용해 제대로 갱신됨을 확인했다.
3. POST 방식으로 "keyplz!" 값을 가진 변수 p를 전송한다.
자바스크립트 코드내에서 POST 요청을 보내는 것은 이 사이트를 참고해서 명령어를 실행했다. createElement()는 말 그대로 요소를 추가하고, setAttribute()는 선택한 요소에 속성 값을 지정하는 역할을 한다. appendchild()는 새로운 요소를 선택한 요소의 자식 노드로 추가한다.
따라서 POST 방식으로 전달되는 form 태그를 먼저 만들고 form 태그에 input 태그를 추가해 submit을 하면, form 태그에 추가한 속성 중 등록했던 GET 방식으로 전달된 주소로 POST 방식을 통해 "keyplz!" 값을 전달한다.
위의 1, 2, 3 방식대로 데이터를 전송하면 key 값이 뜨고 이를 인증하면 풀린다.
[xcz.kr #21] PHP Obfuscation Crack - 300 points (0) | 2021.02.23 |
---|---|
[xcz.kr #32] Easy Trick - 100 points (0) | 2021.02.17 |
댓글 영역