본문 바로가기

Security Indicator/Insight

풀어쓴 SQL Injection 공격

manian쪽에 올린 글인데 예를 들어서 설명 하였으므로 참고할 부분이 있을 것입니다.

도움 되시길.

---------------------------

안녕하세요. 바다란입니다.

다른 사이트들이 기능상의 코딩을 못해서 생기는 문제가 아닙니다.
기능상으로는 최적화 되어 있죠. 작은 부분 하나를 신경 쓰지 못해서 생기는 문제입니다.
동일하게 manian 이 사이트도 똑같이 당합니다.

간단하게 말씀 드려 DB에 직접 인자를 전달하는 웹 코딩에 있어서 이 인자값에 대해 검사를 하지 않으면 DB에 직접 명령을 내릴 수 있습니다.

다들 밑에 게시물 보면 바이러스 제품에 걸리고 안 걸리고 이걸 가지고 언급을 많이 하시는데 이건 차후적인 문제입니다. 어떻게 해서 그 웹 소스에 바이러스 코드가 들어 갈 수 있는지가 가장 중요한 관점이 되어야 하지 않을까요?.

문제는 여기에서 부터 시작합니다.

예를 들어 이 글을 입력하는 URL을 보면 다음과 같습니다.
http://manian.dreamwiz.com/board/write.asp?bid=A010101&page=1&cate=6

Write.asp 라는 웹 소스내에 인자는 bid , page , cate 라는 세개의 인자를 가지고 있습니다.
물론 내부에 더 있을 수 있죠. 이 각각 인자를 가지고 DB에 해당하는 인자를 조합한 값에 일치 되는 결과를 돌려주고 그 결과가 화면상에 나타납니다. 그렇다면 bid 는 문자와 숫자가 조합이 되어 있고 page 와 cate 인자는 숫자가 입력 되도록 되어 있습니다.

만약 위의 인자에 다른 값들이 들어가면 어떻게 될까요? DB에서 인자의 구분은 ' 와 같은 인용부호를 통해 이루어 집니다. Bid=A010101 이라는 값에서 DB로 쿼리하기 전에 코딩상에서 'A010101' 이라는 값을 넣어서 select 쿼리가 들어가게 되겠죠. 이 값의 뒤에 ' 문자를 더 입력하면 어떻게 될까요?. 'A010101'' 입력이 되겠죠. 그러면 DB에서는 ' 인용부호가 닫혀지지 않았다는 에러가 발생하게 됩니다. 여기에서 부터 SQL Injection 공격이 이루어 지는 거죠. ' 문자를 입력하거나 And 문자를 입력하였을때 DB에 저장된 결과를 수십번의 반복 쿼리를 통해 결과값을 얻어 낼 수가 있습니다. 여기에 관련된 공격은 웹에서 SQL Injection 관련 문서를 찾으면 다수 나올 껍니다.

page와 cate에는 숫자만 들어 가야 하는데 이건 프로그래머의 가정이죠. 입력하는 사람이 숫자가 아닌 문자를 입력한다면 어떻게 될까요?. 스크립트 상에서 숫자만 있는지를 검색해야 하는데 안할 경우에는 DB로 바로 전달이 됩니다.
브라우저 상으로 볼때는 500 Internal Server error 가 발생되어 실행이 안되는 것으로 보이나 Raw Traffic상에는 DB에서 리턴되어 오는 결과가 저장 되어 있습니다.
Ethereal 등으로 트래픽을 보면 확인 할 수 있습니다.

위의 예에서 보듯이 지난 5월 부터 이루어진 국내사이트의 공격에서 가장 중요한 관점은 이겁니다. 인자에 대한 입력 체크 및 Validation 체크가 핵심입니다.
Type에 대한 체크 및 인자의 입력값에 대한 길이 체크 그리고 특수문자 입력에 대한 처리가 가장 중요한 부분입니다.

http://blog.naver.com/p4ssion/40015866029 게시물에 올려진 내용들도 참고 하시면 될 듯 싶네요.

paros 나 web application scanner 등을 이용하여 인자 단위의 유효성 체크와 SQL Injection 취약성 가능성을 체크 하는 것이 가장 중요합니다. 진단 툴의 경우도 만들어서 쓰고 있는 툴의 예를 들면 ScreammingCSS 라는 CSS 진단하는 펄 스크립이 있습니다. 이걸 변경하고 SQL Injection 이나 인자 단위의 입력값 검증을 하는 루틴을 첨가하면 손쉽게 만들 수 있습니다.

입장이 곤란해서 오픈을 못하는 것이 안타까울 따름입니다.

그럼 ...

------------

답변중에서:

 

로긴 창에 SQL Injection을 시도하는건 작년 까지의 버전입니다.
중국쪽에서 인자 각각에 대해 DB가 에러메시지를 보내는 것을 받아서 Blind SQL Injection 기법으로 DB user 및 계정 정보를 획득 합니다.
위에 설명을 잘 보시면 Form이나 로그인 창에 입력하는게 아닙니다.

길이제한이 없을 경우 이 글의 링크인 http://manian.dreamwiz.com/board/view.asp?bid=A060201&no=116895 에다 no가 숫자만이 아닌 문자도 받는다고 했을때 http://manian.dreamwiz.com/board/view.asp?bid=A060201&no=116895' and db_name() .. 등등 이렇게 쿼리를 하면 어떻게 결과가 나올까요?..
아마도 500 Internal Server error가 뜹니다. 그러나 위의 게시물대로 Raw Traffic을 보면 MSSQL의 경우  결과가 전송되는 것을 확인 할 수 있습니다. 즉 브라우저에 보여지는 것과 웹로그에는 500 Error라고 나타나도 DB와 조회는 가능하다는 거죠.

이 관계를 모르기 때문에 문제가 계속 되는겁니다.
분명히 인자에 대한 길이 제한 및 인자 값에 들어가 있는 특수 문자 제어등과 같은 Input validation check가 안되면 계속 됩니다. 예전과 같은 SQL Injection 로그인 기법을 생각하시면 안됩니다.

웹 프로그래머 이시면 이글의 링크를 예를 들어 bid 와 no 에 값으로 받는 것에 대해 숫자인지 아니면 특수문자가 들어가 있는지 일정 길이 이상이 넘는지를 체크하여 DB에 전송 해야 합니다. 이런 체크가 선행 되지 않으면 DB는 거져 먹는게 되죠.

그럼.