◆ SQL 기본지식
SQL이란?
Structured Query Language의 약자. 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어이다. 문법이 단순한편이고, 모든 DBMS에서 사용 가능. 인터프리터 언어, 대소문자 구별 없음.
DBMS와 소통할 수 있는 언어, 데이터베이스가 이해할 수 있는 질의 언어
쿼리 : 데이터베이스에 정보를 요청하는 것. 웹 서버에 특정한 정보를 보여달라는 웹 클라이언트 요청에 의한 처리. 대개 데이터베이스로부터 특정한 주제어나 어귀를 찾기 위해 사용됨.
쿼리의 3가지 방법
1. 메뉴에서 매개변수를 선택
2. 예제에 의한 쿼리
3. 쿼리 언어의 사용
테이블 : 세로줄과 가로줄의 모델을 이용해 정렬된 데이터 값의 집합.
> 관계형 테이블 : 관계형 데이터베이스(key와 value들의 간단한 관계를 테이블화 시킨 전산정보 데이터베이스)의 사용자 데이터를 보유하는 기본 구조
> 오브젝트 테이블 : 세로줄을 정의하는 객체 형을 이용하는 테이블. 정의된 형의 오브젝트의 인스턴스를 보유할 목적으로 정의
◆ SQL 문법의 종류
*데이터베이스 언어 : 데이터베이스를 구축하고 이용하기 위한 데이터베이스 시스템과의 통신 수단
데이터 정의 언어 (DDL)
DB구조, 데이터 형식, 접근 방식 등 DB를 구축하거나 수정할 목적으로 사용하는 언어
데이터 정의 언어는 번역한 결과가 데이터사전이라는 특별한 파일에 여러개의 테이블로서 저장됨.
데이터 정의 언어 예제
CREATE : 새로운 데이터베이스 테이블, VIEW, 인덱스, 저장 프로시저 생성
ALTER : 기존 데이터베이스 개체에 대한 변경. RENAME의 역할
DROP : 기존 데이터베이스 테이블, 뷰, 인덱스, 저장 프로시저를 제거
TRUNCATE : 테이블에서 데이터를 돌이킬 수 없는 제거
*저장 프로시저 : 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리의 집합
*VIEW : SQL에서 하나 이상의 테이블에서 원하는 모든 데이터를 선택해, 그들을 사용자 정의해 나타낸 것
*인덱스 : 데이터베이스 분야에 있어서 테이블에 대한 동작의 속도를 높여주는 자료 구조
데이터 조작 언어 (DML)
사용자로 하여금 데이터를 처리할 수 있게 하는 도구. 사용자와 DBMS간의 인터페이스를 제공
SELECT - 검색(질의) [선택절 : WHERE, GROUP BY, HAVING, ORDER BY)
SELECT [ALL | DISTINCT] 컬럼명 [,컬럼명...]
FROM 테이블명 [,테이블명...]
[WHERE 조건식]
[GROUP BY 컬럼명 [HAVING 조건식]]
[ORDER BY 컬럼명]
GROUP BY 컬럼명[,컬럼명...]
ORDER BY 컬럼명[,컬럼명...]
INSERT - 삽입(등록)
INSERT INTO 테이블_또는_뷰_이름 (컬럼1, [컬럼2, ...]) values (값1, [값2, ...])
INSERT INTO 테이블_또는_뷰_이름 values (값1, [값2, ...])
UPDATE - 업데이트(수정)
UPDATE table_name SET column_name = value [, column_name = value ...] [WHERE condition]
DELETE - 삭제
DELETE FROM 테이블or뷰이름 [WHERE 조건]
데이터 제어 언어 (DCL)
데이터에 대한 액세스를 제어하기 위한 언어
GRANT - 특정 데이터베이스 사용자에게 특정 작업을 수행 권한을 부여
REVOKE - 특정 데이터베이스 이용자에게 부여한 특정 권한을 박탈
권한
CONNECT- 데이터베이스 또는 스키마에 연결하는 권한
SELECT - 데이터베이스에서 데이터를 검색하는 권한
INSERT - 데이터베이스에 데이터를 등록할 수 있는 권한
UPDATE - 데이터베이스의 데이터를 업데이트 할 수 있는 권한
DELETE - 데이터베이스의 데이터를 삭제할 수 있는 권한
USAGE - 스키마 또는 함수와 같은 데이터베이스 개체를 사용할 수 있는 권한
SQL injection
응용 프로그램 보안 상의 허점을 이용해, 악의적인 SQL문을 실행되게 함으로써 데이터베이스를 비정상적으로 조작하는 코드 인젝션 공격 방법. 공격 난이도는 낮지만 성공할 경우 피해가 크다.
사용자가 입력한 값을 서버에서 제대로 검증하지 않아, 서버에서 DB의 쿼리문으로 인식해 DB안의 정보가 노출되거나 인증이 우회되는 취약점
공격 종류
▶ Error based SQL Injection
1. SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'
2. ' OR 1=1 -- 입력
3. SELECT * FROM Users WHERE id = ' ' OR 1=1 -- ' AND password = 'INPUT2' => SELECT * FROM Users
입력값에 대한 검증이 없음을 확인하고, 악의적인 사용자가 임의의 SQL 구문을 주입함.
Users 테이블에 있는 모든 정보를 조회하게 됨으로써 가장 먼저 만들어진 관리자 계정에 로그인 할 수 있게 됨.
예) ▽ 사용자의 아이디와 비밀번호를 확인하고 일치하면 로그인을 하는 PHP 프로그램
$username = $_POST["username"];
$password = $_POST["password"];
$mysqli->query("SELECT * FROM users WHERE username='{$username}' AND password='{$password}'");
▽ 공격자가 유저네임에 admin, 패스워드에 password' OR 1=1 -- 을 입력하면?
SELECT * FROM users WHERE username='admin' and password='password' OR 1=1 --'
1=1은 항상 참이므로 비밀번호를 입력하지 않고 로그인할 수 있게 됨
▶ Union based SQL Injection
Union 키워드 : 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드
정상적인 쿼리문에 Union 키워드를 사용해 인젝션에 성공하면 원하는 쿼리문을 실행할 수 있게 됨.
성공 조건 : Union하는 구 테이블의 컬럼 수가 같아야 함, 데이터 형이 같아야 함.
1. SELECT * FROM Board WHERE title LIKE '%INPUT%' OR contents '%INPUT%'
2. ' UNION SELECT null,id,passwd FROM Users--
3. SELECT * FROM Board WHERE title LIKE '% ' UNION SELECT null,id,passwd FROM Users-- %' AND contents '% UNION SELECT null,id,passwd FROM Users -- %'
▶ Blind SQL Injection
① Boolean based SQL
데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용
서버가 응답하는 로그인 성공과 실패 메시지를 이용해 DB의 테이블 정보 등을 추출 가능
② Time based SQL
서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해 데이터베이스의 정보를 유추하는 기법
▶ Stored Procesure SQL Injection
공격자가 시스템 권한을 획득해야 하므로 공격난이도가 높으나 성공한다면 서버에 직접적인 피해를 입힐 수 있음
▶ Mass SQL Injection
다량의 데이터베이스가 조작되어 큰 피해를 입히는 것. 데이터베이스 값을 변조해 데이터베이스에 악성스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비PC로 감염되게 함.
MISSION : 영화 정보가 들어 있는 데이터베이스에 저장된 사용자들의 아이디와 비밀번호를 획득하라.
Q1. SQL Injection이 통하는지 아닌지 확인해보고, 된다면 데이터베이스의 서버 종류가 무엇인지 확인해보자.
검색란에 작은따옴표를 입력해보자. 만약 SQL Injection 취약점이 존재한다면 SQL 오류 메시지를 출력할 것이다.
*데이터베이스에서는 작은따옴표로 문자 데이터를 구분한다.
다음과 같은 에러가 났다.
Error : 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 '%" at line 1
에러가 났다는 것은 SQL 인젝션이 가능하다는 뜻이다.
에러 내용에서 MySQL인 것도 확인할 수 있다.
*MySQL은 주석이 #이다.
서버에 질의하는 쿼리가 무엇인지 확인할 수 있다.
페이지 소스코드를 보면 /bWAPP/sqli_1.php 로 이어지는 것을 알 수 있는데,

