웹 보안

    SQL Injection - 방어 실습(3), 에러 메시지 노출 방지

    SQL Injection - 방어 실습(3), 에러 메시지 노출 방지

    에러 메시지에는 필요한 최소한의 정보만 담는 것이 원칙이다. 앞서 Error Based SQL Injection에서는 공격자가 고의로 에러를 유발시켜 에러 메시지에서 직접적으로 정보를 탈취했다. 따라서 이런 공격을 막기 위해 에러 메시지를 출력하지 않는 코드를 추가했다. 이 코드를 상단에 추가하면 에러 메시지를 출력하지 않는다. Error Based SQL Injection이 불가능해졌다.

    SQL Injection - 방어 실습(2), Prepared Statement

    SQL Injection - 방어 실습(2), Prepared Statement

    Prepared statement(준비된 쿼리, statement) 방식의 DB 쿼리는 원래 동일한 쿼리를 여러 번 반복 실행할 때 성능을 향상시키기 위해 개발되었다. 쿼리에서 데이터가 들어가는 부분을 다 빼놓고 문법만 분석하여 DB서버가 쿼리 계획을 세우고 최적화할 기회를 주고 나서, 최적화된 쿼리에 데이터를 집어넣어 빠르게 반복 실행하려는 목적이었다. 그런데 여기에 성능보다 더 중요한 보안상의 장점이 있다는 사실이 밝혀지면서 이제는 성능보다 보안 때문에 prepared statement를 사용하는 개발자들이 많다. 보안에 도움이 되는 이유는 데이터를 빼고 쿼리 문법만 먼저 분석하는 단계를 거치기 때문이다. 사용자가 입력한 데이터에 위험한 내용이 들어 있더라도, 쿼리 문법을 분석하는 단계에는 그 데이터..

    SQL Injection - 방어 실습(1), 입력값 검증

    SQL Injection - 방어 실습(1), 입력값 검증

    이전 글들에서 SQL Injection에 취약한 웹 사이트를 만들고 공격해 봤다. 이제 SQL Injection에 대한 방어 코드를 작성해 보려고 한다. 첫 번째로 사용자의 입력값에 대한 검증이다. JavaScript를 이용해 특수문자나 sql 예약어를 입력했을 경우 form 제출을 막아 DB에 쿼리가 전달되지 않도록 했다. const checkSearchKeyword = () => { let keyword = document.getElementById("search_input").value; if (keyword.length > 0) { //특수문자 제거 let expText = /[%=*>

    SQL Injection - 공격 실습(4), Blind SQL Injection

    SQL Injection - 공격 실습(4), Blind SQL Injection

    Blind SQL Injection은 Boolean-Based와 Time-Based 두 종류가 있다. Boolean-Based: 참·거짓을 반환하는 요소를 이용하여 원하는 정보를 탈취하는 공격 기법 Time-Based: 개발자가 참·거짓을 드러내지 않도록 설정했을 경우, sleep 함수를 이용하여 참·거짓을 유추하는 공격 기법 쉽게 말해 참인지 거짓인지를 판별하고 싶은 구문을 삽입하여 원하는 정보를 유추해 나가는 공격이다. 예를 들어 DB명의 길이가 얼마인지를 알아내고 싶다면 스무고개를 하듯이 DB명 길이가 5보다 큰가? DB명 길이가 3보다 큰가? DB명 길이가 4인가? 를 질문하며 웹 페이지의 참·거짓을 반환하는 요소에서 답을 얻는 것이다. 내가 만든 웹 페이지에서는 로그인의 성공·실패 여부를 반환하..

    SQL Injection - 공격 실습(3), Error Based SQL Injection

    SQL Injection - 공격 실습(3), Error Based SQL Injection

    이어서 게시판 페이지에서 Error Based SQL Injection을 진행했다. 고의로 에러를 유발시켜 에러 메시지에서 직접적으로 정보를 탈취하는 방법이다. UPDATEXML 함수를 사용했는데, UPDATEXML함수는 XMLType인스턴스와 XPath값의 쌍으로 인자를 지정하여서 업데이트된 값을 가지는 XMLType 인스턴스를 반환하는 함수다. ' and updatexml(null, concat(0x3a, ( "원하는 쿼리 입력" )), null)# 형식으로 입력해서 updatexml의 문법은 맞추되 논리적 에러를 포함하도록 하면 에러가 출력되면서 원하는 정보를 얻을 수 있다. DB 이름 알아내기 ' and updatexml(null, concat(0x3a, (select database())), n..

    SQL Injection - 공격 실습(2), UNION Based SQL Injection

    SQL Injection - 공격 실습(2), UNION Based SQL Injection

    이어서 로그인 페이지에서 UNION Based SQL Injection을 진행했다. SQL에서 UNION이라는 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여준다. 정상적인 쿼리문에 UNION 키워드를 사용하여 인젝션에 성공하면 원하는 쿼리문을 실행할 수 있다. UNION 키워드를 사용하려면 UNION하려는 두 테이블의 컬럼 수가 같아야 하기 때문에 컬럼 수를 먼저 구하고, 출력되는 컬럼을 파악해 원하는 정보를 탈취하게 된다. 컬럼 수 확인 ' UNION SELECT ALL 1# 검색 시 컬럼 수가 맞지 않는다는 오류 메시지가 출력된다. 뒤의 숫자를 하나씩 늘려가며 입력하다 보면 ' UNION SELECT ALL 1,2,3,4,5,6,7,8,9# 을 검색했을 때 오류 메시지가 출력되..

    SQL Injection - 공격 실습(1), 로그인 우회

    SQL Injection - 공격 실습(1), 로그인 우회

    모의 해킹 사이트를 만들었으니 SQL Injection을 직접 해보면서 공격 원리를 파악해 보자. 첫 번째로 로그인 페이지에서 로그인 우회를 시도했다. ID 칸에 ' or 1=1#를 입력하면 올바른 ID/PW를 입력하지 않아도 로그인에 성공한다. DB에 보내는 쿼리를 다시 살펴보면 $sql="SELECT * FROM user_info where uid='$username'&&pw='$userpw'"; 이다. ' or 1=1#을 입력했을 때 실제로 보내지는 쿼리는 SELECT * FROM user_info where uid='' or 1=1#'&&pw='$userpw' 인 것이다. '로 uid 정보를 전달하는 부분을 닫아버리고, 항상 참인 1=1 조건을 or로 연결한 후 뒷부분은 #로 주석 처리 한다. 결..

    SQL Injection - 모의 해킹 사이트 구축(3)

    SQL Injection - 모의 해킹 사이트 구축(3)

    게시판 페이지 1. 게시글 DB에 저장되어 있는 정보를 가져와 출력한다. 2. 사용자는 원하는 단어로 제목을 검색할 수 있다. DB 구축 swsecsql DB에 board 테이블을 만들었다. 글 번호(자동 설정됨), 글 작성자 이름, ID, PW, 성별, 이메일, 주소, 글 제목, 글 생성 시간을 저장한다. 이 정보를 가져와 글 번호, 글 제목, 작성자 ID, 글 생성 시간만 출력하는데, 만약 SQL Injection 공격을 당한다면 이 테이블의 정보가 모두 유출될 수 있다. 게시판 페이지 코드 swsecsql DB에 접속해 글 번호 순으로 정렬해 정보를 가져온다. No Result found! 사용자가 입력한 검색어를 검색하는 쿼리를 보내 가져온다. 홀수 행과 짝수 행의 색깔을 다르게 출력하기 위해 분..