반응형

| XSS

임의의 스크립트를 삽입하여 이용자의 브라우저에서 실행시키는 공격. (클라이언트 측)

*** XSS는 웹 브라우저에서 실행되는 코드에 의해 발생하기 때문에 클라이언트 측 공격입니다.

 

| XSS - 종류

  • Stored XSS
  • Reflected XSS
  • DOM-based XSS

| XSS 취약점이 발생하는 곳.

❗데이터가 저장되고, 출력되는 곳

ex) 게시판 글 작성, 회원가입 등등

 

즉, 정리하면 사용자가 작성한 데이터가 화면에 응답이 되고 있다면 XSS 취약점을 확인해 봐야 합니다. 이번 글에선 XSS 종류 중 Stored XSS에 해당하는 내용들을 알아가 보면서 XSS가 무엇인지 알아보겠습니다. 


▶️Stored XSS 

서버에 스크립트를 저장한 뒤, 스크립트가 포함된 페이지 요청 시 실행되는 공격

 

🔓Stored XSS 찾아보기

  1. 작성한 데이터가 화면에 응답 되는지 확인.
  2. 특수문자 체크
  3. Javascript

 

Stored XSS를 찾는 방법을 순서대로 정리했습니다. 해당 과정을 통해 XSS 취약점을 찾을 수 있는데 간단한 실습을 통해 
Stored XSS 취약점을 어떻게 찾고 무엇인지에 대해서 알아보겠습니다.

 

1️⃣ 작성한 데이터가 화면에 응답 되는지 확인.

현재 어떤 웹 사이트에서 글을 작성할 수 있는 기능이 있는 상황입니다.

게시판에서 사용자가 글을 작성하는 과정

 

게시판에서 글을 작성할 때 위와 같이 글을 작성하게 될 텐데  이제 글을 생성하고 해당 게시물에 접속을 하여 사용자가 입력한 데이터가 화면에 출력되는지 확인합니다. 

 

 

글 생성되었을 때
생성된 게시물에 접속했을 때

 

사용자가 작성한 게시물에 접속을 해보면 입력했던 데이터가 화면에 출력되고 있는 것을 볼 수 있습니다. 이런 경우에 이제 XSS 취약점을 확인해 봐야 합니다. 1번 단계를 끝냈으니 2번 단계로 넘어가겠습니다.

 

2️⃣ 특수문자 체크

2번 과정에서는 특수문자 4개 <, ', ", >를 삽입하여 해당 특수문자가 어떠한 필터링이 없이 그대로 사용되고 있는지 확인을 하게 됩니다. 각 특수문자들은 HTML 태그 기능을 수행할 수 있도록 해주는 특수문자이며 스크립트 삽입할 때 HTML 태그 기능을 사용해야 하기 때문에 먼저 체크를 하는 것입니다.

게시글 생성 시 특수문자 4개 삽입

 

특수 문자를 삽입한 글을 생성한 후에 게시물에 접속을 해보면 다음과 같습니다.

특수문자 삽입한 게시물에 접속했을 때

 

특수문자가 화면에 출력되고 있지만 이 과정에서는 소스코드를 확인하여 어떠한 필터링이 작용되고 있는지 아닌지 확인을 해야 합니다. (저는 Burp Suite를 사용해서 확인했습니다.)

 

특수문자 삽입한 게시물에 접속했을 때 응답 데이터

 

빨간색 박스 부분을 보면 특수문자 <, ', ", >가 그대로 사용되고 있는 것을 알 수 있습니다. 앞서 말한 것처럼 해당 특수문자들을 가지고 HTML 태그 기능을 수행할 수 있다고 말했었습니다. 이렇게 2번 과정은 특수문자가 그대로 사용되고 있는지를 체크하게 됩니다. 

 

🔎 비교를 위해 만약 어떠한 필터링이 작용해서 특수문자를 사용할 수 없는 상황도 확인해 보겠습니다.

 

특수문자 <, ', ", >이 어떠한 필터링으로 인해 다른 기호들로 바뀐 상황

 

바로 위 사진을 특수 문자들이 HTML Entity로 치환이 된 상황입니다. HTML Entity는 XSS 대응 방안 중 하나입니다. 해당 사진은 삽입했던 특수문자가 어떠한 대응 방안 때문에 다른 문자들로 치환이 되었고 이로 인해 태그 기능을 사용할 수 없단 것을 보여드리기 위해서입니다. 바로 아래 표는 각 특수기호가 어떠한 HTML Entity로 치환되었는지 간단하게 적었습니다.

