1. SQL injection이란

2. SQL injection의 종류

3. 대응방법

1. SQL injection이란

출처:안랩

SQL injection은 Database의 취약점을 이용하여 정상적이지 않은 동작을 하도록 하는 SQL문을 입력하여 공격자가 원하는 작업을 수행하거나 정보를 유출하게되는 공격입니다.

 

SQL injection은 최근까지도 많이 일어나고 있는 공격기법 중 하나입니다.

 

2. SQL injection의 종류

2.1 Normal SQL injection

출처:안랩

Normal SQL injection은 논리적 에러를 이용한 SQL injection으로 위의 로그인 예시에서 ' OR 1=1 --와 같이 값을 입력해주게 되면 OR 1=1에 의해 항상 참, --에 의해 뒷 부분은 주석처리가 되며 로그인에 성공하게 됩니다.

 

2.2 Error based SQL injection

https://www.bugbountyclub.com/pentestgym/view/53

Error based SQL injection은 주로 데이터베이스에 대한 정보를 획득하기 위해 사용됩니다. SQL의 잘못된 문법이나 자료형 불일치 등에 의해 데이터베이스가 알려주는 데이터베이스 오류 메시지에 의존하여 수행되는 공격 기법입니다.

 

2.3 Union based SQL injection

출처 : 안랩

SQL의 Union이라는 구문을 사용하는 공격인 Union based SQL injection은 Union을 이용하여 원래의 요청에 하나의 추가 쿼리를 삽입하는 공격입니다.

이 때 필요한 전제조건으로 Union하는 두 쿼리의 컬럼의 개수와 데이터 형식이 같아야합니다.

 

위의 사진의 경우 게시글을 찾는 쿼리문에 Union을 넣어 Users 테이블의 id, 패스워드를 읽어오는 공격입니다.

 

2.4 Blind SQL injection - Boolean based SQL

출처 : 안랩

 

위의 사진은 MySQL 에서 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만, 그리고 마지막으로 ASCII 를 통해서 ascii 값으로 변환해줍니다

만약에 조회되는 테이블 명이 Users 라면 ‘U’ 자가 ascii 값으로 조회가 될 것이고, 뒤의 100 이라는 숫자 값과 비교를 하게 됩니다.

U의 ascii 값은 125이므로 뒤의 100의 값을 변경해가면 125일때 거짓이 나오므로 첫 글자가 U라는것을 알 수 있습니다.

이를 자동화하여 테이블명을 알아내는 방법입니다.

 

2.5 Blind SQL injection - Time based SQL

출처 : 안랩

위의 그림은 Time based SQL Injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법입니다. 로그인 폼에 주입이 되었으며 임의로 abc123 이라는 계정을 생성해 두었습니다.

악의적인 사용자가 abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) -- 이라는 구문을 주입하였습니다. 여기서 LENGTH 함수는 문자열의 길이를 반환하고, DATABASE 함수는 데이터베이스의 이름을 반환합니다.

주입된 구문에서, LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 가 동작하고, 거짓이면 동작하지 않습니다.

 

이를 통해서 숫자 1 부분을 조작하여 데이터베이스의 길이를 알아 낼 수 있습니다. 만약에 SLEEP 이라는 단어가 치환처리 되어있다면, 또 다른 방법으로 BENCHMARK  WAIT 함수를 사용 할 수 있습니다.

 

3. 대응방법

입력 값에 대한 검증

사용자의 입력이 올바른 값인지 검증합니다. 사용자가 공격할 가능성이 있는 키워드들을 검증하고 차단합니다.

 

 

Prepared Statement 구문사용

 Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기합니다. 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격쿼리가 들어간다고 하더라도, 사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않습니다.

 

 

Error Message 노출 금지

공격자가 SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블명, 컬럼명 등)가 필요합니다. 데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환해 줍니다. 여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에, 데이터 베이스에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작 혹은 메시지박스를 띄우도록 하여야 합니다.

 

웹 방화벽 사용

웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법입니다. 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고, 하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법입니다.

'Security > Webhacking' 카테고리의 다른 글

CSRF 공격  (0) 2024.05.12
XSS문제 실습  (0) 2024.05.10
Cookie & Session  (0) 2024.05.08
  1. CSRF란
  2. CSRF의 원리
  3. CSRF 방어 방법

1. CSRF란

