Cha4SEr Security Study

[해커팩토리 초급] - 7번 본문

Web/해커팩토리[초급]

[해커팩토리 초급] - 7번

Cha4SEr 2020. 7. 9. 16:17

해커팩토리 초급 7번 문제입니다.

 

6번 문제와 유사하게 비밀 게시글을 읽어 인증키를 획득하는 문제입니다.

들어가봅시당

 

똑같이 비밀글이 보이고

 

암호를 입력하라는 창이 뜹니다.

 

F12 눌러서 소스코드에 힌트가 있는지 확인해봅시당

 

		
		var EncryptReadKey = "iRAJHaTRiRAJHaLLFBOwrXoLF6j2rSXC";
		function trans() {
			if (document.PasswordTrans.idx.value == "") {
				alert("게시글 번호 값이 존재하지 않습니다.");
				exit;
			}
			if (document.PasswordTrans.password.value=="") {
				alert("게시글 암호를 입력 하세요.");
				document.getElementById("password").setAttribute("class","form-control focusedInput");
				exit;
			}
			InputEncKey = UserPasswordEncryptFunc(document.PasswordTrans.password.value);
			
			if  (InputEncKey == EncryptReadKey) { 
				document.PasswordTrans.submit();
			} else {
				alert("게시글에 대한 암호가 일치하지 않습니다.");
			}
		}
	

 

쭉 둘러보다 보면 암호와 관련된 자바스크립트 코드가 보입니다.

 

대충 해석해 보면

 

1. 인증키를 정의한다. ("iRAJHaTRiRAJHaLLFBOwrXoLF6j2rSXC")

 

2. 사용자로부터 입력받은 패스워드를 UserPasswordEncryptFunc() 함수의 파라미터로 넣고, 함수의 결과를

   InputEncKey에 넣는다.

 

3. InputEncKey와 인증키를 비교하여 일치하면 게시글을 볼 수 있다.

 

정도로 요약할 수 있습니다.

 

여기서 핵심은 UserPasswordEncryptFunc() 인 것 같은데 주어진 자바스크립트 태그에는 존재하지가 않습니다.

아무래도 다른 부분에 숨어있는거 같네요.

 

 

내려보다 보면 5번 문제에서도 유용하게 쓰인 utill.js 파일이 보입니다. 역시 우클릭 후 Open in new tap

클릭해서 확인해봅시다.

 

이런식으로 UserPasswordEncryptFunc 함수와 PasswordEncrypt가 정의되어 있습니다.

 

요약하자면 UserPasswordEncryptFunc 함수가 호출되면  PasswordEncrypt를 통해 암호화가 진행하고 반환하는 코드입니다.

 

PasswordEncrypt는 함수가 좀 복잡하긴 하지만.. 해석을 안하고도 문제는 풀수가 있습니다.

 

바로 크롬 Console 창을 통해서!

 

크롬에서 F12를 누르고 Console 창을 열면 javascript 코드를 실행시킬 수 있는데, 

여기서 웹페이지에 내장된 자바스크립트를 호출할 수 있습니다.

 

이런식으로 UserPasswordEncryptFunc 함수를 호출하고, 결과값을 볼 수 있습니다.

 

그래서 생각해본 것이 리버싱 문제와 유사하게 모든 아스키코드의 문자를 입력해서 나온 결과를  

인증키("iRAJHaTRiRAJHaLLFBOwrXoLF6j2rSXC") 와 비교해보는 것이었습니다.

 

그러기 위해 우선 입력할 글자가 몇글자 인지 파악해야 합니다.

 

우선, 몇가지 대입을 통해 패턴을 찾아봅시다.

 

1~3 글자를 input 했을 때는 4글자가 output으로 나왔고, 4글자 부터 8글자로 바뀌었습니다.

조금 더 실험을 해보니, 6글자 까지는 8글자로 output

7글자 부터는 12글자로 output이 나왔습니다.

 

 

여기서 유추해볼 수 있는 사실은

Input의 1~3글자 단위로 Output은 4글자가 출력이 되는 것 입니다.

 

 

우리가 최종적으로 출력해야할 인증키는

iRAJHaTRiRAJHaLLFBOwrXoLF6j2rSXC  총 32글자 입니다.

 

그렇다는 뜻은 Input값은 22,23,24 글자 중 하나라는 것이죠.

 

또, 여러번 테스트를 해보핬을때 발견한 사실이 하나 더 있었습니다.