💡참고

< &lt;
> &gt;
' &#039; or &apos;
" &quot;

 

이제 다시 돌아가서, 특수문자 <, ', ", >이 그대로 사용되었을 때 이어서 3번 과정을 진행합니다.

 

3️⃣ Javascript

특수문자가 그대로 사용되고 있다는 것은 HTML 코드를 삽입할 수 있다는 것을 의미합니다. 따라서 이때 스크립트를 삽입합니다. 여기서 주의해야 할 점은 POC 코드를 사용해야 한다는 것입니다.

POC 코드를 사용하는 이유는 해당 취약점을 통해 문제가 발생할 수 있다는 것을 보여주기 위함입니다. 간단하게 말하면 일부러 악의적인 스크립트를 사용해서 확인을 하면 안 되기 때문에 POC 코드를 사용하게 됩니다. (POC 코드는 모의해킹을 할 때 취약점을 이용해서 공격이 가능하다는 것을 보여주는 코드입니다.)

 

다음과 같이 스크립트를 삽입합니다. 

<script>alert(1)</script> // 해당 스크립트는 알림창을 띄웁니다.

 

게시글 작성 시 스크립트를 삽입했을 때

 

이처럼 스크립트를 삽입하여 글을 생성하고 해당 페이지에 접속해 보겠습니다. 

 

스크립트가 삽입된 페이지에 접속했을 때

 

스크립트가 삽입된 페이지에 접속했더니 삽입했던 스크립트가 실행되는 것을 볼 수 있습니다. 스크립트 삽입이 가능했고 실행까지 정상적으로 이뤄졌기 때문에 XSS 취약점이 존재한다고 판단할 수 있으며 해당 XSS는 저장되어 있던 스크립트가 실행된 케이스이므로 Stored XSS에 해당합니다.


지금까지 XSS 종류 중 Stored XSS에 대해서 알아봤습니다. 다른 글에서 Reflected XSS, DOM-based XSS에 대해서도 알아보고 대응 방안에 대해서도 설명하겠습니다.

반응형
반응형

| SQL Injection

웹 애플리케이션의 취약점을 이용하여 악의적인 SQL 코드를 삽입하는 것. 이를 통해서 데이터 베이스에 비정상적인 접근을 하는 것.

 

| SQL Injection 종류

  • SQL Injection
  • Blind SQL Injection
  • Error based Injection
  • Time based Injection

| SQL Injection 알아보기 (실습)

login_func.php (sql 쿼리 부분) -  로그인 로직

$sql = "select * from member_table where id='$userid' and pw='$userpw'";
        $result = mysqli_query($db_conn, $sql);
        $row = mysqli_fetch_array($result);
        
        if($row){
            session_regenerate_id(true);
            $_SESSION['userid'] = $row['id'];
            return true;
        } else {
            echo "<script>alert('로그인 실패')</script>";
            return false;
        }

 

위 소스코드는 로그인 시 로그인을 처리하는 코드입니다. 해당 로그인 로직을 가진 웹 페이지에서 SQL Injection 이 어떻게 이뤄지는 간단하게 알아보겠습니다. 

 

▶️ 정상적인 로그인 과정

로그인-페이지
로그인 페이지

 

로그인 페이지에서 아이디와 비밀번호를 입력하면 쿼리문에 아이디 비밀번호에 입력 값들이 들어가게 됩니다. 즉, 다음과 같습니다.

"select * from member_table where id='아이디' and pw='비밀번호'"

 

 

만약 아이디가 mega이고, 비밀번호가 1234인 계정으로 로그인을 하면 다음과 같이 쿼리문이 이뤄집니다.

"select * from member_table where id='mega' and pw='1234'"

 

 

해당 계정으로 로그인을 하면 정상적으로 로그인이 되는 것을 볼  수 있습니다.

로그인 성공 시

 

 

이번엔 로그인을 시도할 때 비정상적인 로그인 방법으로 시도 해보겠습니다. 


▶️ 비정상적인 로그인 과정

❓만약 다음과 같이 아이디와 비밀번호를 입력했다면?

아이디 : mega’ or ‘1’=’1

비밀번호 : 1234

비정상적인 로그인 시도

 

이렇게 비정상적인 방법으로 로그인을 시도해보겠습니다.

비정상정인 아이디로 로그인 성공

 

분명 원래 아이디가 mega인데 mega' or '1'='1 을 입력했더니 로그인이 된 상황입니다. 