CSRF는 공격자가 만든 악성 스크립트가 포함된 URL을 사용자가 실행하게 되면, 사용자의 세션을 이용하여 사용자가 의도하지 않은 작업을 수행하는 공격입니다.

대표적으로 패스워드 변경, 송금 등이 있습니다.

 

2. CSRF의 원리

CSRF 공격이 성립하기 위해 충족되야하는 조건이 있습니다.

1. 사용자는 보안이 취약한 서버로부터 이미 로그인되어 있는 상태여야 합니다.
2. 쿠키 기반의 서버 세션 정보를 획득할 수 있어야 합니다.
3. 공격자는 서버를 공격하기 위한 요청 방법에 대해 미리 파악하고 있어야 합니다.

 

위 조건이 만족되었을 때  CSRF공격이 가능하게 됩니다.

 

CSRF공격의 시나리오는 다음과 같습니다. 

1. 사용자가 보안이 취약한 서버에 로그인되어있다.

2. 공격자의 악성 스크립트가 포함된 URL을 사용자가 접속하게된다.

3. 악성 스크립트에 담겨있는 내용이 사용자 세션 ID를 이용해 실행되게된다.

4. 서버는 해당 내용을 사용자가 요청한것으로 인식하고 실행하게 된다.

3. CSRF 방어방법

1. Referrer 검증

Request header에 포함된 Referer는 현재 요청된 페이지의 링크 이전의 웹페이지 주소를 포함합니다.

Referrer를 검증해서 해당 요청이 요청될 수 있는 위치인지 검사를 하면 CSRF를 막을 수 있습니다.

 

2. CSRF 토큰 검증

로그인을 할 때 CSRF 토큰을 생성하여 세션에 저장해 둡니다.

CSRF 토큰을 페이지 요청태그의 hidden값에 넣어줍니다.

Ex) <input type="hidden" name="_csrf" value="${CSRF_TOKEN}" />

이후 요청을 할 때마다 CSRF 토큰을 같이 보내어, 서버에서 토큰을 검증합니다.

'Security > Webhacking' 카테고리의 다른 글

SQL injection 공격  (0) 2024.05.12
XSS문제 실습  (0) 2024.05.10
Cookie & Session  (0) 2024.05.08

https://xss-game.appspot.com/

 

XSS game

Welcome, recruit! Cross-site scripting (XSS) bugs are one of the most common and dangerous types of vulnerabilities in Web applications. These nasty buggers can allow your enemies to steal or modify user data in your apps and you must learn to dispatch the

xss-game.appspot.com

위 사이트에서 진행하였다. 문제는 총 6문제이다.

1번 문제

 

간단하게 <script>alert()</script>를 넣어주면 풀리는 문제

 

2번 문제

 

<script>가 통하지 않아 <img>의 onerror를 이용하여 alert()를 작동시켰다.

 

3번 문제

 

코드를 보면 <img src='/static/level3/cloud{num}.jpg/>로 값을 넣어주는것을 확인할 수 있다.

문제 2번과 마찬가지로 onerror를 쓰면 되는것으로 보이지만 사용자가 입력을 하는 부분이 없다.

 

 

이럴때는 URL을 이용하여 원하는 값을 입력해주면 된다.

frame#뒤에 없는 번호인 5번을 넣어 error를 발생시키고, onerror를 통해 alert()함수를 실행시켜보았다.

 

4번 문제

 

 

위의 input상자에 넣은 값을 <img>의 onload="startTimer('{{timer}}');"에 넣어주는 것을 볼 수 있다.

timer의 따옴표를 탈출하고 alert()를 실행시키기 위해서 -1');를 통해 startTimer('-1');를 만들어주자

