Wargame.kr을 풀기 전에 먼저 SQL Injection에 대한 이해도와 스킬을 기본적으로 습득하기 위한 좋은 사이트가 LOS라는 조언을 듣고 Lord Of SQL을 풀기 시작했습니다.


일단 기본적으로 SQL Injection을 수행할 때 POST 형태로 수행하지 않고 GET 형태로 많은 문제를 풀이할 수 있습니다. 이는 Fiddler와 같은 다양한 프로그램을 사용하는 것에 치중하지 말고, SQL Injection에 대한 이해도를 높이는 것을 우선하라는 제작자의 배려가 아닌가 싶습니다. 


감사하게도 이러한 페이지에서 공부를 할 수 있어서 실력을 늘리고 여러 노하우를 익힐 수 있었습니다.


 제작자 Rubiya님께 매우 감사드립니다.


서론을 마치고 본격적으로 풀이를 진행해보려고 합니다.


LOS 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.





 

 문제 이해


문제 소스코드는 다음과 같이 PHP 소스를 그대로 보여주는 것을 알 수 있습니다.

<?php
  include "./config.php";
  login_chk();
  dbconnect();
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); // do not try to attack another table, database!
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
  $query = "select id from prob_gremlin where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysql_fetch_array(mysql_query($query));
  if($result['id']) solve("gremlin");
  highlight_file(__FILE__);
?>


위의 문제에서 5번, 6번 라인에서는 SQL Injection 문제이니만큼 Database에 대한 직접적인 공격을 막기 위한 처리가 나타나 있습니다. "Do not try to attack another table, database!" 라고 경고를 적어주었네요. 따라서 5번, 6번 라인에서는 Gremlin 문제를 막기 위한 필터링이 아닌, Gremlin 이외의 공격은 삼가해달라라는 의미입니다.


흠흠. 그렇다면 우리가 GET 형태로 넘겨줄 수 있는 값이 무엇이 있을까 살펴보도록 합시다.


7번 라인을 보시게 되면 우리가 id라는 값과, pw라는 값을 넣어서 실제로 어떻게 SQL문을 완성시켜주는지 알 수 있도록 나타내주었습니다.


물론 5번 라인과 6번 라인에서도 id, pw에 값을 넣어줄 수 있다는 것을 유추할 수 있지만, 직접적으로 어떻게 어떤 데이터로 들어가는지 알려주는 것은 7번 라인입니다.


id='{$_GET[id]}'와 pw='{$_GET[pw]}'를 보아하니 single quote(싱글 쿼터)가 들어가 있으므로 문자열 형태로 값을 넘겨주는 것을 알 수 있습니다. 

그리고 10번 라인을 보면, 만약 SQL 쿼리를 통해 return 되는 값이 존재한다면 문제가 풀리게 되어 있습니다.


따라서 일단 리턴되는 값이 있도록 쿼리를 짜보도록 합시다.






 

 문제 풀이(쿼리)


GET 형태이기 때문에 다음과 같이 쿼리를 짜주었습니다.



 

 id 쪽에 값 삽입


만약 id쪽에 값을 넣고 싶다면 다음과 같이 입력하면 되겠습니다.

 https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?id=%27%20or%201=1%20%23


위의 쿼리는 id=' or 1=1%23이라고 작성해주었습니다. %23은 # 즉, MySQL의 주석입니다.

그렇다면 쿼리는 다음과 같이 들어가게 됩니다.


 query : select id from prob_gremlin where id='' or 1=1 #' and pw=''


이렇게 되면 or 1=1 때문에 참이 되어 리턴되는 값이 존재하게 됩니다.

따라서 if문은 참이되어 문제가 풀리게 됩니다.



 

 pw 쪽에 값 삽입


만약 pw쪽에 값을 넣고 싶다면 다음과 같이 입력하면 되겠습니다.

https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?pw=%27%20or%20%271%27=%271 


위의 쿼리는 pw=' or '1'='1이라고 작성해주었습니다. 

여기서는 주석 처리가 필요없습니다.


이는 다음과 같이 변하기 때문입니다. 눈으로 직접 보시는 게 편합니당 ><


 query : select id from prob_gremlin where id='' and pw='' or '1'='1'


이렇게 되면 '1'='1'과 같이 참인 문법이 완성되게 됩니다. 따라서 따로 주석이 필요없게 됩니다.



 

 DB 백업 명령어


DB 를 백업하기 위해서는 mysqldump라는 명령어를 사용해야 합니다.

 

 단일 데이터베이스 백업


mysqldump 명령어를 이용하여 백업하는 방법은 다음과 같습니다.

mysqldump -u root -p [dbname] > [filename].sql


여기서 [dbname]은 데이터베이스 이름을 말하며, CREATE 명령어로 생성한 하나의 데이터베이스를 의미합니다.

