flag 가 현란한 무빙을 보여준다.
소스코드를 확인해 보자.
<html>
<head>
<style>*{margin: 0;}</style>
<script>
var box;
window.onload = init;
function init() {
box = document.getElementById("formbox");
setInterval(moveBox,1000);
}
function moveBox() {
box.posX = Math.random() * (window.innerWidth - 64);
box.posY = Math.random() * (document.documentElement.scrollHeight - 64);
box.style.marginLeft = box.posX + "px";
box.style.marginTop = box.posY + "px";
debugger;
}
function text2img(text){
var imglist = box.getElementsByTagName('img');
while(imglist.length > 0) {imglist[0].remove();}
var canvas = document.createElement("canvas");
canvas.width = 620;
canvas.height = 80;
var ctx = canvas.getContext('2d');
ctx.font = "30px Arial";
var text = text;
ctx.fillText(text,10,50);
var img = document.createElement("img");
img.src = canvas.toDataURL();
box.append(img);
};
function main(){
var _0x1046=['2XStRDS','1388249ruyIdZ','length','23461saqTxt','9966Ahatiq','1824773xMtSgK','1918853csBQfH','175TzWLTY','flag','getElementById','94hQzdTH','NOP\x20!','11sVVyAj','37594TRDRWW','charCodeAt','296569AQCpHt','fromCharCode','1aqTvAU'];
var _0x376c = function(_0xed94a5, _0xba8f0f) {
_0xed94a5 = _0xed94a5 - 0x175;
var _0x1046bc = _0x1046[_0xed94a5];
return _0x1046bc;
};
var _0x374fd6 = _0x376c;
(function(_0x24638d, _0x413a92) {
var _0x138062 = _0x376c;
while (!![]) {
try {
var _0x41a76b = -parseInt(_0x138062(0x17f)) + parseInt(_0x138062(0x180)) * -parseInt(_0x138062(0x179)) + -parseInt(_0x138062(0x181)) * -parseInt(_0x138062(0x17e)) + -parseInt(_0x138062(0x17b)) + -parseInt(_0x138062(0x177)) * -parseInt(_0x138062(0x17a)) + -parseInt(_0x138062(0x17d)) * -parseInt(_0x138062(0x186)) + -parseInt(_0x138062(0x175)) * -parseInt(_0x138062(0x184));
if (_0x41a76b === _0x413a92) break;
else _0x24638d['push'](_0x24638d['shift']());
} catch (_0x114389) {
_0x24638d['push'](_0x24638d['shift']());
}
}
}(_0x1046, 0xf3764));
var flag = document[_0x374fd6(0x183)](_0x374fd6(0x182))['value'],
_0x4949 = [0x20, 0x5e, 0x7b, 0xd2, 0x59, 0xb1, 0x34, 0x72, 0x1b, 0x69, 0x61, 0x3c, 0x11, 0x35, 0x65, 0x80, 0x9, 0x9d, 0x9, 0x3d, 0x22, 0x7b, 0x1, 0x9d, 0x59, 0xaa, 0x2, 0x6a, 0x53, 0xa7, 0xb, 0xcd, 0x25, 0xdf, 0x1, 0x9c],
_0x42931 = [0x24, 0x16, 0x1, 0xb1, 0xd, 0x4d, 0x1, 0x13, 0x1c, 0x32, 0x1, 0xc, 0x20, 0x2, 0x1, 0xe1, 0x2d, 0x6c, 0x6, 0x59, 0x11, 0x17, 0x35, 0xfe, 0xa, 0x7a, 0x32, 0xe, 0x13, 0x6f, 0x5, 0xae, 0xc, 0x7a, 0x61, 0xe1],
operator = [(_0x3a6862, _0x4b2b8f) => {
return _0x3a6862 + _0x4b2b8f;
}, (_0xa50264, _0x1fa25c) => {
return _0xa50264 - _0x1fa25c;
}, (_0x3d7732, _0x48e1e0) => {
return _0x3d7732 * _0x48e1e0;
}, (_0x32aa3b, _0x53e3ec) => {
return _0x32aa3b ^ _0x53e3ec;
}],
getchar = String[_0x374fd6(0x178)];
if (flag[_0x374fd6(0x17c)] != 0x24) {
text2img(_0x374fd6(0x185));
return;
}
for (var i = 0x0; i < flag[_0x374fd6(0x17c)]; i++) {
if (flag[_0x374fd6(0x176)](i) == operator[i % operator[_0x374fd6(0x17c)]](_0x4949[i], _0x42931[i])) {} else {
text2img(_0x374fd6(0x185));
return;
}
}
text2img(flag);
}
</script>
</head>
<body>
<div id='formbox'>
<h2>Find FLAG !</h2>
<input type='flag' id='flag' value=''>
<input type='button' value='submit' onclick='main()'>
</div>
</body>
</html>
난독화가 많이 되어있는 상태이다....
일단은 돌아다니는 flag는 거슬리니까 움직여주는 함수인 'moveBox'는 주석으로 처리해놓자.
/*function moveBox() {
box.posX = Math.random() * (window.innerWidth - 64);
box.posY = Math.random() * (document.documentElement.scrollHeight - 64);
box.style.marginLeft = box.posX + "px";
box.style.marginTop = box.posY + "px";
debugger;
}*/
if (flag[_0x374fd6(0x17c)] != 0x24) {
text2img(_0x374fd6(0x185));
return;
}
for (var i = 0x0; i < flag[_0x374fd6(0x17c)]; i++) {
if (flag[_0x374fd6(0x176)](i) == operator[i % operator[_0x374fd6(0x17c)]](_0x4949[i], _0x42931[i])) {} else {
text2img(_0x374fd6(0x185));
return;
}
}
text2img(flag);
어차피 어떤 변수, 어떤 값인지 모르는 상황에서는 조건문을 먼저 볼 수밖에 없다.
조건문에서 flag에 대한 값을 '!=' 연산자를 통해서 확인하는 거 같은데 이 부분이 중요한 거 같다.
console로 확인해 보자.
정의되지 않았다고 이야기한다.
그러면 처음부터 정해진 값이 아닌 무언가가 상호작용되야지 값이 들어가진다는 것을 알 수 있다.
유일하게 상호작용 할 수 있는 것은...
submit인 거 같다.
문자열을 넣어 sumbit 해보자.
임의의 값을 넣으니 NOP!이라는 이미지를 출력한다.
다시 개발자 도구로 돌아가 확인해 보자.
먼저 if 조건이 바로 넘어갈 수 있으니 breakpoint로 설정한 후 디버거 모드로 들어가자.
설정을 하고 다시 확인해 보니 '3'이 출력되었다.
123을 입력했으니 '3'이 출력된 거 보면 문자열의 길이를 생각해 볼 수 있다.
좀 더 확실히 보자.
'length'로 출력되는 거 보니 길이에 대한 부분이 맞았고...
아까 보여준 조건문의 조건은 '0x24' 즉 길이가 36글자여야 한다.
다음 for문을 살펴보자.
for (var i = 0x0; i < flag[_0x374fd6(0x17c)]; i++) {
if (flag[_0x374fd6(0x176)](i) == operator[i % operator[_0x374fd6(0x17c)]](_0x4949[i], _0x42931[i])) {} else {
text2img(_0x374fd6(0x185));
return;
}
flag [_0x374 fd6(0x17 c)] 부분은 36이라는 값을 알고 있으니 36으로 수정해 주자.
flag [_0x374 fd6(0x176)](i)는 for문을 이용해서 문자열 첫 번째부터 끝까지 가져와 operator 이랑 연산된 값을 비교해서 같으면 flag값을 출력하는 거 같다.
그러면 operator에 비교하는 값을 이용해서 답을 추출할 수 있을 거 같다.
'DreamHack > CTF' 카테고리의 다른 글
(CTF 출제)Out of money (0) | 2024.05.08 |
---|---|
(CTF 출제)DreamHack - broken-png (0) | 2024.05.08 |
(CTF 출제)DreamHack - Flying Chars (0) | 2024.05.02 |
(CTF 출제)DreamHack - Easy Login (1) | 2024.05.01 |
(CTF 출제)DreamHack - Mango (0) | 2024.04.30 |