ROOTCTF 제 1 회서울디지텍고등학교청소년해킹방어대회 Write-Up MISC Welcome(50) JunhoYeo( 여준호 ) 10st / 3147p 1. 제 1 회서울디지텍고등학교해킹방어대회 2. 에오신것을환영합니다 3. 모든문제의정답은다음과같은형식을가지고있습니다 4. 정답형식 = FLAG{ 내용 } 5. 6. FLAG{Welcome_to_Seoul_Digitech_ROOT_CTF} 정답형식을알려주는문제로, 그대로문제에나온대로입력하면된다. FLAG{Welcome_to_Seoul_Digitech_ROOT_CTF} MISC Find The Flag(913) 1. 문제출제자는크리스마스에혼자보내야된다는생각에화가나서플래그를숨겨버렸습니다. 2. 문제출제자가숨긴플래그를찾아주세요! 3. HINT:JS file,webcachev01.dat 분석 다른문제들을보면알겠지만, 해당 CTF 에서는구글드라이브를통해파일을공유한다. 그렇기때문 에 JS file 을다운로드받을수있는구글드라이브공유링크가 WebCacheV01.dat 에있을것이라 고생각했다. 먼저리눅스터미널의 strings 명령어를사용하여 WebCacheV01.dat 에서문자열데이터만을뽑아내
어파일에저장해두었다. 그리고검색기능을사용하여구글드라이브공유링크를찾아냈다. 해당링크에서 YWRtaW5fcm9vdA.js 파일을다운로드할수있었다. 그러나도저히 JavaScript file 로는보이지않았다. 파일의 hex code 를보니 header signature 가 PNG file 로되어있어서, 확장자를.PNG 로변경한뒤 열어보았더니플래그가아니라고떴다.
다행히 hex code 중간에서플래그를찾을수있었다. 여담이지만그냥다운받아서 hexdump 뜰필요없이처음부터플래그가있었다 씁쓸 FLAG{I3_Br0wser_F0r3ns1c_4ND_RoUgh_W0rk}
MISC Calculate(167) 1. 누가내패스워드좀알려줘! 2. hint : 역연산 주어진링크에들어가니 Python으로작성된소스코드를확인할수있었다. jdoodle.com/python-programming-online 에서코드를실행하니사용자에게문자열을입력받아암호화함수인 one(), two(), three(), four() 를순서대로호출하여문자열의문자를하나씩암호화한뒤플래그값이암호화되어저장된것으로추정되는 result 배열의값과비교하여일치하면 Correct!!, 일치하지않으면 Incorrect.. 를출력하는것같았다. 1. #include <stdio.h> 2. int one(int num, int size){ 3. int r = num + size; 4. r += 915; 5. return r; 6. } 7. int two(int num, int size){ 8. int r = num - size; 9. r -= 372; 10. return r; 11. } 12. int three(int num, int size){ 13. int r = num ^ size; 14. r ^= 826; 15. return r; 16. } 17. int four(int num, int size){ 18. size %= 32; 19. int r = num >> (32 - size); 20. int b = (num << size) - (r << 32); 21. return b + r; 22. } 23. int main(){
24. int result[32] = {5040, 4944, 5088, 4992, 7232, 4848, 7584, 7344, 4288, 7408, 7 360, 7584, 4608, 4880, 4320, 7328, 7360, 4608, 4896, 4320, 7472, 7328, 7360, 4608, 4752, 4368, 4848, 4608, 4848, 4368, 4944, 7200}; 25. char data[100]="qwertyuiop{}asdfghjkl!?zxcvbnm,.qwertyuiopasdfghjklzxcvbnm_1234 567890"; 26. for(int i=0; i<32; i++){ 27. for(int j=0; j<sizeof(data); j++){ 28. int number; 29. int str=data[j]; 30. number=one(str,100); 31. number=two(number,100); 32. number=three(number,100); 33. number=four(number,100); 34. if(result[i]==number){ 35. printf("%c", data[j]); 36. break; 37. } 38. } 39. } 40. return 0; 41. } 노가다스피릿으로하나씩직접입력해코드표를만드려는생각도들었지만순간이건아니라는것을깨닫고위와같이 C 언어로 Flag 값을출력하는소스코드를작성했다. 파이썬도좋겠지만 C 언어로하면더재미있을것같았기때문에 -라고쓰고파이썬을못해서그랬다고읽으면될것이다 씨익배열 result 에는 Flag 가암호화된값이, 배열 data 에는 Flag 를이룰것으로추정되는문자들이저장되어있다. 배열 result 에서알수있듯이 Flag 는총 32 개의문자로구성되어있다. 이중 for 문을사용하여 result[i] 의값과 data[j] 를암호화함수를순서대로암호화한값 number 를비교해두값이일치하면해당 data[j] 를출력하고 break 하여배열 result 의다음값을구하고, 일치하지않으면배열 data 의다음값과비교하는구조로플래그를출력한다. 간단한코드니까금방이해할수있을거라고생각한다. 프로그램을실행하면위처럼 Flag 가나온다. 여담으로다른분들께서는역연산함수를만들어서푸신분들이많은것같다. 그런데개인적으로는저렇게하나씩암호화해서비교하는브루트포싱으로푸는것도재미있고더빨리짤수있는것같다. 이는역시역연산함수를만드는것을못해서그랬다고읽으면될것같다. FLAG{Rev3rse_P1us_M1nus_X0R_R0L}
MISC Vocabulary 1. 플래그가적힌친구의단어장을잃어버렸다 2. 어서빨리찾아야된다. 3. 그친구가화내기전에플래그라도찾아보자 4. hint : PNG height pleas_find.png 파일을다운로드하여확인하고청개구리처럼 hex editor 로열어봤는데보 기불편해서그냥열라는대로 notepad 로열어봤다.
파일끝부분에단어장이보인다. 영국에서시작된어디서많이본듯한편지와 Fake Flag, 그리고 height를 1000px로 increase하라는힌트가나왔다. 그래서그림판을사용해서급한대로옮겼더니이미지가깨져버렸다. 그렇다면혹시 hex edit을하여 PNG file의 height를고치라는게아닐까? 물론그걸어떻게할지모르기때문에! 구글링을하여자료를찾아보았다. https://www.linkedin.com/pulse/hex-editing-width-height-png-files-ciaran-mc-ardle PNG hex edit을하여이미지의 width, height data를바꾸는것에관한링크다. 저기에표시한파란부분을수정하면 PNG width, 빨간부분을수정하면 PNG height 를 고칠수있는것같다. 1000px 로바꾸라고하였으므로 02 EE 를 1000 의 16 진수값인 03 E8 로고쳤다.
저밑에 Hello :) Go Down! 부분이나타났다. 더내려가면플래그가있는듯하다. 그 냥두배, 2000px 으로길이를바꿔보기로했다. 2000 의 16 진수값인 07 D0 으로고쳤다. 어라라! 뭔가가보인다. 플래그가나타났다! FLAG{_1vErticAl_2rEADiNg_3TAStlSb}
REVERSING Stage Game(229) 1. 인내의시간.. 2. Stage Level 1~10 3. hint : Sleep Stage.exe 파일이주어진다. 실행해본결과다음과같은프로그램인것같다. 먼저실행되면기다릴수있는지를물어보고 1이면스테이지게임시작, 0이면종료를한다. 게임내용은그냥 sleep() 함수등으로일정한시간동안기다리게하다가다음스테이지로넘어가고거기서더기다리면다음스테이지로넘어가고하는것을반복하면플래그를주고끝나는것같다. 문제는기다리는시간이너무길다는것이다. 본인의인내심으로는 3번스테이지가한계인것같다 리버싱해서수정해보자!
올리디버거로열고 All referenced text strings 으로문자열만모아서확인해보니저렇게문자열들이 나온다. 아이기분좋아 저중하나를클릭해보면역시! 예상대로 Sleep() 함수를호출 (call) 하여 delay 를발생시킨다는것 을볼수있다. 이걸 아무것도안하는 어셈블리명령으로바꾸면될것같은데
바로 NOP(No OPeration) 명령을쓰면될것같다. 어셈블리에서아무것도안하고넘어가는명령이다. 버퍼오버플로우 (BOF) 공격에서 NOP sled를만들때사용하는바로그명령! 저기 PUSH EAX 명령은왠지 Sleep() 함수에전달되는인수인것같아서그냥 CALL 명령이랑같이 NOP처리를했는데왠지안했어도됬을것같은기분이든다. 뭐하는명령인지도궁금하다. All intermodular calls로사용한 API 함수들을모아볼수있다. 이걸참고해서다음으로패치해야하는부분을볼수있다. 또마지막에 JMP로 Sleep() 함수로넘어가는? 부분이있던것같은데그부분도패치해줘야한다. 왜그런지는모르겠는데아마마지막스테이지를통과하고도좀더기다려야플래그가나오는게아닐까? 리버싱까막눈이라모르겠지만언젠가똭! 보면똭! 이해할날이오겠지 저렇게다 NOP로패치한프로그램을실행하니플래그가나왔다. CTF에서내가처음으로푼리버싱문제라서그런지정말기분이좋았다. 어떤문서에서쉘이따지고플래그가나왔을때의쾌감이있다는데이런게바로그런것일까 흐헿헿 (?) +) 여기서는처음이자마지막리버싱문제였다칸다ㅠ FLAG{Y0ur_p4t1enc3_1s_gr3at}
WEBHACKING Login 1. 로그인페이지인데로그인이안된다... 2. 로그인을성공하고짱해커가되어보자!! 3. Hint : Array, length<6 4. Hint2 : Get 으로배열을전송하는방법, sql injection 진짜오랫동안헤맷지만답은꽤가까이에있었던문제 페이지에들어가면 go! 버튼이나오는데, 이를누르면 login.php 으로 pw=guest 라는값을전달하며 리디렉션해준다. login.php에가면위와같은 PHP 소스코드를볼수있다. _GET() 함수로 pw, fpw 변수의값을받아와서 SQL 어쩌고저쩌고해서받아온 result 배열의 id값이 True면 (?) flag라는쿠키를생성하고저값을집어넣은뒤 flag.html로리디렉션하는것같다. 그러면 flag.html에 Flag값이나오겠지? 뭐딱봐도 SQL Injection(SQLI) 공격을해야하는것같다. 물론본인은 SQL 지식이전혀없으므로먼저꼼수를시도해봤다. 1) 그냥 flag.html로고고싱 실패다!
2) 쿠키값을변조후 flag.html 로고고싱 EditThisCookie 라는 chrome extension 을사용해서위와같이쿠키를만들었다. 역시 FLAG IS IN HERE 만나올뿐 실패닷! 결국 SQL injection 뿐인가 여러가지방법들을사용해봤지만리디렉션은되지않았다.. 1. http://sdhsroot.kro.kr/login/login.php?pw[1]='or'1 끈질긴구글링끝에 _GET() 으로 array 를전달하는방법을겨우겨우알아내위처럼 SQL 인젝션을시 도했다. Flag 쿠키가생성되고리디렉션은되었지만 플래그는나오지않았다. 페이지소스보기를해도나오지않는시츄레이션이라멘붕이제대로왔다. 설마 Flag 쿠키에저장되는값이플래그일까? Base64 format으로 decode를시도해보자다시 Base64로 encode된값이나오길래아래처럼플래그가나올때까지계속 decode하며해결했다. 1. VmxjeE1FNUdSbk5UV0hCclUwVmFiMWxzVm1GTlZtUnhVbFJXYVZKdGVGcFdSM0JYWWxaV1ZVMUVhejA9 2. VlcxME5GRnNTWHBrU0Vab1lsVmFNVmRxUlRWaVJteFpWR3BXYlZWVU1Eaz0= 3. VW10NFFsSXpkSEZoYlVaMVdqRTViRmxZVGpWbVVUMDk= 4. Umt4QlIzdHFhbUZ1WjE5bFlYTjVmUT09 5. RkxBR3tqamFuZ19lYXN5fQ== 6. FLAG{jjang_easy} FLAG{jjang_easy}
WEBHACKING SPACE PROSPECTION 1. 2023 년... SPACE PROSPECTION 라는회사가화성에진출했다. 2. 회사의사이트에들어가핵심기술을가져오자!! 주어진링크인 sdhsroot.kro.kr/blackout/index.html 에접속했다. 사이트여기저기를뒤져보다가 BLOG 메뉴의 SINGLEPOST 에가니위와같은 Article 이나온다. 1. http://sdhsroot.kro.kr/blackout/singlepost.html 2. <h1>flag</h1> 3. <div class="article"> 4. <img src="images/martianrover-journey.jpg" alt=""> 5. <h1>martian ROVER JOURNEY</h1> 6. <span>february 6, 2023</span> 7. <p> 지금은 2023 년... 우리의핵심기술을잃어버렸다.</p>
8. <p> 아주아주오래전... 이파일안에는우리의핵심기술이담겨있었습니다.</p> 9. <p> 하지만페이지디자인작업중정전이나버렸고, 이곳에담겨있던핵심기술은날아가버렸습니다.</p> 10. <P> 지금도이서버어딘가에핵심기술이담겨있는파일이돌아다닐수있습니다.</P> 11. </div> 이파일 은아마 Article에있는 picture나 html file을의미하는것이라고생각하고다운받아살펴보고 hex code도확인하는등온갓시도를해보았고, 사이트에있는다른파일들도살펴보았다. 그러다가 정전 (blackout) 과파일이 날아갔다, 서버어딘가에 등으로 blackout 때문에날아가버린 vi 에디터의.swp 파일이서버어딘가에남아있다는것을말해주려고하는것같았다. 그렇다면.swp 파일의이름은무엇일지 guessing해야할것이다..flag.txt.swp 등으로 Flag와관련하여시도해보았지만아니였다. 잠깐, 이파일 이라고했으므로해당 html file과관련되어있지않을까? sdhsroot.kro.kr/blackout/.singlepost.html.swp에서 Flag를찾을수있었다. FLAG{FROM_2017_FLAG}
WEBHACKING 보물찾기 이리저리찾아보고헤매다가 http://sdhsroot.kro.kr 의구성요소를모두다운받아하나의폴더에저 장하고, 개발중이였던해킹툴의소스코드를약간수정하여실행했더니 Flag 가나왔다. 뭐이런 다른 CTF에서파일의 hex dump에 Flag를숨겨놓는간단한문제들이나오는것을여러번보았기때문에 Flag값을더빨리찾아낼수있도록재미삼아만든툴이다. 파일의 hex code를출력하고 Flag에자주쓰이는키워드 (Flag, FLAG, flag, ctf, CTF 등 ) 를 hex code에서검색해출력하는기능까지구현했는데, 파일명을하나입력받아해당파일명의파일만검색하는것에서같은디렉토리안의파일전체를대상으로검색하고 hex code 출력기능을제거하여사용했다. 보다시피그냥 C언어로쉽게프로그래밍이가능한툴이다. 코드는생략 ( 잇힝 ) 저녀석에따르면 http://sdhsroot.kro.kr/vendor/bootstrap/css/bootstrap.min.css 의주석부분 에있다는데, 상상도못한곳이다. 깃허브어쩌고길래외부모듈인줄알았는데. 문제힌트에서나는 모르는무언가가있었던것일까.. 그냥방심하지말고하나씩차분하게살펴보아야하는거구나
WEBHACKING Phishing 주어진링크를클릭하면부적절한접근이라는알림이표시되면서이전페이지로리디렉션된다. 크롬에서페이지주소의앞부분에 view-source: 를붙이자위와같이페이지소스를볼수있었고, 주석으로 asd.php 가표시되어있는것역시확인이가능했다. sdhsroot.kro.kr/phishing/asd.php 에접속하자위처럼 FLAG{ 코드속에 } 이라는 alart 가나온다. 물론해당 Flag 는 Fake 로, 인증이되지않는다. 페이지소스를확인해보니난독화된자바스크립트코드가있었다.
1. var b = 200; 2. for (a = 0; a <= 20; a++) { 3. b = b + ((a * b) - (a / b)); 4. if (a == 0) b = 70; 5. else if (a == 1) b = 76; 6. else if (a == 3) b = 71; 7. else if (a == 2) b = 65; 8. else if (a == 4) b = 123; 9. else if (a == 20) b = 125; 10. else if (a == 5) { 11. continue 12. } else if (a == 6) { 13. alert(" 코 "); 14. continue 15. } else if (a == 7) { 16. alert(" 드 "); 17. continue 18. } else if (a == 8) { 19. alert(" 속 "); 20. continue 21. } else if (a == 9) { 22. alert(" 에 "); 23. continue 24. } else if (a == 10) { 25. alert("."); 26. continue 27. } else if (a == 11) { 28. alert("."); 29. continue 30. } else if (a == 12) { 31. alert("."); 32. continue 33. } else if (a >= 4 && a <= 20) { 34. continue 35. } 36. alert(string.fromcharcode(b)) 37. } jsbeautifier.org 에서난독화를해제하자위와같은코드가나타났다. 1. <script> 2. var b = 200; 3. for (a = 0; a <= 20; a++) { 4. b = b + ((a * b) - (a / b)); 5. if (a == 0) b = 70; 6. else if (a == 1) b = 76; 7. else if (a == 3) b = 71; 8. else if (a == 2) b = 65; 9. else if (a == 4) b = 123; 10. else if (a == 20) b = 125; 11. document.write(string.fromcharcode(b)) 12. } 13. </script> 위와같이코드를수정한뒤 js.do 에서실행하자문제의힌트에서처럼깨진문자열로이루어진 Flag 가나왔다. FLAG{ˡᐭꅭ 곚삍䘐䣇눛뵼 ᩎꓨ ᶐ ㆰ }