또한 [filename]은 여러분이 저장하고자 하는 이름을 저장하면 됩니다.


 

 전체 데이터베이스 백업


만약 MySQL 내부에 있는 모든 데이터베이스를 한 번에 백업하고자 하면 다음과 같이 사용할 수 있습니다.

mysqldump -u root -p --all-databases > [filename].sql


여기서는 전체 데이터베이스를 백업하는 명령어입니다.

따라서 명령어 내부에 특정 데이터베이스를 특정하는 부분이 존재하지 않습니다.


 

 캐릭터 셋 옵션을 이용한 백업


데이터를 백업할 때 캐릭터 셋을 지정해줄 수 있습니다.

단일 데이터베이스 백업과 거의 비슷한 명령어입니다.

# euckr 캐릭터셋 설정으로 백업함
mysqldump -u root -p --default-character-set=euckr [dbname] -> [filename].sql

# utf8 캐릭터셋 설정으로 백업함
mysqldump -u root -p --default-character-set=utf8 [dbname] -> [filename].sql


 

 특정 테이블만 백업


만약 데이터베이스가 아닌 특정 테이블 데이터만 백업하고자 한다면 다음과 같은 방법으로 명령어를 사용하면 됩니다.

# [dbname] 내에 있는 [table_name] 테이블을 백업함
mysqldump -u root -p [dbname] [table_name] > [filename].sql

# [dbname] 내에 있는 여러 테이블을 백업함
mysqldump -u root -p -B [dbname] --tables [table_name_1] [table_name_2] ... > [filename].sql


만약 백업 명령어에서 [dbname].[table_name] 이런 식으로 사용하시는 걸로 착각하시면 안 됩니다아아!

또한 여러 테이블을 백업할 때 -B 옵션과 --tables 옵션을 적용해주시면 됩니다.


 

 테이블 구조만 백업


만약 테이블의 구조만 백업하고자 하면, 다음과 같은 명령어로 백업하면 됩니다.

테이블의 구조란 데이터베이스 내에 있는 테이블들의 데이터를 제외하고 나머지를 모두 백업한다는 의미입니다.

mysqldump -u root -p --no-data [dbname] > [filename].sql


구조만 백업하기 때문에 --no-data 옵션을 넣어줍니다.


 

 데이터베이스를 XML 형태로 백업


MySQL에서는 데이터베이스를 백업할 때 XML 형태로 백업이 가능합니다.

mysqldump -u root -p --xml [dbname] > [filename].sql







 

 DB 복구 명령어


MySQL에서는 위와 같은 명령어로 백업을 했을 때 해당 파일을 이용하여 복구가 가능합니다.


 

 개별 데이터베이스 복구


데이터베이스를 하나씩 복구하고자 할 때 다음과 같은 명령어로 복구하면 됩니다.

# 쉘에서 복구하는 명령어
mysql -u root -p [dbname] < [filename].sql


-- mysql 내부에서 복구하는 명령어
use [dbname];
source [filename].sql;


 

 전체 데이터베이스 복구


전체 데이터베이스를 한 번에 복구하고자 할 때 다음과 같은 명령어로 복구하면 됩니다.

# 쉘에서 복구하는 명령어
mysql -u root -p < [filename].sql


-- mysql 내부에서 복구하는 명령어
-- use를 이용하여 db를 선택하지 않음
source [filename].sql




 

 뷰(View)란?


뷰(View)란 데이터베이스에 존재하는 일종의 가상 테이블을 말합니다.

이러한 뷰를 이용하여 실제 테이블처럼 행과 열을 가지고 있지만, 실제로 데이터를 저장하고 있지는 않습니다.

즉, 우리가 여러 테이블을 번거롭게 들러서 확인을 해야 할 때 혹은 SELECT 문을 겹겹이 사용해서 어려운 쿼리문으로 조회를 수행해야 할 때 이러한 번거로움을 줄여주는 것이 바로 뷰(View) 입니다.


단, 유의해야 할 점은 MySQL에서 뷰는 단지 다른 테이블이나 다른 뷰에 있는 데이터를 보여주는 역할만을 수행합니다. 이름이 그래서 뷰(View)인가 봅니다. 뷰는 마치 하나의 테이블인 것처럼 보여준다는 장점이 있습니다.





 

 뷰의 특징


 

 뷰의 장점


MySQL에서의 뷰의 장점은 다음과 같습니다.


1. 특정 사용자에게 테이블 전체가 아닌 필요한 필드만 보여줄 수 있음

2. 복잡한 쿼리를 단순화해서 사용할 수 있음

3. 위와 같이 사용한 쿼리를 재사용할 수 있음


 

 뷰의 단점


단, 편리하지만 단점 또한 있습니다.


1. 한 번 정의된 뷰는 변경이 불가능함

2. 삽입, 삭제, 갱신 작업에 많은 제한 사항을 가짐

