[Web Hacking - Server] Background: SQL DML

KyungH·2024년 12월 1일

DH Lecture - Web Hacking

목록 보기
15/17
post-thumbnail

📝 Background: SQL DML

SQL에서는 Data Definition Language (DDL), Data Manipulation Language (DML),
Data Control Language (DCL) 총 세가지의 질의 언어를 제공한다.

그 중 DML은 데이터베이스에서 데이터를 조회, 추가, 삭제, 수정을 수행하는 구문이며
우리가 이용하는 대부분의 기능은 DML로 처리한다고 볼 수 있다.

그렇다면 DML 구문을 사용하는 목적과 형태를 알고 SQL Injection 공격을 이해해보자.


📌 SELECT

SELECT는 데이터를 조회하는 구문이다.

# mysql SELECT Statement https://dev.mysql.com/doc/refman/8.0/en/select.html
SELECT select_expr [, select_expr] ...
FROM table_references
WHERE where_condition
[GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
[ORDER BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

구문에서 볼 수 있듯이 특정 조건을 만족하는 데이터를 찾기위한 WHERE,
조회한 결과를 정렬하거나 특정 부분만을 확인하기 위한 ORDER BY, LIMIT 등이 있다.

설명
SELECT해당 문자열을 시작으로, 조회하기 위한 표현식과 컬럼들에 대해 정의
FROM데이터를 조회할 테이블의 이름
WHERE조회할 데이터에 대한 조건
ORDER BY조회한 결과를 원하는 컬럼 기준으로 정렬
LIMIT조회한 결과에서 행의 갯수와 오프셋을 지정

💡구문 사용 예시

SELECT
    uid, title, boardcontent
FROM board
WHERE boardcontent like '%abc%'
ORDER BY uid DESC
LIMIT 5 

FROM 절을 사용하여 board 테이블의 uid, title, boardcontent 데이터를
검색한 후 WHERE 절을 사용하여 boardcontent 데이터에서 "abc" 문자열이
포함되어 있는지 확인한다. 이렇게 찾은 데이터를 ORDER BY 절을 통해 uid 기준으로
내림차순(DESC) 정렬한 후, 5 개의 행을 결과로 반환한다.


📌 INSERT

INSERT는 데이터를 추가하는 구문이다.

# mysql INSERT Statement https://dev.mysql.com/doc/refman/8.0/en/insert.html
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    { {VALUES | VALUE} (value_list) [, (value_list)] ...
      |
      VALUES row_constructor_list
    }

INSERT 구문에서는 데이터를 추가할 테이블과 컬럼을 정의하는 INTO,
추가할 데이터를 정의하는 VALUES 등이 있다.

설명
INSERT해당 문자열을 시작으로, 추가할 테이블과 데이터를 정의
INTO데이터를 추가할 테이블의 이름과 컬럼을 정의
VALUESINTO 절에서 정의한 테이블의 컬럼에 명시한 데이터들을 추가

💡구문 사용 예시

INSERT 
    INTO board (title, boardcontent)
    VALUES ('title 1', 'content 1'), ('title 2', 'content 2');

INTO 절을 사용하여 테이블과 컬럼을 각각 boardtitle,
boardcontent 로 명시하였고, VALUES 절을 통해 명시한 테이블의
각각의 컬럼에 데이터를 추가하였다. 위의 예시처럼 쿼리 한 줄로 두 개 이상의
데이터를 추가할 수 있다.

➕서브 쿼리 응용

INSERT 
    INTO board (title, boardcontent)
    VALUES ('title 1', (select upw from users where uid='admin'));

서브 쿼리를 통해 다른 테이블에 존재하는 데이터를 추가할 수 있다.
INTO 절을 통해 추가할 테이블과 컬럼을 명시한 부분은 같으나, boardcontent
SELECT 구문을 실행하여 users 테이블에 uid 값이 "admin"인 행을 찾고,
해당하는 행의 upw 데이터를 추가하였다.


📌 UPDATE

UPDATE는 데이터를 수정하는 구문이다.

# mysql UPDATE https://dev.mysql.com/doc/refman/8.0/en/update.html
UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET assignment_list
    [WHERE where_condition]

UPDATE 구문에서 수정할 컬럼과 데이터를 정의하는 SET, 수정할 데이터의
조건을 정의하는 WHERE 등이 있다.

설명
UPDATE해당 문자열을 시작으로, 수정할 테이블을 정의
SET수정할 컬럼과 데이터를 정의
WHERE수정할 행의 조건을 정의

💡구문 사용 예시

UPDATE board
    SET boardcontent = "update content 2"
    WHERE title = 'title 1';

board 테이블의 boardcontent 컬럼을 "update content 2" 문자열로 수정하고,
수정될 데이터의 title 컬럼의 값이 "title 1"인 행인 것을 WHERE로 명시하였다.


📌 DELETE

DELETE는 데이터를 삭제하는 구문이다.

# mysql DELETE https://dev.mysql.com/doc/refman/8.0/en/delete.html
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [[AS] tbl_alias]
    [PARTITION (partition_name [, partition_name] ...)]
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

DELETE 구문에서 삭제할 테이블의 정의하는 FROM, 삭제할 데이터의 조건을
정의하는 WHERE 절이 있다.

설명
DELETE해당 문자열을 시작으로, 이후에 삭제할 테이블을 정의
FROM삭제할 테이블을 정의
WHERE삭제할 행의 조건을 정의

💡구문 사용 예시

DELETE FROM board
    WHERE title = 'title 1';

board 테이블의 title 컬럼이 "title 1"인 행을 삭제하는 것을 알 수 있다.


📌 SQLI

[setup.sql]
CREATE TABLE admin (uid STRING, upw STRING);
CREATE TABLE board (name STRING, text STRING);
INSERT INTO admin (uid, upw) VALUES ('admin', [FLAG]);

Input)
Name: [userInput]
Text: [userInput]

Query)
INSERT INTO board (name, text) VALUES ("", "");

BOARD 출력)
name:
text:

위와 같은 구문에서는 사용자의 입력값을 다로 점검하지 않아 SQLI 취약점이 발생하며,
admin 테이블의 'admin' 사용자의 upw 값에 접근하여 FLAG를 획득할 수 있다.
FLAG 값을 확인하기 위해 board 테이블에 값을 넣어 출력을 해봐야하기 때문에
다음과 같은 서브 쿼리 구문을 작성하여 upw 값을 boardINSERT 할 수 있다.

", (SELECT upw FROM admin WHERE uid="admin"))--


text 컬럼에 admin 테이블로부터 받아온 FLAG 값을 넣어 출력값을 확인한다.


References

Dreamhack 강의 - Background: SQL DML

0개의 댓글