이런 식으로 임의의 쿼리를 삽입하여 DB에 비정상적인 접근을 하는 것을 SQL Injection 이라고 합니다.

 

이제 SQL Injection이 어떻게 가능한 건지에 대해서 알아보겠습니다.


❓SQL Injection이 어떻게 발생했는가?

로그인을 할 때, 사용자가 아이디와 비밀번호를 입력하면 그 정보를 가지고 DB 안에 있는 정보와 비교하여 일치하면 로그인, 불일치하면 로그인 실패로 이어지게 됩니다. 정상적인 로그인 시도와, 비정상적인 로그인 시도를 했을 때의 DB가 어떤 응답을 하고 있는지 살펴보면서 SQL Injection에 대해서 이해해 보겠습니다.

우선, DB에 있는 회원정보 테이블입니다.

회원 정보 테이블 - 계정 정보가 들어가 있습니다.

 

아까 정상적인 로그인  시도할 때 아이디: mega, 비밀번호: 1234로 입력하고 로그인을 했었습니다. 이 때의 sql 쿼리를 DB에게 전송한다면 다음과 같은 결과를 반환 합니다.

 

아이디와 비밀번호를 입력했을 때
결과

 

결과 사진을 보면 sql 쿼리에 의해 아이디가 mega, 비밀번호가 1234인 계정을 가져오고 있는 모습입니다. 이번엔 잘못된 입력으로 로그인했을 때 어떤 결과값을 반환하는지 확인해 보겠습니다.

잘못된 아이디, 비밀번호 입력했을 때
결과

 

잘못된 아이디를 통해 비정상적인 로그인을 할 때와 정상적인 아이디를 통해 로그인을 시도할 때 DB는 같은 결과를 반환하고 있기에 로그인이 가능했던 것입니다. or '1'='1을 추가했는데 왜 같은 결과가 나오지?라고 생각해 볼 수 있는데 이는 비교 연산자의 우선순위 때문에 발생하게 됩니다.

 

id='mega' or '1'='1' and pw='1234' 즉, 빨간색으로 밑줄 되어있는 부분에서 연산이 먼저 일어나기 때문입니다. 

'1'='1' and pw='1234'을 비교하면,  and 조건은 비교하는 두 조건이 모두 참이 되어야 하며 1과 1은 같고 비밀번호(pw)도 1234가 맞기 때문에 true가 되게 됩니다. 그다음에 or을 연산하는데 or 연산자는 비교할 때 하나라도 참이라면 참이 되게 됩니다.

 

id='mega' or ('1'='1' and pw='1234') 이렇게 연산이 이뤄지게 되는데 id가 mega인 계정이 DB 내부에 있기 때문에 id='mega'는 참이 되게 됩니다. or 연산은 하나라도 참이면 참이기 때문에 where절이 참이되며 아이디가 mega인 계정을 DB는 반환하게 됩니다.

 

*** id='mega'(이미 여기가 참) or (or 뒤에 falsty한 값이 와도 or 앞에가 이미 참이므로 전체는 참)  ***

 

다시 정리하면, id가 mega인 계정이 DB 내부에 있고(참), or 연산자로 인해 sql 쿼리의 where 절이 전체 적으로 참이 되어 id가 mega인 계정을 가져오게 되는 것입니다. 따라서 해당 로그인 인증 로직을 별다른 필터링없이 그대로 사용 중이라면 비밀번호를 아무거나 입력해도 로그인이 가능하게 됩니다. 아이디만 알고 있다면 sql 쿼리의 where 조건이 전부 참이 되도록 만들 수 있기 때문에 DB는 정상적으로 로그인했을 때와 같은 결과를 반환하게 됩니다.

 

정말로 아무 비밀번호를 입력했을 때 정상적으로 로그인 했을 때 와 같은 결과를 반환하는지 확인해보겠습니다.

아이디: ' or '1'='1 / 비밀번호: (아무거나 입력)
결과

 

결과를 확인해보면 DB가 정상적으로 로그인했을 때와 같은 결과를 반환하고 있다는 것을 알 수 있습니다.


 

이렇게 간단한 실습을 통해 SQL Injection에 대해서 알아봤는데 해당 글은 "SQL injection이 이런 거구나" 정도로 생각하시면 될 거 같습니다. 앞으로는 SQLInjection 종류에 대해 설명하고, 해당 SQL Injection 공격 기법이 어떤 식으로 사용되며 어떻게 DB 데이터를 추출까지 가게 되는지에 대해서 다뤄보겠습니다.

반응형

+ Recent posts