3. 뷰는 자신만의 인덱스를 가질 수 없음


위와 같은 특징을 유의하여 뷰를 생성하고 사용해보도록 합시다.





 

 뷰 생성 예제


VIEW는 마치 테이블을 만들듯 생성할 수 있습니다. 따라서 CREATE 문을 사용하여 생성해보도록 합시다.

MySQL에서 VIEW를 생성하는 예제는 다음과 같습니다.


 

 단일 테이블의 필요한 필드만 조회하는 뷰 명령어

-- VIEW 생성 명령어
CREATE VIEW [view_name] AS \
SELECT [field_name_1], [field_name_2] ... \
FROM [table_name] \
WHERE [조건];


위의 명령에서는 하나의 테이블에서 필요한 필드의 내용만 가져오기 위한 명령어를 작성해보았습니다.

이는 테이블이 하나밖에 없기 때문입니다.



 

 여러 테이블의 필요한 필드를 조회하는 뷰 명령어


만약 여러분이 여러 테이블의 내용을 섞어서 보고싶다면 다음과 같은 방법을 사용해보도록 합시다.


-- 여러 테이블을 조회하는 VIEW 생성 명령어
CREATE VIEW [view_name] AS \
SELECT a.[field_name_1], b.[field_name_2] \
FROM [table_name_1] AS a, [table_name_2] AS b \
WHERE [조건];


위의 명령어는 table_name_1과 table_name_2의 두 테이블에서 각각 field_name_1과 field_name_2를 가져오는 명령어입니다.

field_name_1은 table_name_1에 있는 필드이고, field_name_2는 마찬가지로 table_name_2에 있는 필드입니다.

여기서 [조건]에 적절한 조건을 넣어줘야 합니다.


예를들면..

- table_name_1의 어떤 필드와 table_name_2의 어떤 필드의 값이 같은 것을 조회한다.

- table_name_1의 어떤 필드의 특정 값을 조회한다.

등이 있겠습니다.


실행 결과는 다음과 같이 나타나게 됩니다.

Field_name_1

Field_name_2

table_name_1에 있는 field_name_1의 값 

table_name_2에 있는 field_name_2의 값 

 ...

... 






 

 뷰 대체 예제


뷰 대체란 기존에 생성했던 뷰를 다시 새로운 뷰로 대체한다는 뜻입니다.

뷰는 한 번 생성하면 변경이 불가능하기 때문에 새로운 뷰로 대체하는 것으로 뷰에 설정한 필드를 대체할 수 있습니다.


 

 뷰 대체 명령어


-- 뷰 대체 명령어
-- 기존의 view_name 이라는 VIEW를 새로운 필드로 설정해줄 수 있음
CREATE OR REPLACE VIEW [view_name] AS \
SELECT [field_name_1], [field_name_2] AS [new_field_name] \
FROM [table_name];


만약 위와 같이 뷰를 대체하게 되면, [field_name_2]라는 이름을 가진 필드가 [new_field_name]이라는 이름으로 대체됩니다.






 

 뷰 사용 예제


생성한 뷰는 일반적인 SELECT 명령어로 사용할 수 있습니다.


-- 생성된 뷰 조회(뷰 이름 : view_name)
SELECT * FROM view_name;


위와 같이 생성된 뷰를 전체 조회하게 되면 원하는 테이블의 원하는 필드 값만 볼 수 있습니다.



DCL(Data Control Language) 명령은 프로그래밍 보다는 MySQL 내부의 데이터를 제어하는 언어입니다.

제어라 하니 애매모호할 수 있겠습니다.

더 자세히 말씀드리자면! 데이터의 보안, 무결성, 회복, 병행 수행제 등을 정의하는데 사용합니다.


DCL의 명령어는 GRANT, REVOKE, COMMIT, ROLLBACK 이라는 명령어가 있습니다.


그런데 역서 COMMIT과 ROLLBACK 명령어는 TCL(Transaction Control Language)이라고 하여 트랜잭션을 제어하는 명령어라고 구분되어 표현되기도 합니다.


하지만 이 포스트에서는 모두 DCL이라고 생각하고 작성하도록 하겠습니다.







 

 GRANT 명령어


GRANT 명령어는 사용자에게 권한을 부여하기 위한 명령어입니다.

MySQL에서 사용자 권한을 주는 방법에는 INSERT 문을 이용하는 방법이 있습니다.

그러나 여기서는 GRANT의 명령어로 권한을 주는 명령어를 살펴보도록 하겠습니다.


-- 사용자 권한 부여 명령어
GRANT ALL PRIVILEGES ON [dbname.table_name] TO [user@host] IDENTIFIED BY 'my_password';


-- 예제 (호스트 : 로컬호스트)
GRANT ALL PRIVILEGES ON testDB.testTable TO myuser@localhost IDENTIFIED BY 'testPassword';

