SQL 기초
<SQL 기능에 따른 분류>
데이터 정의어(DDL)
: 테이블이나 관계의 구조를 생성하는데 사용하며 CREATE, ALTER, DROP문 등이 있다.
데이터 조작어(DML)
: 테이블에 데이터를 검색, 삽입, 수정, 삭제하는데 사용하며 SELECT, INSERT, DELETE, UPDATE문 등이 있다.
데이터 제어어(DCL)
: 데이터의 사용 권한을 관리하는데 사용하며, GRANT, REVOKE문 등이 있다.
<SELECT 문 / Query 문>
select 명령문:
select 컬럼명 from 테이블명 where 조건절; |
Like
'김%' - 김으로 시작하는 단어
'%김%' - 김이 포함되는 단어
'%김' - 김으로 끝나는 단어
<SQL injection>
임의의 SQL 코드를 주입해서 데이터베이스가 비정상적인 동작을 하게 만드는 공격이다. 공격의 난이도는 낮은 편이지만 그에 비해 피해 정도가 매우 크다. OWASP에서도 수년 동안 인젝션 기법이 보안 위협 1순위로 분류되는 만큼 보안에 각별한 주의가 필요하다.
① 논리적 에러를 이용한 SQL Injection
SELECT * FROM User WHERE id='INPUT1' AND password='INPUT2' ∨
SELECT * FROM User WHERE id='' OR 1=1 --' AND password='INPUT2''
' OR 1=1 --을 주입해서 WHERE절을 모두 참으로 만들고 뒤쪽 구문은 주석 처리 시켜주면 User테이블에 있는 모든 내용을 조회할 수 있다.
② Union 명령어를 이용한 SQL Injection
SQL 에서 Union 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드이다.
정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다. Union Injection을 성공하기 위해서는 Union 하는 두 테이블의 컬럼 수와 데이터 형이 같아야 한다.
SELECT * FROM Board WHERE title LIKE '%INPUT%' OR contents '%INPUT%'
∨
SELECT * FROM Board WHERE title LIKE '% ' UNION SELECT null, id, passwd FROM Users -- %' AND contents '%' UNION SELECT null, id, passwd FROM Users --%'
input으로 Union 키워드와 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐서서 하나의 테이블로 보여지게 된다. 위 코드는 사용자의 id와 passwd를 요청하는 쿼리문이다. 인젝션이 성공하게 되면, 사용자의 개인정보가 게시글과 함께 화면에 보여지게 된다.
<테이블과 필드의 정의>
테이블과 필드 | 정의 |
information_schema.schemata | 데이터베이스와 관련된 정보를 가진 테이블 |
schema_name | 모든 데이터베이스의 이름 값을 가진 필드 |
information_schema.tables | 테이블과 관련된 정보를 가진 테이블 |
tables_name | 모든 테이블의 이름 값을 가진 필드 |
information_schema.columns | 필드와 관련된 정보를 가진 테이블 |
column_name | 모든 필드의 이름 값을 가진 필드 |
<Union 구문을 통한 DB 구조파악 순서>
- order by를 통한 column 갯수 확인
- DB 버전 정보 확인
- database 정보 확인
- table 정보 확인
- user 정보 확인
- column 정보 확인
- recode 정보 확인
<시스템 변수 및 함수>
시스템 변수 및 함수 | 설명 |
database() | 데이터베이스 명을 알려주는 함수 |
user() | 현재 사용자의 아이디 |
system_user() | 최고 권한 사용자의 아이디 |
@@version | 데이터베이스 서버의 버전 |
@@datadir | 데이터베이스 서버가 존재하는 디렉토리 |
SQL Injection – GET/search
Quest. SQL Injection이 통하는지 아닌지 확인해보고, SQL Injection이 된다면 데이터베이스의 서버 종류가 무엇인지 확인해봅시다.
데이터베이스에서는 작은따옴표(')로 문자열을 구분한다. 따라서 '만 입력했을 경우 쿼리 문법에 오류가 생기면서 오류 메세지가 출력된다. 오류 메세지를 보면 데이터베이스 서버가 MySQL인 것을 확인할 수 있다.
Quest. 모든 영화자료를 출력해봅시다.
SELECT * FROM movies WHERE title LIKE ' '에서 ' OR 1=1#를 추가해서 조건절이 항상 참이 되게했다.
Quest. 데이터베이스에서 호출하는 칼럼 수가 몇 개인지 알아내세요.
UNION문은 이전 쿼리에서 사용하는 SELECT문의 컬럼 수와 현재 SELECT문의 컬럼 수가 일치해야 한다. 따라서 양쪽 컬럼 수가 일치할 때까지 숫자를 높여가면 데이터베이스에서 호출하는 컬럼 수를 알 수 있다.
확인 결과 데이터베이스에서 호출하는 컬럼 수는 7개이다.
Quest. 데이터베이스에 존재하는 모든 테이블 명을 출력하세요.
information_schema.tables의 table_name 칼럼에서 테이블 이름을 확인할 수 있다.
' union select all 1,table_name,3,4,5,6,7 from information_schema.tables#
Quest. 우리가 출력한 테이블 명에서 사용자 정보가 있을 것 같은 테이블이 있습니다. 그 테이블의 칼럼 명을 출력해봅시다.
information_schema.columns에서 칼럼 이름은 column_name 칼럼에서 확인할 수 있다.
사용자 정보는 users 테이블에 있으므로 users 테이블의 칼럼 명을 출력해야 한다.
where을 사용해서 table_name='users'로 제한해주면 users 테이블의 칼럼 명만 출력된다.
' union select all 1,column_name,3,4,5,6,7 from information_schema.columns where table_name='users'#
Quest. 사용자의 id, password, email 정보 등을 출력해봅시다.
사용자의 정보는 users 테이블에 있고, 테이블에 id, password, email 칼럼이 있는 것을 위에서 확인했다.
따라서 users 테이블에서 id, password, email 칼럼을 출력하면 된다. 그러나 id는 순서번호만 나오기 때문에 id 대신 login 칼럼을 출력했다.
' union select all 1,login,3,email,password,6,7 from users#
'Study > Web Hacking' 카테고리의 다른 글
[bWAPP] Broken Auth. - Insecure Login Forms/Robots File (0) | 2020.10.31 |
---|---|
[bWAPP] SQL Injection (Login Form/Hero) (0) | 2020.10.04 |
[bWAPP] HTML Injection - Stored (Blog) (0) | 2020.09.20 |
[bWAPP] HTML Injection - Reflected (POST) (0) | 2020.09.19 |
[bWAPP] HTML Injection – Reflected(GET) (0) | 2020.09.12 |