□LFI/RFI
: 파일참조 공격, 페이지 내 다른 파일을 참조하는데서 취약점이 발생함
- 함수 : include
- 컴포넌트쪽 공격
- 취약점 구조 : 소스코드 내 'admin?page../../../test.html' 와 같은 구조를 가지고 있음
LFI : 로컬 파일 참조
>> admin 페이지가 실행되는 서버의 파일을 참조하는 공격(웹서버)
>> ../../../../../../etc/passwd 와 같이 입력하여 로컬에 있는 파일 참조
../ : 상위 디렉토리 지정 문자열이 핵심, 인코딩 작업을 수행함, HTML,URL, 2중URL 등
RFI : 원격 파일 참조
>> 원격에 있는 페이지를 웹서버로 임포트하여 실행되는 공격
리모트
예시 http://attacker.com/webshell >>> 웹셸이 업로드된 효과
http:// : 프로토콜 지정이 핵심, hphttptp:// 이중으로 문자열을 입력함으로써 회피
취약한 부분을 찾아서 공격
LFI와 파일다운로드 공격과는 다르다
LFI는 파라미터를 통해 파일을 참조하는 방식, 파일 다운로드는 페이지가 다운로드할 파일을 지정하여 호출 하는 방식
lfi: http://test.com/abcd?page=../../../../../../etc/passwd
download: http://test.com/download?id=test.doc test.doc 대신에 상대경로 (../../../../../)로 파일명 입력
LFI는 함수 구조로 기반, download는 페이지로 동작
>> LFI : ../에 대해 인코딩 데이터 복호화 필요, ../ 필터 필요(WAF에 인코딩 데이터 복호화 기능 지원)
RFI : uri구조에 http와 같은 프로토콜 입력 필터
download : ../가 필터되도록(LFI 동일)
Rule을 만들면서 주의할점
1) 정규 표현식 사용여부 체크
ex) GET1,GET2,GET99와 같이 입력이 될 수 있는 것들.
꼭 이해 필요 룰 고도화를 해야하기 때문에
2)Rule에 탐지 되었을때 어떤 공격에 의해 탐지 되었는지에 대해 명확히 구분할것
rule에 의해 탐지되면 로그가 남으며, log기반으로 공격 횟수 카운팅이 가능
똑같은 상대경로기에 대응하는 방식은 똑같다
정보노출
Burosuite는 Proxy 도구
>> 서버단에서 설정
>> 보안 장비 대응 : 없는 메서드 필터 GET이라고 하는 문자열 뒤에 필터(정규표현식 사용)
관리자 페이지 노출
>> 서버단에서 접근제어 설정이 우선 시
>> 보안장비 : uri나 url기반에 관리자 페이지 접근 정규표현식 사용
인증우회
>> 서버단에서 인증 프로세스 체크가 유일
기존의 데이터를 회원가입에 접근시에는 인증없이 접근이여서 문제가 됨
중간에 프로세스 체크를 해줘야함
보안장비에 대한 대응책이 없음
파라미터 조작
>> 서버단에서 프로세스 체크 설정이 필요
:: 일반 게시판에서 글 쓰는 과정에서 프록시를 통해 공지사항 게시판 ID로 변경 시
파라미터 조작은 자동화 공격이 많음
:: 비정상행위로 탐지가 가능 (WAF 탐지 안됨 , IDS/IPS 탐지 가능)
디버깅 정보노출
보안 장비로 탐지 안됨
>> 서버단에서 디버깅 정보 최소화가 유일
개발자의 능력에 따라 천차만별로 보안 처리가 됨
세션 재사용
보안 장비로 탐지 힘들고
>> 서버단에서 세션정보 초기화가 설정 필수
무조건 되어 있어야 하고 안되어 있다면 취약점임
불필요한 Method 사용
>> PUT ,DELETE 를 통해 페이지 접근 시 탐지 하는 룰 필요
:: 의도적으로 PUT,DELETE를 사용하는 경우가 있음.
위험도가 있기에 PUT과 DELETE를 사용하지 않는게 좋고
오탐만 더 늘어날것이다.
공공기관,공기업은 원칙적으로 PUT과 DELETE를 사용못함
개발주체가 왜 사용을 했는지 소명 자료가 필요
소명자료가 없으면 전체 재개발이 필요, 소명자료가 있다 할지라도 객관적인 자료가 아니면 허용 X
명확한 객관적인 자료가 없으면 전체 재개발이 필요합니다. 상급기관에서 나온다면 분명히 얘기가 나옴
그렇기에 소명을 하지 못하는 경우가 있기에
내가 만약 PM일때 PUT과 DELETE를 하는 경우를 잡아서 바꾸도록해야됨
패킷이 재 사용되는 경우가 태반이기에 겸사겸사 실무에가서 어떻게 대응해야 할지 알아야함
외주 업체에 만약에 맡긴다면 명확하게 해줘야 한다.
PATCH도 가능하다면 사용하면 안됨
BruteForce
>> 비정상행위 탐지 룰 추가
게시글을 올리거나 파라미터에 데이터를 넣으면서 숨겨진 작업을 확인하거나
파라미터 변조나 로그인 등 1초에 5번 이렇게 접근하는것을 탐지하는 룰을 만들어 줘야함
Command Injection
>> uri에 ;,|,||,&& 가 들어가는 경우( 단 정규 표현식 사용 필요)
; ls 와 같이 공백이 들어간다
ModSecurity
1. apt update >> 저장소 업데이트(패키지)
2. apt install libapache2-mod-security2 -y
3. apache 서비스 재시작
4.설치 확인
5.설정 파일 복사 > 기본으로 설정파일이 허용되어 있지 않음
crs는 룰을 의미함
ModSecurity1 에서는 룰이 없었지만 2에서는 룰을 포함함
옵션도 gpt에게 물어보면 정규표현식으로 알려줌
apt-cache show libapache2-mod-security2
정상으로 패키지가 실행이 됐는지를 보여주는 명령어
6.설정파일 설정 >> rule파일은 아님
정상데이터를 확인하려는 일부의 rule이 들어가있음
mousepad /etc/modsecurity/modsecurity.conf
7번 line에 SecRuleEngine DetectionOnly를 SecRuleEngine On으로 수정
*****Rule구조*****
지시자 | 탐색영역 | 탐지할데이터 | log에 기록할 메시지 필드
SecRule REQUEST_HEADERS:Content-Type "^application/json" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" >> 원래 한줄임
log에 기록할 메시지 필드
SecRule REQUEST_HEADERS "^application/json"
지시자 탐색영역 탐지할데이터
REQUEST : 요청(클라이언트가 서버로 보내는 데이터)
인터넷 >>>>>>>>>> 웹서버
RESPONSE : 응답 (서버가 클라이언트로 보내는 데이터)
인터넷 <<<<<<<<<<< 웹서버
알아야할것
^application/json ^= 시작할 문자열 지정, application 문자열로 시작해야됨
id : rule 고유 식별번호
phase = 탐지할 영역
phase1 = request 헤더만
phase2 = request 헤더 + body
phase3 = 2 + response 헤더만
phase4 = 3 + response 헤더 + 바디
t:lowercase : 대소문자 구분 없음
pass : 통과하겠다
nolog : 로그로 기록하지 않겠다.
7. 서비스 재시작
systmemctl restart apache2
8. 사용자 룰 파일 위치 및 사용자 Rule 추가
mousepad 000-default-conf
SecRuleEngine On
SecRule ARGS:testparam "@contains test" "id:9999,deny,status:403,msg:'TEST'"
ARGS : 전역변수(매개변수)
@contains: 파라미터 인자값
deny, status, msg : deny(거부), status(403 출력), msg: log에 기록할 메시지명
http://test.com/?testparam=test 가 입력되면 403 출력
사용자 Rule 추가 후 서비스 재시작 (필수)
systemctl restart apache2
9.사용자 Rule 테스트
curl -v -X GET http://127.0.0.1/?testparam=1
curl -v -X GET http://127.0.0.1/?testparam=test
log에서 id값과 msg 확인 가능
로그 확인가능
로그 기록 확인
로그는 각각의 필드가 존재함
--ae7b8069-A-- >> 접속 정보가 존재 , 시간정보, 접속주체(클라이언트)
[13/Dec/2024:11:13:29.610999 --0500] Z1xdKfK9mVQQ3bqHCPRYlQAAAAA 127.0.0.1 36892 127.0.0.1 80
클라이언트 서버
--ae7b8069-B-- >> 클라이언트 헤더 정보(REQUEST 헤더)
GET /?testparam=test HTTP/1.1
Host: 127.0.0.1
User-Agent: curl/8.8.0
Accept: */*
--ae7b8069-F-- >> RESPONE 헤더 정보
HTTP/1.1 403 Forbidden
Content-Length: 274
Content-Type: text/html; charset=iso-8859-1
--ae7b8069-E-- >> RESPONE BODY 정보
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<hr>
<address>Apache/2.4.62 (Debian) Server at 127.0.0.1 Port 80</address>
</body></html>
--ae7b8069-H-- >> 탐지된 룰, 영역 기록
Message: Warning. Pattern match "^[\\d.:]+$" at REQUEST_HEADERS:Host. [file "/usr/share/modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "735"] [id "920350"] [msg "Host header is a numeric IP address"] [data "127.0.0.1"] [severity "WARNING"] [ver "OWASP_CRS/3.3.7"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/6.5.10"]
Message: Access denied with code 403 (phase 2). String match "test" at ARGS:testparam. [file "/etc/apache2/sites-enabled/000-default.conf"] [line "33"] [id "9999"] [msg "TEST"]
Apache-Error: [file "apache2_util.c"] [line 288] [level 3] ModSecurity: Warning. Pattern match "^[\\\\\\\\d.:]+$" at REQUEST_HEADERS:Host. [file "/usr/share/modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "735"] [id "920350"] [msg "Host header is a numeric IP address"] [data "127.0.0.1"] [severity "WARNING"] [ver "OWASP_CRS/3.3.7"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/6.5.10"] [hostname "127.0.0.1"] [uri "/"] [unique_id "Z1xdKfK9mVQQ3bqHCPRYlQAAAAA"]
Apache-Error: [file "apache2_util.c"] [line 288] [level 3] ModSecurity: Access denied with code 403 (phase 2). String match "test" at ARGS:testparam. [file "/etc/apache2/sites-enabled/000-default.conf"] [line "33"] [id "9999"] [msg "TEST"] [hostname "127.0.0.1"] [uri "/"] [unique_id "Z1xdKfK9mVQQ3bqHCPRYlQAAAAA"]
Action: Intercepted (phase 2)
Stopwatch: 1734106409607233 3999 (- - -)
Stopwatch2: 1734106409607233 3999; combined=2486, p1=1066, p2=1239, p3=0, p4=0, p5=181, sr=320, sw=0, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.9.8 (http://www.modsecurity.org/); OWASP_CRS/3.3.7.
Server: Apache/2.4.62 (Debian)
Engine-Mode: "ENABLED"
--ae7b8069-Z-- >> 로그의 끝
┌──(root㉿kali)-[/home/kali/Desktop]
└─# cd /usr/share/modsecurity-crs
┌──(root㉿kali)-[/usr/share/modsecurity-crs]
└─# ls
owasp-crs.load rules util >> rules가 이미 작성된 룰 포함
(root㉿kali)-[/etc/apache2/mods-enabled]
└─# ls
security2.conf >> 이 설정파일이 기본 룰 임포트 설정, 12번째 라인에 OWASP Rule 경로가 명시됨
운영체제가 데비안 계열인지 레드햇 계열인지에 따라서 룰이 설정되어있는 경로가 다름
Snort Rule 구조
Inline 모드 vs SPAN 모드(미러 모드)
실시간 탐지 미러링 모드 백업처리해서 사용 실시간 탐지 불가
snort는 시스코에 의해 인수됨
명령모드
네트워크 침입탐지 모드
snort 구조
룰을 어떻게 작성할꺼냐
Waf는 기본적으로 설치를 하게되면 룰이 있기 때문에 설정을 하지 않았지만
snort는 기본 룰이 없기에 룰을 추가해야하는데
룰의 이해도가 필요한 부분
사용자가 작성한 룰로 작동함
[Snort]
RTN(Rule header)
alert tcp 192.168.22 any -> 222.111.222.123 80
alert tcp 192.168.0.0/24 any -> 222.111.222.123 80 >> 출발지 192,168.0.0(1~254)까지 모두 탐지
룰작성시 목적지에 CIDR를 잘 사용하지 않음, 목적지가 명확함 (WEB Server)
distance 스킵
within 마지막 몇 바이트 건너뛰기
bytetest 내가 선언한것과 크기비교
pcre 정규표현식을 쓰겠다
1.Snort 설치
sudo su
apt update
apt install snort -y
snort --version
2.Snort test
/etc/snort
rules, snort.config // 룰 폴더 및 snort 설정 파일 경로
apt install mousepad -y
cd /rules
rm -rf* // 기존 룰 파일 모두 삭제
touch local.rules // 사용자 정의 룰 파일 생성
alert icmp any any -> any any (msg:"ICMP TEST";sid:10000001;)
>> local.rules 에 추가
터미널 창 하나더 오픈
snort -v -c /etc/snort/rules/local.rules //-v 자세히 실행, -c 룰 파일 지정
kali 에서 우분투로 ping 날려보기
3. log 확인
/var/log/snort
alert 또는 snort.alert
4. 실습 (Snort 옵션 이해)
Option 4개
룰작성 -> 파일 다운로드 -> 탐지확인, 스노트 종료 -> 파일 내용 확인 반복
00 1byte
리틀엔디언 방식으로 읽어오겠다
relative = distance 와 같다
little
3374 4953
alert any any -> any any (msg:"test";file_data;content:"test";depth:10;content:"test2";within:4;content:"test3";within:4;distance:10byte_test:4,>,12,relative,little;sid:10000002;)
any any -> any any : 모든 출발지로부터 모든 목적지
depth
within
distance
byte_test
고민해야하는 상황
오용탐지와 비정상 행위 탐지 중 어느게 더 작성이 어려울까???
오용탐지가 더 쉬움(정규표현식 이용)
비정상 >> 어디까지 카운팅을 허용 할거냐에 대한 명확한 임계치가 없음
>> 서버 리소스를 감안해서 타협이 필요