-- 예제 (호스트 : 원격 접속)
GRANT ALL PRIVILEGES ON testDB.testTable TO myuser@'%' IDENTIFIED BY 'testPassword';

-- 예제 (호스트 : 아이피)
GRANT ALL PRIVILEGES ON testDB.testTable TO myuse@192.168.0.100 IDENTIFIED BY 'testPassword';


GRANT 명령어 이후 설정한 권한을 적용해야 합니다.


-- 설정한 권한 적용 명령어
FLUSH PRIVILEGES;


위의 명령어까지 완료하면 이제 GRANT 명령어가 적용됩니다.






 

 REVOKE 명령어


REVOKE 명령어는 GRANT 명령어로 적용한 권한을 해제해주는 명령어입니다.

이 명령어를 사용하면 MySQL에서 사용자 권한을 해제해줄 수 있습니다.


-- 권한 해제 명령어(INSERT, UPDATE, CREATE 권한 해제)
REVOKE insert, update, create ON [dbname.table_name] TO [user@host];

-- 권한 해제 명령어(전체 권한 해제)
REVOKE ALL ON [dbname.table_name] TO [user@host];


위와 같은 예제로 간단히 알아보았습니다.

만약 예제를 통해 해제한 권한이 잘 적용되었는지 확인해보고자 한다면 다음 명령을 사용해보면 좋습니다.


-- 권한 확인 명령어
SHOW GRANTS FOR [user@host];






 

 COMMIT 명령어


COMMIT 명령어는 작업한 결과를 물리적 디스크로 저장하고, 조작 작업이 정상적으로 완료되었음을 관리자에게 알려주는 명령어입니다.

요약하자면, 작업 결과를 저장 후, 관리자에게 "잘 되었습니다" 하고 알려준다는 것입니다. 이 명령어는 INSERT, UPDATE, DELETE 등의 작업 내용에 대해 데이터가 물리 디스크로 완전히 업데이트되며, 모든 사용자가 변경한 데이터의 결과를 볼 수 있게 됩니다.

이 명령어를 사용하면 MySQL에서 작업한 내용들이 물리적 디스크로 저장/적용되고, 정상적으로 처리되었다면 이를 알려줍니다.


-- 여러분이 INSERT, UPDATE, DELETE 등의 작업을 수행하였다고 가정...

-- 이전 까지의 작업을 완전 저장하는 명령어
COMMIT;


위의 명령어를 보고 조금 맥이 빠질 수 있습니다.

실제로 MySQL과 물리디스크 사이에서 일어나는 일은 매우 복잡하지만, 명령어는 딱 한 단어 뿐입니다.






 

 ROLLBACK 명령어


ROLLBACK 명령어는 작업했던 내용을 원래의 상태로 복구하기 위한 명령입니다. 이는 INSERT, UPDATE, DELETE 와 같은 트랜잭션의 작업 내용을 취소할 수 있습니다.

단! 이 명령어를 사용하는데 있어서 주의해야할 점이 있습니다.

바로 COMMIT 명령어를 사용하기 이전의 상태만 ROLLBACK이 가능하다는 것입니다..!


COMMIT을 하게 되면 위에서 설명드렸다싶이, 물리디스크에 직접 저장하고 알리는 기능이므로, 이미 물리적으로는 이전의 상태가 저장되어 있지 않다는 의미입니다.

따라서, 이전 상태로 되돌릴 수 없습니다.


-- 여러분이 INSERT, UPDATE, DELETE 등의 작업을 수행하였다고 가정...

-- 이전 까지의 작업을 취소하는 명령어
ROLLBACK;


위의 명령어도 사실 별 게 없습니다.

COMMIT과 마찬가지로 단 하나의 단어로만 명령을 수행합니다.










MySQL 명령어는 웹 프로그래밍 할 때, 데이터베이스를 정의하는 내용은 크게 사용되지 않을 수 있습니다.

그러나 DML(Data Manipulation Language) 명령어 즉, 데이터 조작어가 매우 많이 사용됩니다.


이 언어는 PHP, Python Flask, Python Django 등과 같은 서버사이트 언어에서 많이 사용되며, 문법은 MySQL의 방법을 그대로 사용합니다.

때문에 이번에는 DML 명령어들이 대해 정리해보려고 합니다.


명령어의 종류는 SELECT, INSERT, UPDATE, DELETE가 있습니다.

위와 같은 명령어는 조건문을 붙여서 보다 능동적이게 명령어를 활용할 수 있습니다.






 

 SELECT 명령어


SELECT 명령어는 생성되어 있는 테이블에서 원하는 값을 선택하여 가져오고 싶을 때 사용하는 명령어 입니다.

명령어를 살펴보도록 하겠습니다.


-- 기본 선택 명령어(table_name 테이블에서 모두 가져오기)
SELECT * FROM [table_name];