a, ab, abc 를 넣었을때는 값이 모두 다릅니다.

하지만 abca를 넣었을때는 Function("abc") + Funcion("a")가 되었습니다.

Function("abcabc") = Function("abc") + Funcion("abc") 가 되었네요.

 

음.. 이런 규칙을 말로 어떻게 표현해야할지 잘 모르겠지만..

대충 3글자를 기준으로 한세트(?) 로 취급이 되는것 같습니다.

 

 

그렇다면 이런 규칙을 가지고 해볼 수 있는 것은 

 

인증키 ("iRAJHaTRiRAJHaLLFBOwrXoLF6j2rSXC") 를 4글자 단위로 나누는 것 입니다.

 

var key = [iRAJ, HaTR, iRAJ, HaLL, FBOw, rXoL, F6j2, rSXC];

라고 정의를 해주면 

 

아스키 코드로 조합할 수 있는 3글자 문자열을 입력했을 때의 결과값이 각각

 

iRAJ, HaTR, iRAJ, HaLL, FBOw, rXoL, F6j2, rSXC 인 문자열을 합치면 정답이 될 것입니다.

 

Function("Thi") = iRAJ

Function("sIs") = HaRT

Function("Sam") = iRAJ

Function("ple") = HaLL

  ...

 

이런식으로 결과가 나왔다고 하면 정답은 "Thi" + "sIs" + "Sam" + "ple" = "ThisIsSample" 이라고 나오게 될 것입니다.

 

그렇다면 이제 코딩을 해 봅시다. 

 

제가 만든 코드를 보시기 전에 직접 본인만의 코딩을 해보시고 펼쳐보시는 것을 추천드립니다.

(막 짠거라 훨씬 효율적인 코드가 나올 수 있을것같은 생각이 들기 때문에..ㅎ)

 

 

더보기
// 인증키를 4글자 단위로 나눈 다음 배열로 저장
var enc_code = "iRAJ,HaTR,iRAJ,HaLL,FBOw,rXoL,F6j2,rSXC"
var enc_list = enc_code.split(',');



var password = ""; // 정답을 저장할 변수
var check = 0;



for (var x = 0; x < enc_list.length; x++){  // enc_list의 길이만큼 반복

	// 공백이나 기타 특수문자들을 제외한 후
    // 33(!) ~ 126(~) 까지의 아스키 코드 문자만 반복문을 돌림
    
    
    // 문자 3개를 조합하기 위한 3중 for문
    for (var i = 33; i <= 126; i++){		
        for(var j = 33; j <= 126; j++){
            for(var k = 33; k <= 126; k++){
            	
                // String.formCharCode는 매개변수(int 값)에 대응하는 아스키 문자 반환
                var temp_chr = String.fromCharCode(i)+String.fromCharCode(j)+String.fromCharCode(k);
                
                // 세개의 문자를 조합한 임시 문자열을 UserPasswordEncryptFunc 함수에 넣은 결과를 저장
                var temp_result = UserPasswordEncryptFunc(temp_chr);
                
                // 그 결과를 enc_list[x](인증키) 와 비교
                if(temp_result == enc_list[x]){
                	
                    // 문자열이 일치한다면 결과를 최종 정답에 붙임
                    password = password + temp_chr;
                } 
                
                
                /* 마지막 문자열(rsXC)은 3글자가 아니라 1~2글자일 수도 있기 때문에 
                check 값을 활용해서 한번 더 검사했습니다. */
                
                else { 
                    var temp_chr2 = String.fromCharCode(j)+String.fromCharCode(k);
                    var temp_result2 = UserPasswordEncryptFunc(temp_chr2);
                    if(temp_result2 == enc_list[x]){
                        password = password + temp_chr2;
                        check = 1;
                        break;
                    }
                }
            }
        if(check == 1){
            break;}
        }
    }
}

// 위 과정으로 나온 정답 출력
password

 

정답 : BestOfBestHackerFactory

(드래그 하시면 볼 수 있습니다.)

 

 

위 비밀번호를 입력하시면 인증키를 바로 획득해서 볼 수 있습니다.

'Web > 해커팩토리[초급]' 카테고리의 다른 글

[해커팩토리 초급] - 10번  (0) 2020.07.13
[해커팩토리 초급] - 8번  (0) 2020.07.12
[해커팩토리 초급] - 6번  (1) 2020.07.08
[해커팩토리 초급] - 5번  (1) 2020.07.08
[해커팩토리 초급] - 4번  (0) 2020.07.08
Comments