이 sqli_1.php 파일을 들어가보면

다음이 데이터베이스 서버에 질의하는 쿼리임을 알 수 있다.
"SELECT * FROM movies WHERE title LIKE '%"
데이터베이스 종류를 알아내기 위해 다음과 같은 쿼리를 사용했다.
' union select all 1,@@version,database(),4,5,6,7#
@@version으로 버전을, database()로 이름을 알아낼 수 있다.
Q2. 모든 영화자료를 출력해보자.
SELECT의 조건을 참으로 만들면 모든 영화자료를 출력할 수가 있다. 위에서 알아봤듯이, 1=1은 항상 참인 것을 이용하자. 검색창에 ' or 1=1 # 이나 ' or 1=1 -- ' 을 입력하면 영화자료를 출력할 수가 있다. 조건절을 참으로 만들고 뒷부분을 주석처리 한 것이다.
위와 같이 영화자료가 출력된다.
Q3. 데이터베이스에서 호출하는 칼럼 수가 몇 개인지 알아내보자.
이번 미션은 UNION based SQL Injection을 이용하면 알 수 있다.
칼럼 수를 일치시켜야 하기 때문에, 칼럼 수를 늘려가며 몇 개인지 알아낼 것이다.
우선 실험적으로 ' union select all 1# 을 입력해보았다.
그럼 위와 같은 결과가 나온다.
칼럼은 ' union select all 1,2# 이런식으로 숫자를 하나씩 늘려가면 된다.
1부터 차례대로 늘린 결과, 마침내 칼럼 수가 7이라는 것을 알 수 있었다.
Q4. 데이터베이스에 존재하는 모든 테이블명을 출력하라.
information_schema는 DB안에 테이블이 있는지, 몇개나 있는지 알고 싶을 때 사용할 수 있다. 정확히는 서버 내에 존재하는 DB의 메타정보(테이블, 칼럼, 인덱스 등의 스키마 정보)를 모아둔 DB다. 이 안의 모든 테이블은 읽기 전용이라고 한다. 이 안의 tables 에서 생성된 모든 테이블 정보를 확인할 수 있다.
4번째 자리에 table_name을 넣어 출력해보았다.
' union select all 1,2,3,table_name,5,6,7 from information_schema.tables#
table_name은 2,3,4,5 중에 아무데나 넣어도 상관없다.
위 사진에서 영화정보 밑에 있는 숫자를 주목하면
노출되는 컬럼이 2,3,5,4에 위치한 칼럼이기 때문에 네개 중 하나에 넣으면 된다.
영화정보 밑으로 쭉 테이블들이 출력되었다.
테이블이 아주 많다.
4번째 자리에 table_name을 넣으니 그 위치에 맞게 테이블명이 출력되었다.
Q5. 우리가 출력한 테이블 명에서 사용자 정보가 있을 것 같은 테이블이 있다. 그 테이블의 칼럼 명을 출력해보자.
사용자 정보가 있을 법한 테이블은 users인 것 같다.
columns 테이블에서 칼럼 목록을 불러올 수 있다고 한다.
' union select all 1,column_name,3,4,5,6,7 from information_schema.columns#
을 입력해봤는데, 너무 많은 정보가 떴다. where을 사용하면 user로 제한해 users 테이블만 출력할 수 있다.
' union select all 1,column_name,3,4,5,6,7 from information_schema.columns where table_name='users'#
을 입력하면 다음과 같이 나온다.
Q6. 사용자의 id, password, email 정보 등을 출력해보자.
' union select all 1,id,password,email,login,6,7 from users#
login을 출력해야 id가 나오는 것을 확인했기 때문에 login을 추가해주었다.
[참고]
<쿼리>
<테이블>
<SQL>
coding-factory.tistory.com/217
nevertrustbrutus.tistory.com/35
'Web Hacking > BWAPP' 카테고리의 다른 글
[bWAPP(비박스)] SQL Injection (GET/Select) (0) | 2023.03.08 |
---|---|
비박스(bWAPP) - Robots File (0) | 2020.11.22 |
비박스(BWAPP) Broken Auth - Insecure Login Forms (0) | 2020.11.16 |
비박스(BWAPP) SQL Injection - Login Form/Hero (0) | 2020.11.16 |