-- WHERE문 포함 선택 명령어(table_name 테이블에서 name이 '깜이군'인 값 가져오기
SELECT * FROM [table_name] WHERE name='깜이군'; 

SELECT * FROM [table_name] WHERE name LIKE '깜이군';

-- 애매한 것도 모두 선택하는 명령어(table_name 테이블에서 name에 '깜이'가 들어가는 것 모두 가져오기)
SELECT * FROM [table_name] WHERE name LIKE '%깜이%';

-- 선택 후 name 컬럼으로 오름차순 정렬하는 명령어(ASC 없어도 가능)
SELECT * FROM [table_name] ORDER BY name;
SELECT * FROM [table_name] ORDER BY name ASC;

-- 선택 후 name 컬럼으로 내림차순 정렬하는 명령어
SELECT * FROM [table_name] ORDER BY name DESC;

-- 선택 후 여러 컬럼으로 정렬하는 명령어(우선순위 name > email)
SELECT * FROM [table_name[ ORDER BY name, email;


위와 같이 다양한 방법으로 SELECT문을 사용할 수 있습니다.

위의 방법 이외에도 다양한 조건문을 활용하거나 MySQL 내의 함수를 활용하여 사용할 수도 있습니다.






 

 INSERT 명령어


INSERT 명령어는 생성되어 있는 테이블에 원하는 값을 삽입하는 기능을 가진 명령어 입니다.

명령어를 살펴보도록 하겠습니다.


-- Table Example
-- CREATE TABLE testTable( idx INT PRIMARY KEY AUTO_INCREMENT,
--	                       name VARCHAR(255) NOT NULL,
--                         email VARCHAR(255) NOT NULL
--                       )CHARSET=utf8;

-- 테이블에 값을 삽입함
INSERT INTO testTable( name, email ) VALUES ('kkamikoon', 'kkamikoon@test.com');

-- idx는 AUTO_INCREMENT라 딱히 설정해주지 않아도 됨


위와 같이 테이블이 있다고 가정하고, 값을 삽입해보았습니다.

설명을 작성해두었지만, idx의 경우 AUTO_INCREMENT이기 때문에 테이블 필드 이름과 데이터 값을 따로 지정해주지 않아도 됩니다.

이는 1씩 자동적으로 증가한다는 의미입니다.






 

 UPDATE 명령어


UPDATE 명령어는 생성되어 있는 테이블에 삽입되어 있는 값을 수정해주는 기능을 가진 명령어입니다.

명령어를 살펴보도록 하겠습니다.


-- Table Example
-- CREATE TABLE testTable( idx INT PRIMARY KEY AUTO_INCREMENT,
--	                       name VARCHAR(255) NOT NULL,
--                         email VARCHAR(255) NOT NULL
--                       )CHARSET=utf8;

-- idx가 1인 컬럼의 name을 변경함
UPDATE testTable SET name='새로운깜이군' WHERE idx=1;

-- 전체 name을 변경함
UPDATE testTable SET name='새로운깜이군';


업데이트는 삽입되어 있는 값을 수정해주는 만큼 조건문이 필요합니다.

수정하고자 하는 값을 특정해주고 변경을 해줘야 원하는 결과를 얻을 수 있습니다.

만약 WHERE문이 없이 UPDATE를 수행한다면 모든 값이 업데이트한 값으로 바뀝니다.






 

 DELETE 명령어


DELETE 명령어는 생성되어 있는 테이블에 삽입되어 있는 값을 삭제해주는 기능을 가진 명령어입니다.

명령어를 살펴보도록 하겠습니다.


-- Table Example
-- CREATE TABLE testTable( idx INT PRIMARY KEY AUTO_INCREMENT,
--	                       name VARCHAR(255) NOT NULL,
--                         email VARCHAR(255) NOT NULL
--                       )CHARSET=utf8;

-- idx가 1인 값을 삭제함
DELETE FROM testTable WHERE idx=1;

-- testTable의 전체 값을 삭제함
DELETE FROM testTable;


DELETE 명령어도 UPDATE와 마찬가지로 값을 특정해주지 않으면 전체 값이 DELETE되는 특징이 있습니다.

원하는 곳을 적절히 삭제하기 위해서는 WHERE문으로 조건을 달아주어야 합니다.



MySQL 명령어는 웹 프로그래밍 하면서 나름 익혔지만, 생각보다 익혀지지 않아서 가끔 헷갈릴 때가 있습니다.

이번 포스트에서는 MySQL 기본 명령어에 대해 알아보도록 합니다.


명령어는 DDL 명령어인 Data Define Language 명령어를 다뤄보려고 합니다.

DDL 명령어란 데이터 정의어로써 테이블과 같은 데이터 구조를 정의하는데 사용됩니다. 또한 데이터 구조를 정의함에 있어서 발생할 수 있는 이슈로 생성, 변경, 삭제, 이름 변경의 명령어도 함께 포함하고 있습니다.

따라서 아래에서 다룰 명령어는 CREATE, DROP, ALTER, RENAME, TRUNCATE의 명령어를 다뤄보려고 합니다.






 

 CREATE 명령어


CREATE 명령어는 테이블을 생성하거나 데이터베이스를 생성하는 명령어입니다.

먼저 각각 데이터베이스 생성, 테이블 생성으로 구분하여 명령어를 살펴보도록 하겠습니다.


 

 데이터베이스 생성


-- 데이터베이스 생성 명령어
CREATE DATABASE [dbname];

-- 데이터베이스 생성 및 속성 설정 명령어
CREATE DATABASE [dbname] CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;


위의 명령어를 보면 되게 되게 간단합니다.

단, 데이터베이스를 생성할 때 속성을 미리 설정할 수 있으므로, 함께 설정하며 생성할 수 있습니다.


 

 테이블 생성


-- 테이블 생성 명령어
CREATE TABLE [tablename] (
	[column_name1] INT PRIMARY KEY AUTO_INCREMENT,
	[column_name2] VARCHAR(255) NOT NULL,
	[column_name3] DATETIME NOT NULL,
)CHARSET=utf8;


테이블 생성 명령도 되게 간단합니디.

위의 명령어에서는 나름 예제로써 NOT NULL, AUTO_INCREMENT 등의 값을 써주었습니다.






 

 DROP 명령어


DROP 명령어는 테이블을 삭제하거나 데이터베이스를 삭제하는 명령어입니다.

먼저 각각 데이터베이스 삭제, 테이블 삭제로 구분하여 명령어를 살펴보도록 하겠습니다.


 

 데이터베이스 삭제


-- 데이터베이스 삭제 명령어
DROP DATABASE [dbname];


CREATE 명령어보다 간단합니다. 삭제하고자 하는 데이터베이스 명을 작성하기만 하면 삭제가 가능합니다.

단 여기서 DROP 위데 DATABASE 라는 단어를 붙여줘야 합니다. 이는 테이블이냐 데이터베이스냐를 구분하기 위해서입니다.


 

 테이블 삭제


-- 테이블 삭제 명령어
DROP TABLE [table_name];


데이터베이스 삭제 명령과 비슷하고, DATABASE 대신 TABLE을 작성하면 됩니다.

크게 어려울 것이 없는 명령어입니다.






 

 ALTER 명령어


ALTER 명령어는 테이블의 내용을 수정할 수 있도록 하는 명령어입니다.

수정하는 명령어인 만큼 사용 방법이 꽤 다양합니다.


-- 테이블에 컬럼 추가하기
ALTER TABLE [table_name] ADD COLUMN [column_name] [column_type];

-- 테이블의 컬럼 타입 변경하기
ALTER TABLE [table_name] MODIFY COLUMN [column_name] [column_type];

-- 테이블의 컬림 이름 변경하기
ALTER TABLE [table_name] CHANGE COLUMN [old_column_name] [new_column_name] [new_column_type];

-- 테이블의 컬럼 삭제하기
ALTER TABLE [table_name] DROP COLUMN [column_name];

-- 테이블에 컬럼 인덱스 주기
ALTER TABLE [table_name] DROP INDEX [index_name];

-- 테이블에 PRIMARY KEY 만들기
ALTER TABLE [table_name] ADD PRIMARY KEY( column_name_on_this_table );

-- 테이블에 PRIMARY KEY 삭제하기
ALTER TABLE [table_name] DROP PRIMARY KEY;

-- 테이블 명 바꾸기
ALTER TABLE [old_table_name] RENAME [new_table_name]; 


위와 같이 ALTER 명령어는 매우 다양한 명령을 지원하고 있습니다.

위의 명령어 사용법을 이용하여 적절히 응용하면 보다 유연한 MySQL 사용이 가능합니다.






 

 RENAME 명령어


RENAME 명령어는 테이블의 이름을 변경하는 명령어 입니다.

데이터베이스의 이름을 변경하고자 하면, 별도의 작업을 해주셔야 합니다.(RENAME을 통해 데이터베이스 이름을 변경할 수 없습니다.)


 

 테이블 이름 변경


-- 테이블 이름 변경 명령어
RENAME TABLE [old_table_name] TO [new_table_name];

-- 여러 테이블 이름 변경 명령어
RENAME TABLE [old_table_name1] TO [new_table_name1], [old_table_name2] TO [new_table_name2];


위와 같이 여러 개의 테이블 이름을 한 번에 변경하거나, 하나의 테이블 이름을 변경해줄 수 있습니다.






 

 TRUNCATE


이 명령어는 DML의 명령어인 DELETE와 DDL 명령어인 DROP과 비슷한 형태로, 데이터를 삭제하는 명령어입니다.

그러나 이 명령어는 위의 두 명령어와는 차이가 있습니다.


DML의 DELETE 명령어의 경우 WHERE문과 같은 조건문을 붙여서 원하는 곳만 삭제할 수 있습니다.

DDL의 DROP 명령어의 경우 테이블 혹은 데이터베이스를 모두 삭제하는 명령어입니다.


TRUNCATE는 DROP 후 CREATE를 하는 특징을 가지고 있습니다. 

이러한 특징을 가진 명령어로써, 차이점은 다음과 같습니다.


 

 DELETE 명령어


데이터를 삭제하고 삭제한 공간을 재사용하기 위한 명령어입니다.


 

 TRUNCATE 명령어


데이터가 존재하던 공간까지 모두 제거합니다.

AUTO_INCREMENT로 지정하여 값이 증가하던 컬럼이 완전 초기화 됩니다.(MySQL 5.0.13 버전 이후)

[Table_name].frm 파일이 아직 유효할 경우, 데이터나 인덱스가 손상된 경우라도 빈 테이블로 재생성이 가능합니다.


-- 테이블의 데이터 삭제 명령어
TRUNCATE TABLE [table_name];








 

 로딩중 표시 함수


Javascript로 로딩중 표시를 하기 위한 함수는 다양한 방법으로 만들 수 있습니다.

그 중에서 제가 생각하기에 굉장히 괜찮은 함수를 소개해보려고 합니다.


function LoadingWithMask() {
	//화면의 높이와 너비를 구합니다.
	var maskHeight = $(document).height();
	var maskWidth  = window.document.body.clientWidth;
	
	//화면에 출력할 마스크를 설정해줍니다.
	var mask       = "<div id='mask' style='position:absolute; z-index:9000; background-color:#000000; display:none; left:0; top:0;'></div>";
	var loadingImg = '';
	 
	loadingImg += "<div id='loadingImg'>";
	loadingImg += " <img src='LoadingImg.gif' style='position: relative; display: block; margin: 0px auto;'/>";
	loadingImg += "</div>";  
 
	//화면에 레이어 추가
	$('body')
		.append(mask)
		.append(loadingImg)
	   
	//마스크의 높이와 너비를 화면 것으로 만들어 전체 화면을 채웁니다.
	$('#mask').css({
			'width' : maskWidth
			, 'height': maskHeight
			, 'opacity' : '0.3'
	}); 
 
	//마스크 표시
	$('#mask').show();   
 
	//로딩중 이미지 표시
	$('#loadingImg').show();
}


이 함수를 실행하게 되면 여러분이 저장해둔 LoadingImg.gif 파일을 로딩하여 보여줍니다.




 

 로딩중 표시 제거 함수


로딩중인 표시를 제거해야할 경우에는 다음과 같은 함수를 실행시키면 됩니다.


function closeLoadingWithMask() {
	$('#mask, #loadingImg').hide();
	$('#mask, #loadingImg').remove();  
}


이 함수를 사용하는 예제와 예제 소스를 보시도록 하겠습니다.




 

 로딩중 예제 소스와 예제


먼저 전체 예제 소스를 먼저 살펴보도록 합시다.

아래의 소스는 예제를 설명하기 위해 조금 각색했습니다.


 

 예제 소스

<script>
function test(imageName) {
	LoadingWithMask('your site\'s image path');
	setTimeout("closeLoadingWithMask()", 3000);
}

function LoadingWithMask(gif) {
	//화면의 높이와 너비를 구합니다.
	var maskHeight = $(document).height();
	var maskWidth  = window.document.body.clientWidth;
	
	//화면에 출력할 마스크를 설정해줍니다.
	var mask       = "<div id='mask' style='position:absolute; z-index:9000; background-color:#000000; display:none; left:0; top:0;'></div>";
	var loadingImg = '';
	 
	loadingImg += " <img src='"+ gif + "' style='position: absolute; display: block; margin: 0px auto;'/>";

	//화면에 레이어 추가
	$('body')
		.append(mask)

	//마스크의 높이와 너비를 화면 것으로 만들어 전체 화면을 채웁니다.
	$('#mask').css({
			'width' : maskWidth,
			'height': maskHeight,
			'opacity' : '0.3'
	}); 
 
	//마스크 표시
	$('#mask').show();
 
	//로딩중 이미지 표시
	$('#loadingImg').append(loadingImg);
	$('#loadingImg').show();
}

function closeLoadingWithMask() {
	$('#mask, #loadingImg').hide();
	$('#mask, #loadingImg').empty();  
}



 

 예제


   






 

 예제에 쓰인 그림 파일


스피너(Pacman)


팩맨(Pacman)


위지스(Wedges)


해당 이미지들은 아래의 사이트에서 얻을 수 있었습니다.


Loading.io 링크

 

 브레인 블리딩(Brain Bleeding)


브레인 블리딩은 KoreLogic에서 소개하는 자바스크립트 난독화 기법입니다. Korelogic의 블로그에서는 자바스크립트를 이용한 공격을 관리자에게 숨기기 위한 용도로 사용될 수 있으며, 이를 위한 방법을 제안한다고 작성되었습니다.

사실 이 기법은 원래 UTF-8이라는 웹 사이트에서 제공되는 기법을 가져와 사용한 것입니다.


브레인 블리딩의 예시는 다음과 같습니다.



 

 JJencode


여기서 사용되는 기법은 UTF-8.jp에서 제안한 JJencoding 기법을 이용하였습니다.

JJencode란 [특정한 문자]와 [$ 문자], [: 문자], [. 문자] 등을 이용하여 문자를 난독화하는 기법입니다.

기존에 문자들을 보다 복잡한 문자로 변경해주는데에 있습니다.


JJencode 예제는 다음과 같습니다.


위의 그림에서 보이는바와 같이 입력할 수 있는 UTF-8 형식의 문자를 이용하여 난독화를 수행하는 것을 볼 수 있습니다.

JJencode 웹 페이지는 다음 링크를 들어가시면 됩니다.


UTF-8.jp의 JJencode 링크


여기서 여러분이 인코딩하고자 하는 global variable name을 입력해주면 그 문자를 이용하여 난독화가 이루어지는 것을 볼 수 있습니다.




 

 브레인퍽(BrainFuck)


요약하면 [난해한 프로그래밍 언어]라고 할 수 있습니다. 이는 1993년 우어반 뮐러(Urban Muller)가 아미넷에 올려 알려진 것이 시초라고 하며, 난해한 프로그래밍 언어 중에서 매우 오래된 녀석이라고 합니다. 브레인퍽이 정말 프로그래밍 언어라고 할 수 있는 이유는 [조건문], [루프문], [배열] 등의 기능이 정말로 존재하며, 이러한 규칙을 이용하여 정말 프로그래밍할 수 있기 때문입니다.


해당 포스트에서는 자세한 언어적 요소를 다루지는 않습니다. 다만, 간략하게 소개만 하도록 하겠습니다.


 

 브레인퍽 구조

브레인퍽은 다음과 같은 일곱 가지 명령(여덟 개의 문자)들로 이루어져 있습니다.


문자

설명

+

테이프가 가리키는 숫자를 1 증가시킵니다.

-

테이프가 가리키는 숫자를 1 감소시킵니다.

>

테이프를 한 칸 오른쪽으로 옮깁니다.

<

테이프를 한 칸 왼쪽으로 옮깁니다.

.

테이프가 가리키는 숫자를 ASCII 문자로 해석해서 출력합니다.

,

문자를 하나 읽어서 ASCII 값을 테이프가 가리키는 위치에 저장합니다. 만약 파일의 끝위치(EOF - End Of File)에서 동작하는 원리는 구현체마다 차이가납니다.

[...]

루프문입니다. 매번 현재 테이브가 가리키는 숫자(매 루프마다 바뀔 수 있습니다.)가 0인지 아닌지 체크하여 조건이 만족되면 계속 안에 들어 있는 코드를 실행합니다.


위의 구조가 상당히 복잡한 것을 알 수 있습니다.

마치 어셈블리어보다 덜 고급지면서 은근 있을 건 다 있는 녀석입니다. 허허...


브레인퍽은 사실 프로그래밍일 깡으로 하기에는 부적절한 언어입니다. 때문에 기존의 코드를 난독화를 위해 사용되기도 합니다.





 

 브레인퍽 난독화 사이트


브레인퍽의 코드를 직접 작성하는 것은 머리가 기계가 아닌 이상 굉장히 어려운 일입니다. 따라서 직접 코딩하지 않고, 복잡한 구조를 이용한 난독화 기법 적용이 있습니다. 이러한 난독화 기법을 제공해주는 사이트가 있어서 소개해보려고 합니다.


DCode - Brainfuck 링크


해당 사이트에서는 두 가지 방법의 서비스를 제공합니다.

하나는 기존의 소스코드를 브레인퍽 코드로 변환해주는 인코딩(Encoding)이 있고, 브레인퍽 소스코드를 원래의 소스로 변환해주는 기능을 가지고 있습니다.


 

 브레인퍽 인코딩

기존의 코드를 브레인퍽 코드로 변경하는 예제를 살펴보도록 하겠습니다.

위와 같은 순서로 원하는 소스코드를 입력하게 되면, 브레인퍽 소스코드로 변환됩니다.




 

 브레인퍽 디코딩

브레인퍽 코드로 변경했다면 다시 원래의 코드로 바꾸는 기능이 필요하지요. 다음과 같은 순서로 난독화한 소스코드를 입력해준다면, 다시 원래의 소스코드를 보여주는 서비스도 함께 제공합니다!




+ Recent posts