이어서 뒤에 alert(' 를 붙여줌으로써 alert('');를 만들어준다

다음과 같이 입력하면 된다.

 

전체 입력 = -1');alert('

입력 시 실행되는 함수 = startTimer('-1');alert('');

 

5번 문제

signup.html

이번 문제에는 3가지 html페이지가 있지만 여기서는 signup.html만 보면 된다.

level.py

level.py의 코드를 보면 next값을 get요청이 들어왔을 때 들어오는 값으로 설정해주고 있는 것을 알 수 있다.

 

signup.html

signup.html의 코드를 보면 <a href="{{next}}">로 되어있는 부분이 있는데, <a>태그의 href에는 주소 뿐만이 아니라 자바스크립트 코드가 들어가서 실행될 수도 있다.

next의 값에 javascript:alert();를 입력하면 되지 않을까?

 

 

URL의 next값에 javascript:alert()를 넣어준 후 next버튼을 눌러주면 alert가 실행되면서 성공하게 된다!

 

6번문제

 

/* This is a completely awesome invisible gadget */

gadget.js

<!doctype html>
<html>
  <head>
    <!-- Internal game scripts/styles, mostly boring stuff -->
    <script src="/static/game-frame.js"></script>
    <link rel="stylesheet" href="/static/game-frame-styles.css" />
 
    <script>
    function setInnerText(element, value) {
      if (element.innerText) {
        element.innerText = value;
      } else {
        element.textContent = value;
      }
    }
 
    function includeGadget(url) {
      var scriptEl = document.createElement('script');
 
      // This will totally prevent us from loading evil URLs!
      if (url.match(/^https?:\/\//)) {
        setInnerText(document.getElementById("log"),
          "Sorry, cannot load a URL containing \"http\".");
        return;
      }
 
      // Load this awesome gadget
      scriptEl.src = url;
 
      // Show log messages
      scriptEl.onload = function() { 
        setInnerText(document.getElementById("log"),  
          "Loaded gadget from " + url);
      }
      scriptEl.onerror = function() { 
        setInnerText(document.getElementById("log"),  
          "Couldn't load gadget from " + url);
      }
 
      document.head.appendChild(scriptEl);
    }
 
    // Take the value after # and use it as the gadget filename.
    function getGadgetName() { 
      return window.location.hash.substr(1) || "/static/gadget.js";
    }
 
    includeGadget(getGadgetName());
 
    // Extra code so that we can communicate with the parent page
    window.addEventListener("message", function(event){
      if (event.source == parent) {
        includeGadget(getGadgetName());
      }
    }, false);
 
    </script>
  </head>
 
  <body id="level6">
    <img src="/static/logos/level6.png">
    <img id="cube" src="/static/level6_cube.png">
    <div id="log">Loading gadget...</div>
  </body>
</html>

index.html

class MainPage(webapp.RequestHandler):
  def render_template(self, filename, context={}):
    path = os.path.join(os.path.dirname(__file__), filename)
    self.response.out.write(template.render(path, context))
 
  def get(self):
    self.render_template('index.html')
 
application = webapp.WSGIApplication([ ('.*', MainPage), ], debug=False)

level.py

 

문제 화면

6번 문제는 URL의 frame#뒤에 넣은 값을 읽어, 해당 주소를 <script> 의 src로 넣고 document.head.appendChild()로 head영역에 더해주게 된다.

즉 src의 값을 alert()를 실행하는 주소의 값으로 넣어주면 된다.

 

내 웹서버에 js파일을 업로드하여 실행해주는 방법도 있지만, 이번엔 Data URL schema방식을 사용했다.

 

Data URL schema문법

data:[<mediatype>][;base64],<data>

 

 

data:text/javascript,alert()를 입력해주어 성공!

'Security > Webhacking' 카테고리의 다른 글

SQL injection 공격  (0) 2024.05.12
CSRF 공격  (0) 2024.05.12
Cookie & Session  (0) 2024.05.08

쿠키와 세션은 무엇인가

쿠키와 세션은 웹 서비스에서 사용자의 상태를 저장하여 사용자가 웹사이트를 더욱 편하게 사용하도록 만들기 위해 만들어진 개념입니다.

왜 이런 개념이 만들어졌을까요?

HTTP 프로토콜의 특징


https://raonctf.com/essential/study/web/cookie_connection

웹 서비스에서 사용하는 HTTP프로토콜은 Connectionless와 Stateless라는 특성을 가집니다.

 

Connectionless
클라이언트가 서버에 요청을 하고 응답을 받으면 바로 연결을 끊어 연결을 유지 하지 않는다.

이를 통해 서버의 자원을 효율적으로 관리하고, 수 많은 클라이언트의 요청에도 대응할 수 있게 한다.
Stateless
Stateless는 서버가 클라이언트의 이전 상태를 보존하지 않는다는 의미이다

쿠키와 세션을 사용하지 않는다면 페이지를 이동할 때마다 로그인을 해주어야 하게 된다.

 

위와 같은 문제점을 보완해주기 위해 생겨난 개념이 쿠키(Cookie)와 세션(Session)입니다.

 

쿠키(Cookie)


https://raonctf.com/essential/study/web/cookie_connection

HTTP 쿠키(HTTP cookie)란 하이퍼 텍스트의 기록서(HTTP)의 일종으로서 인터넷 사용자가 어떠한 웹사이트를 방문할 경우 사용자의 웹 브라우저를 통해 인터넷 사용자의 컴퓨터나 다른 기기에 설치되는 작은 기록 정보 파일을 일컫는다. -wikipedia-

 

쉽게 말해 우리가 웹 사이트를 이용할 때 서버에서 우리 컴퓨터에 있는 웹 브라우저에게 쿠키라는 파일을 하나 보내줍니다. 그 쿠키에는 사용자가 웹 사이트를 편하게 이용할 수 있는 여러정보가 담겨있습니다.

 

쿠키의 구성요소

  • 쿠키의 이름 (name)
  • 쿠키의 값 (value)
  • 쿠키의 만료시간 (Expires)
  • 쿠키를 전송할 도메인 이름 (Domain)
  • 쿠키를 전송할 경로 (Path)
  • 보안 연결 여부 (Secure)
  • HttpOnly 여부 (HttpOnly)

쿠키의 특징

  • 클라이언트는 총 300개의 쿠키를 저장할 수 있다
  • 하나의 도메인 당 20개의 쿠키를 가질 수 있다
  • 하나의 쿠키는 4KB까지 저장 가능하다

쿠키의 동작방식

1. 사용자가 쿠키 없이 request 요청

2. 서버가 쿠키를 생성하여 response와 쿠키를 함께 응답

3. 사용자가 서버에게서 받은 쿠키를 저장하고 다음 request부터 쿠키를 넣어 요청

 

쿠키의 사용 예

  • 방문 사이트에서 로그인 시, "아이디와 비밀번호를 저장하시겠습니까?"
  • 쇼핑몰의 장바구니 기능
  • 자동로그인, 팝업에서 "오늘 더 이상 이 창을 보지 않음" 체크, 쇼핑몰의 장바구니

 

션(Session)


세션이란 일정시간동안 사용자로부터 들어오는 요구를 하나의 상태로 유지하는 기술이다.

 

예를 들어, 로그인을 했을 때 다른 페이지로 이동해도 로그인 상태가 계속 유지되면서 이용할 수 있는것은 세션이 있기 때문입니다.

 

세션의 특징

  • 세션은 서버의 메모리 혹은 DB등에 저장된다.
  • 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.
  • 접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정 가능.
  • 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 됨
  • 사용자가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 세션 ID를 부여함.

세션의 동작방식

1. 사용자가 서버에 접속 시 세션 ID를 발급받음

2. 사용자가 request 요청을 보낼 때 쿠키에 세션 ID를 넣어서 보내게 됨

3. 서버는 세션 ID를 통해 세션 ID에 맞는 클라이언트의 정보를 가져옴

4. 가져온 클라이언트 정보를 통해 사용자에게 응답

 

세션의 사용 예

  • 로그인 상태유지

쿠키와 세션의 차이


  쿠키 세션
저장 위치 클라이언트 웹 서버
저장 형식 text Object
만료 시점 쿠키 저장시 설정 브라우저 종료시 삭제
사용하는 자원 클라이언트 리소스 웹 서버 리소스
용량 제한 총 300개
하나의 도메인 당 20개
하나의 쿠키 당 4KB
서버가 설정하게 됨
속도 빠름 느림
보안 안좋음 좋음

 

쿠키 취약점

쿠키와 관련하여 발생할 수 있는 취약점에는 다음과 같은 것들이 있습니다.

 

Session Hijacking

 - XSS나 Sniffing등의 공격을 통해 쿠키를 탈취당하게 되면 공격자가 피해자의 세션 ID를 통해 바로 로그인을 할 수 있게 됩니다.

 

CSRF

 - CSRF공격을 통해 사용자의 세션 ID를 이용하여 공격자가 원하는 작업을 수행할 수 있습니다.

 

 

'Security > Webhacking' 카테고리의 다른 글

SQL injection 공격  (0) 2024.05.12
CSRF 공격  (0) 2024.05.12
XSS문제 실습  (0) 2024.05.10

+ Recent posts