상세 컨텐츠

본문 제목

[HackCTF-Web#15] Authenticate - 350 points

WebHacking/HackCTF

by bing_su 2022. 1. 12. 16:24

본문

반응형
SMALL

HackCTF Web의 15번째 문제는 Authenticate다.

문제 링크: http://ctf.j0n9hyun.xyz:2031

문제 링크로 들어가면 로그인 창이 있다. 처음에는 SQL Injection 문제인가 싶어서 Username에 admin, Password에 ' OR '1' = '1을 넣어서 로그인 시도를 해봤다. 

 SQL Injection 시도

이 외에도 여러 방법으로 우회를 시도했으나 계속 "Invalid creds..."라는 문구만 뜨는 것으로 봐서 SQL Injection 문제는 아니라고 판단했다. (SQL Injection 구문 참고: https://security04.tistory.com/171)

<!DOCTYPE html>
<html>
<head>
	<title>Auth3ntication</title>
	<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.js"></script>

		
</head>
<body>
<h4>Auth3ntication
</h4>
<hr />

		<form action="#" method="post">
			<label>Username</label>
			<input class="form-control" type="text" name="username" id="cuser" placeholder="Username" />
			<label>Password</label>
			<input type="password" class="form-control" name="password" id="cpass" placeholder="Password" />
			<input type="submit" style="margin-top: 12px;" value="Login" class="form-control btn btn-success c_submit" />
		</form>
	<script type="text/javascript">
			$(".c_submit").click(function(event) {
				event.preventDefault();
				var u = $("#cpass").val();
				var k = $("#cuser").val();
				var func = "\x0d\x13\x45\x17\x48\x09\x5e\x4b\x17\x3c\x1a\x1f\x2b\x1b\x7a\x0c\x1f\x66\x0b\x1a\x3e\x51\x0b\x41\x11\x58\x17\x4d\x55\x16\x42\x01\x52\x4b\x0f\x5a\x07\x00\x00\x07\x06\x40\x4d\x07\x5a\x07\x14\x19\x0b\x07\x5a\x4d\x03\x47\x01\x13\x43\x0b\x06\x50\x06\x13\x7a\x02\x5d\x4f\x5d\x18\x09\x41\x42\x15\x59\x48\x4d\x4f\x59\x1d\x43\x10\x15\x00\x1a\x0e\x17\x05\x51\x0d\x1f\x1b\x08\x1a\x0e\x03\x1c\x5d\x0c\x05\x15\x59\x55\x09\x0d\x0b\x41\x0e\x0e\x5b\x10\x5b\x01\x0d\x0b\x55\x17\x02\x5a\x0a\x5b\x05\x10\x0d\x52\x43\x40\x15\x46\x4a\x1d\x5f\x4a\x14\x48\x4b\x40\x5f\x55\x10\x42\x15\x14\x06\x07\x46\x01\x55\x16\x42\x48\x10\x4b\x49\x16\x07\x07\x08\x11\x18\x5b\x0d\x18\x50\x46\x5c\x43\x0a\x1c\x59\x0f\x43\x17\x58\x11\x04\x14\x48\x57\x0f\x0a\x46\x17\x48\x4a\x07\x1a\x46\x0c\x19\x12\x5a\x22\x1f\x0d\x06\x53\x43\x1b\x54\x17\x06\x1a\x0d\x1a\x50\x43\x18\x5a\x16\x07\x14\x4c\x4a\x1d\x1e";
				buf = "";
				if(k.length == 9) {
					for(i = 0, j = 0; i < func.length; i++) {
						c = parseInt(func.charCodeAt(i));
						c = c ^ k.charCodeAt(j);
						if(++j == k.length) {
							j = 0;
						}
						buf += eval('"' + a(x(c)) + '"');
					}
					eval(buf);
					
				} else {
					$("#cresponse").html("<div class='alert alert-danger'>Invalid creds...</div>");
				}
			});
			
			function a(h) {
				if(h.length != 2) {
					h = "\x30" + h;
				}
				return "\x5c\x78" + h;
			}
			
			function x(d) {
				if(d < 0) {
					d = 0xFFFFFFFF + d + 1;
				}
				return d.toString(16).toUpperCase();
			}
	</script>
	
		
		</div>
		<div id="cresponse">
		</div>
		
<hr />
</body>
</html>

페이지 소스를 봤다. (캡처하기 뭔가 애매해서 티스토리 코드블럭으로 옮겨서 봤다.) 처음 봤을 때는 난독화까지는 아닌 것 같았지만 그래도 복잡해 보였다. 대충 암호화를 하는 것 같은데, 그래도 최대한 로직을 분석해봤다. 

if(k.length == 9) {
	for(i = 0, j = 0; i < func.length; i++) {
		c = parseInt(func.charCodeAt(i));
		c = c ^ k.charCodeAt(j);
		if(++j == k.length) {
			j = 0;
		}
		buf += eval('"' + a(x(c)) + '"');
	}
	eval(buf);
					
} else {
	$("#cresponse").html("<div class='alert alert-danger'>Invalid creds...</div>");
}

이 부분을 분석해봤다. k 문자열의 길이가 9일 때 위에 선언된 func 문자열을 유니코드로 변환한 후 정수로 바꿔서 c에 넣고 j index에 해당하는 k와 XOR을 해서 x, a 함수를 통해 암호화해서 값을 반환하는 것 같다. (이러면 웬만해서 쓰레기 값이 리턴되지 않나..)

</div>
<div id="cresponse">
</div>

그러던 중, 페이지 소스코드를 봤을 때 보였던 id인 "cresponse"가 보였다. 이 문자열의 길이도 9니까 괜히 준 건 아니겠다 싶어서 개발자 도구 콘솔에 해당 값을 넣고 위의 로직을 돌려봤다. 

Chrome 개발자 도구 콘솔에 cresponse 값을 키 값으로 넣어 암호화된 결과 확인

na d8f08r_hzXkblhh["{.+r.'s1q=%|?dretv/#t?df|xw5#p"ba&xv?h`a/*.hf/1p::(<)r-cpchkdu>cl~khkpl2bvp:'l~{.`}>s)d~{:yq?i)`c}=-3p%8x,:{&8%<'u1e{ht#b's18%:sdumbh4ck5%.&yl6a0r;cag88ay#t:/tj)bjw9Pz~v<-h1tt~j?-k?uuq?:rp

나온 문자열이다. 보던 중 "dumbh4ck5"라는 문자열이 눈에 띄었다. 마침 딱 9글자라 Username에 쓰기에도 적절하다고 생각되었다. 다시 Username을 dumbh4ck5로 생각하고 개발자 도구 콘솔에 넣고 암호화 로직을 다시 돌렸다.

Chrome 개발자 도구 콘솔에 dumbh4ck5를 키 값으로 넣어 암호화된 결과 확인

우리가 알아볼 수 있을 만한 코드가 나왔다. 이를 코드블럭으로 정리한 후 살펴보자.

if(u == "XorIsNotSooS3cur3") {
	if(document.location.href.indexOf("?p=") == -1) {
    		document.location = document.location.href + "?p=" + u;
    }
}
else {
	$("#cresponse").html("<div class='error'>Wrong password sorry.")
}

u 값이 XorIsNotSooS3cur3일 때 p 값이 u가 되게 GET 방식으로 전달하면 문제가 풀릴 것 같다.

혹은, 해당 코드는 dumbh4ck5이 키 값일 때 도출되었고 키 값은 우리가 입력한 Username 문자열이므로 Username에 dumbh4ck5, Password에 XorIsNotSooS3cur3을 넣어도 문제가 풀릴 것 같다.

첫번째 방식으로 풀었을 경우: 플래그 나옴
두번째 방식으로 풀었을 경우: 플래그 나옴

두 방식 모두 플래그를 얻을 수 있었고, 이를 인증하면 문제가 풀린다.

한 문제 남았다. 내일 발표자료 준비 전까지 풀 수 있으려나 모르겠지만 힘내야겠다.

반응형
LIST

관련글 더보기

댓글 영역