본문 바로가기

WEB HACKING

[SWING] Web Hacking 04

과제 1
Server

 

Server

 

네트워크에서 클라이언트로 여러 가지 서비스를 제공(serve)

 

서비스 : 카카오톡, 인스타그램 등 인터넷을 통해 제공받는 모든 정보

네트워크 : 서버와 클라이언트가 서로 통신할 수 있게 다리 역할을 하는 기술

 

Web Server

 

클라이언트가 서버에 페이지 요청 시 정적 컨텐츠를 제공하는 서버

 

정적 컨텐츠 (.html, .png, .css)

ex) 보이는 부분에서 기기나 시점에 따라 변하지 않는 부분으로 네이버 검색창의 로고나 메인 페이지 검색창과 같은 부분.

1) HTTP 서버 (소프트웨어)가 있는 컴퓨터로 구성

2) 서버가 파일을 요청한 브라우저에게 전송

 

동적 컨텐츠 (JSP)

ex) 로그인한 유저에 따라 다르게 보이는 프로필 창과 같은 부분.

1) 클라이언트 요청에 따라 다양한 화면 제공

2) 파일 제공 + 웹 어플리케이션 서버와 직접 통신

 

<작동 순서>

1. 클라이언트 (브라우저) -> 서버 : 서비스 요청

2. 서버 : 요청에 응답하여 처리 수행

3. 서버 : 처리 결과를 클라이언트에게 반환

4. 클라이언트 : 처리 결과를 받음

 

DB

Database

데이터의 집합

여러 사람이 공유할 목적으로 방대한 데이터를 체계적으로 정리하여 저장하는 서버

 

DBMS

데이터베이스를 관리하고 운영하는 소프트웨어

계층형, 망형, 관계형(대부분)

ex) MySQL, MariaDB 등

 

SQL(Structured Query Language)

관계형 데이터베이스에서 사용되는 언어로 SQL문은 DDL과 DML로 나뉘는데

DDL은 Create table, Alter table, Drop table 등 테이블을 만드는데 사용되는 명령어이고

DML은 Select, Insert, Delete, Update 처럼 테이블 속 데이터를 수정하는 명령어이다.

 

 

MySQL 사용 실습

 

MySQL :: Download MySQL Installer

 

MySQL :: Download MySQL Installer

Select Operating System: Select Operating System… Microsoft Windows Select OS Version: All Windows (x86, 32-bit) Windows (x86, 32-bit), MSI Installer 8.0.31 5.5M (mysql-installer-web-community-8.0.31.0.msi) MD5: 7a83203e24f873b49fa2df2f1a58eca6 | Signatu

dev.mysql.com

MySQL 다운로드 및 설치하기(MySQL Community 8.0) (hanbit.co.kr)

 

MySQL 다운로드 및 설치하기(MySQL Community 8.0)

SQL을 본격적으로 사용하려면 DBMS를 설치해야 합니다. 여러 가지 DBMS 중에서 MySQL 설치 하는 방법을 알아보고, 정상적으로 설치가 되었는지 확인하는 방법을 알아보겠습니다. 2021년 10월 기준 MySQL

hongong.hanbit.co.kr

 

MySQL이 없기에 위위 링크에서 위 링크를 참고해 다운로드 받았다.

 

설치하다가 저런 오류가 났는데 컴퓨터 이름이 한글이면 영어로 바꾸어야 한다는 듯 하다.

설정 -> 시스템 -> 정보 -> 이 컴퓨터 이름 바꾸기 -> 다시 시작

그리고 MySQL과 관련된걸 모두 삭제하고 재부팅한 뒤에 다시 깔아야... 한다.

Installer 에서 깔던 것을 Remove 눌러서 지우고 Installer와 이미 깔린 폴더를 지우고 Program Data도 비워줘야 한다!

 

1. MySQL 접속

*MySQL : 가장 많이 사용하는 관계형 데이터베이스 관리 시스템

 

 

mysql -uroot -p1002 mysql

(기본 비밀번호는 1111이지만 깔 때 root 계정의 비밀번호를 지정해버렸다)

 

 

2. 데이터베이스 확인, 생성, 접속

show
create
use

show databases;
create database swingweb;
use swingweb;

 

 

3. 테이블 생성

CREATE TABLE 테이블 이름 (컬럼명 데이터타입... , 컬럼명 데이터타입... , ...);
+ 한글 깨짐 방지를 위해 UTF-8 설정

create table member(id varchar(10) not null, name char(15), num char(6))
engine=InnoDB DEFAULT CHARSET=uft8;

 

Inno... 대문자 아이

 

4. 테이블 구조 및 컬럼 유형 확인

desc

desc member;

 

 

5. 테이블에 데이터 삽입 / 모든 컬럼 조회

INSERT INTO 테이블명 VALUES ('넣을 데이터','...');
select * from 테이블명;

insert into member valuses('swing','son','35');
select * from member;

 

 

6. 테이블 데이터 수정

UPDATE 테이블명 SET (변경할 컬럼 설정) WHERE (조건);

update member set num='13' where id='swing';
select * from member;

 

 

7. 테이블 데이터 삭제

DELETE FROM 테이블명 WHERE (조건);

delete from member where id='swing';
select * from member;

 

 

8. MySQL 종료

quit

 

 

*지금부터는 강의안 외 문법입니다.

 

시스템 권한 분류 시스템 권한 설명
USER (사용자) 관련 권한 CREATE USER 사용자 생성 권한
ALTER USER 생성된 사용자의 정보 수정 권한
DROP USER 생성된 사용자의 삭제 권한
SESSION (접속) 관련 권한 CREATE SESSION 데이터베이스 접속 권한
ALTER SESSION 데이터베이스 접속 상태에서 환경 값 변경 권한
TABLE 관련 권한 CREATE TABLE 자신의 테이블 생성 권한
CREATE ANY TABLE 임의의 스키마 소유 테이블 생성 권한
ALTER ANY TABLE 임의의 스키마 소유 테이블 수정 권한
DROP ANY TABLE 임의의 스키마 소유 테이블 삭제 권한
INSERT ANY TABLE 임의의 스키마 소유 테이블 데이터 삽입 권한
UPDATE ANY TABLE 임의의 스키마 소유 테이블 데이터 수정 권한
DELETE ANY TABLE 임의의 스키마 소유 테이블 데이터 삭제 권한
SELECT ANY TABLE 임의의 스키마 소유 테이블 데이터 조회 권한
INDEX (인덱스) 관련 권한 CREATE ANY INDEX 임의의 스키마 소유 테이블의 인덱스 생성 권한
ALTER ANY INDEX 임의의 스키마 소유 테이블의 인덱스 수정 권한
DROP ANY INDEX 임의의 스키마 소유 테이블의 인덱스 삭제 권한
OBJECT 권한 설명
ALTER 객체에 대해 변경 할 수 있는 권한
COMMENT 객체에 대해 COMMENT 할 수 있는 권한
DELETE  객체에 대해 자료를 삭제할 수 있는 권한
GRANT 객체에 대해 GRANT 할 수 있도록 하는 권한
INDEX 인덱스를 생성할 수 있는 권한
RENAME 이름을 변경할 수 있는 권한
INSERT 데이터를 삽입할 수 있는 권한
SELECT 데이터를 조회할 수 있는 권한
UPDATE 데이터를 갱신할 수 있는 권한
EXECUTE 프로시저, 함수, 패키지를 실행할 수 있는 권한
REFERENCES 데이터를 참조할 수 있는 권한

 

DML(Data Manipulation Language)

DDL(Data Definition Language)

10. ALTER

테이블의 제약 조건이나 속성을 수정

ALTER DATABASE 데이터베이스명 CHARACTER SET=문자집합이름;
ALTER DATABASE 데이터베이스명 COLLATE=콜레이션이름;

ALTER TABLE 테이블이름 ADD 필드명 필드타입; (추가)
ALTER TABLE 테이블이름 DROP 필드명; (삭제)
ALTER TABLE 테이블이름 MODIFY COLUMN 필드명 필드타입; (수정)

 

11. DROP

테이블을 삭제 (데이터를 삭제하는 delete와 다르므로 신중하게 사용할 것)

DROP DATABASE 데이터베이스명;
DROP TABLE 테이블명;

 

12. TRUNCATE

테이블의 데이터를 모두 삭제하고 사용하던 기억 공간도 해제.

테이블에 생성된 객체도 삭제.

단, 테이블의 구조만은 삭제되지 않음.

삭제 여부를 묻지 않고 삭제된 데이터는 자동으로 커밋됨.

TRUNCATE TABLE 테이블 이름;

 

13. RENAME

테이블명 변경

인덱스 및 데이터는 변경 없음

테이블 백업을 위해 바꾸는 경우도 있고 그럴 땐 테이블명 앞뒤로 TMP(임시), BAK(백업) 등을 붙여 용도를 나타내기도 함

ALTER TABLE 원본 테이블 RENAME TO 바꾸려는 테이블명;

DCL(Data Control Language)

14. GRANT

사용자에게 접속 권한, 오브젝트 생성 권한, DBA 권한 등 권한을 부여

GRANT 시스템 권한명 [, 시스템 권한명 ... | 롤명]
TO 유저명 [, 유저명... | 롤명 ... |PUBLIC | ​[WITH ADMIN OPTION];

- 시스템 권한명 : 부여할 시스템 권한의 이름
- 롤명 : 권한을 부여할 또는 권한을 받을 롤 (ROLE)의 이름
- 유저명 : 권한을 부여 받을 유저(User) 이름
- PUBLIC : 시스템권한, 또는 데이터베이스 역할을 모든 사용자에게 부여할 수 있다.
- WITH ADMIN OPTION : 권한을 부여 받은 사용자도 부여 받은 권한을 다른 사용자 또는 역할로 부여할 수 있게된다.

GRANT [객체권한명] (컬럼)
ON [객체명]
TO { 유저명 | 롤명 | PUBLC} [WITH GRANT OPTION]

-객체권한명 : 객체에 사용 가능한 권한
- 컬럼명 : 만약 ON 절의 Object 가 Table 이나 View 일 경우
- ON 객체명: Table, VIew, Sequence, Procedure 등
- TO {유저명 | 롤명 | PUBLIC} : 사용자를 일일이 나열 할 수 있고, ROLE 에 소속된 사용자가 될수도 있다.
- WITH GRANT OPTION: 이 옵션을 사용하면 TO 절의 대상도 자신이 받은 권한을 다른 유저에게 부여할수 있다.

에러

 

15. REVOKE

사용자에게 부여한 권한을 회수

REVOKE { 권한명 [, 권한명...] ALL}
ON 객체명
FROM {유저명 [, 유저명...] | 롤명(ROLE) | PUBLIC}
[CASCADE CONSTRAINTS]

-객체 권한의 철회는 그 권한을 부여한 부저야만이 수행할 수 있다.
- CASCADE CONSTRAINT :이 명령어의 사용으로 참조 객체 권한에서 사용된 참조 무결성 제한을 같이 삭제 가능
- WITH GRANT OPTION 으로 객체 권한을 부여한 사용자의 객체 권한을 철회하면
권한을 부여받은 사용자가 부여한 객체 권한 또한 같이 철회되는 종속철회가 발생한다.

에러

TCL(Transaction Control Language)

16. commit

입력한 자료나 수정한 자료에 대해서 또는 삭제한 자료에 대해서 전혀 문제가 없다고 판단되었을 경우

commit 명령어를 통해 트랜잭션을 완료

즉, 최종 확인 겸 주어지는 마지막 기회

 

17. rollback

실행한 sql문장을 취소하고 이것을 실행하기 전으로 돌아가는 것

 

18. savepoint

롤백할때 저장점이 없으면 완전히 처음으로 돌아가버린다.

sql문장에서 돌아가고 싶은 위치가 있을 경우 그 위치를 savepoint로 설정해두면 그 위치로 돌아갈 수 있다.

세이브 포인트 지정은 했는데 롤백이 안된다

 

SQL injection

 

임의의 계정에 로그인 / 계정 삭제 / 데이터베이스 읽기 가능

 

SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위이다. 

OWASP Top10 중 첫 번째에 속해 있으며, 공격이 비교적 쉬운 편이고 공격에 성공할 경우 큰 피해를 입힐 수 있는 공격이다.

 

Error based SQL Injection

논리적 에러를 이용한 SQL Injection

가장 많이 쓰이고, 대중적인 공격 기법이다.

 

 

위의 사진에서 보이는 쿼리문은 일반적으로 로그인 시 많이 사용되는 SQL 구문이다. 해당 구문에서 입력값에 대한 검증이 없음을 확인하고, 악의적인 사용자가 임의의 SQL 구문을 주입하였다. 주입된 내용은 ‘ OR 1=1 --   WHERE 절에 있는 싱글쿼터를 닫아주기 위한 싱글쿼터와 OR 1=1 라는 구문을 이용해 WHERE 절을 모두 참으로 만들고, -- 를 넣어줌으로 뒤의 구문을 모두 주석 처리해주었다.

매우 간단한 구문이지만, 결론적으로 Users 테이블에 있는 모든 정보를 조회하게 됨으로써 가장 먼저 만들어진 계정으로 로그인에 성공하게 된다. 보통은 관리자 계정을 맨 처음 만들기 때문에 관리자 계정에 로그인 할 수 있게 된다. 관리자 계정을 탈취한 악의적인 사용자는 관리자의 권한을 이용해 또 다른 2차피해를 발생시킬 수 있게 된다.

 

  • 에러가 발생되는 사이트에서는 에러 정보들을 이용하여 DB 및 쿼리 구조 등의 정보를 추측 가능

 

EXAMPLE (로그인)

공격 대상 : SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'

공격 예시 : SELECT * FROM Users WHERE id = '' OR 1=1 -- ' AND password = 'INPUT2'

과정 : 싱글쿼터를 닫아주기 위한 싱글쿼터와, OR 1=1 구문을 이용해 WHERE 절을 모두 참으로 만들고, -- 를 넣어줌으로써 뒤의 구문을 모두 주석 처리해버림

결과 : Users 테이블에 있는 모든 정보를 조회하게 됨으로써 가장 먼저 만들어진 계정 (보통 관리자 계정) 으로 로그인할 수 있게 됨 → 관리자 계정 탈취

 

 

Union based SQL Injection

Union 명령어를 이용한 SQL Injection 

SQL 에서 Union 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드이다.

정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다.

Union Injection을 성공하기 위해서는 Union 하는 두 테이블의 컬럼 수가 같아야 하고, 데이터 형이 같아야 한다. 

 

위의 사진에서 보이는 쿼리문은 Board 라는 테이블에서 게시글을 검색하는 쿼리문이다. 입력값을 title  contents 컬럼의 데이터랑 비교한 뒤 비슷한 글자가 있는 게시글을 출력한다. 여기서 입력값으로 Union 키워드와 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐서서 하나의 테이블로 보여지게 된다. 현재 인젝션 한 구문은 사용자의 id passwd를 요청하는 쿼리문이다. 인젝션이 성공하게 되면, 사용자의 개인정보가 게시글과 함께 화면에 보여지게 된다. 

물론 패스워드를 평문으로 데이터베이스에 저장하지는 않겠지만 인젝션이 가능하다는 점에서 이미 그 이상의 보안위험에 노출되어 있다. 이 공격도 역시 입력값에 대한 검증이 없기 때문에 발생하게 되었다.

 

EXAMPLE (게시글 조회)

공격 대상 : SELECT * FROM Board WHERE title LIKE '%INPUT%' OR contents '%INPUT%'

공격 예시 : SELECT * FROM Board WHERE title LIKE '% ' UNION SELECT null,id,passwd FROM Users -- INPUT%' OR contents '%INPUT%'

해설 : 위의 쿼리문은 Board라는 테이블에서 게시글을 검색하는 쿼리문이다. 입력값을 tiltle 과 contents 컬럼의 데이터와 비교한 뒤 비슷한 글자가 있는 게시글을 출력한다. 여기서 입력값으로 UNION 키워드와 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐져서 하나의 테이블로 보여지게 된다.

과정 : 사용자의 id와 passwd를 요청하는 쿼리문을 주입함

결과 : 사용자의 개인정보가 게시글과 함께 화면에 보여짐

 

 

Blind SQL Injection

Boolean based SQL

Blind SQL Injection은 데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용한다.

로그인 폼에 SQL Injection이 가능하다고 가정했을 때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보 등을 추출해 낼 수 있다.

 

 

위의 그림은 Blind Injection을 이용하여 데이터베이스의 테이블 명을 알아내는 방법이다. (MySQL) 인젝션이 가능한 로그인 폼을 통하여 악의적인 사용자는 임의로 가입한 abc123 이라는 아이디와 함께 abc123’ and ASCII(SUBSTR(SELECT name From information_schema.tables WHERE table_type=’base table’ limit 0,1)1,1)) > 100 -- 이라는 구문을 주입한다.

해당구문은 MySQL 에서 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만, 그리고 마지막으로 ASCII 를 통해서 ascii 값으로 변환해준다. 만약에 조회되는 테이블 명이 Users 라면 ‘U’ 자가 ascii 값으로 조회가 될 것이고, 뒤의 100 이라는 숫자 값과 비교를 하게 된다. 거짓이면 로그인 실패가 될 것이고, 참이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교를 하면 된다.  공격자는 이 프로세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아 낼 수 있다.

 

  • 사용되는 SQL문 : limit, SUBSTR, ASCII..
  • 에러가 발생되지 않는 사이트에서는 논리적 에러를 이용하거나 UNION을 이용할 수가 없기 때문에, Blind를 통해 정상적인 쿼리가 수행되는지, 혹은 쿼리가 수행되지 않아 쿼리 결과가 없는지를 판단함

 

EXAMPLE (로그인 폼 통해 DB의 테이블 명 알아내기)

공격 대상 : SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'

공격 예시 : SELECT * FROM Users WHERE id = 'abc123' and ASCII(SUBSTR((SELECT name FROM information_schema.tables WHERE table_type='base table' limit 0,1),1,1)) > 100 (로그인이 될 때까지 시도) -- INPUT1' AND password = 'INPUT2'

해설 : 위의 쿼리문은 DB의 테이블 명을 알아내는 쿼리문이다.

과정 : 임의로 가입한 abc123이라는 아이디와 함께 뒤의 구문을 주입한다. 해당 구문은 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만, ASCII를 통해서 ascii 값으로 변환한다. 만약 조회되는 테이블 명이 Users 라면 'U' 자가 ascii 값으로 조회가 될 것이고, 뒤의 100이라는 숫자 값과 비교하게 된다.

결과 : 거짓이면 로그인 실패가 될 것이고, 참이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교하면 된다. 공격자는 이 프로세스를 자동화 스크립트로 만들어 단기간 내에 테이블 명을 알아낼 수 있다. 

 

 

Blind SQL Injection

Time based SQL

Time Based SQL Injection 도 마찬가지로 서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해서 데이터베이스의 정보를 유추하는 기법이다.

사용되는 함수는 MySQL 기준으로 SLEEP  BENCHMARK .

 

 

위의 그림은 Time based SQL Injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법이다.

로그인 폼에 주입이 되었으며 임의로 abc123 이라는 계정을 생성해두었다.

악의적인 사용자가 abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) – 이라는 구문을 주입하였다.

여기서 LENGTH 함수는 문자열의 길이를 반환하고, DATABASE 함수는 데이터베이스의 이름을 반환한다.

주입된 구문에서, LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 가 동작하고, 거짓이면 동작하지 않는다.

이를 통해서 숫자 1 부분을 조작하여 데이터베이스의 길이를 알아낼 수 있다.

만약에 SLEEP 이라는 단어가 치환처리되어있다면, 또 다른 방법으로 BENCHMARK  WAIT 함수를 사용할 수 있다. BENCHMARK  BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye'));

이런 식으로 사용이 가능하다. 이 구문을 실행 하면 약 4.74초가 걸린다고 한다.

 

  • 쿼리 결과를 특정 시간만큼 지연시키는 것
  • Blind와 마찬가지로 에러가 발생되지 않는 조건에서 사용하며, 참 혹은 거짓이라는 결과값이 나오지 않으므로 시간을 재는 것
  • 궁극적으로는 DB 구조를 파악하기 위함

 

EXAMPLE (로그인 폼 통해 DB의 길이 알아내기)

공격 대상 : SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'

공격 예시 : SELECT * FROM Users WHERE id = 'abc123' OR (LENGTH(DATABASE())=1 (SLEEP 할 때까지 시도) AND SLEEP(2)) -- INPUT1' AND password = 'INPUT2'

해설 : LENGTH는 문자열의 길이를 반환하고, DATABASE는 DB의 이름을 반환한다.

과정 : LENGTH(DATABASE()) = 1 이 참이면 SLEEP(2)가 동작하고, 거짓이면 동작하지 않는다.

결과 : 숫자 1 부분을 조작하여 DB의 길이를 알아낼 수 있다.

예외 : SLEEP이라는 단어가 치환 처리 되어있는 경우, BENCHMARK나 WAIT 함수를 사용할 수 있다.

 

 

Stored Procedure SQL Injection

저장된 프로시저 에서의 SQL Injection

저장 프로시저(Stored Procedure) 은 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것이다.

공격에 사용되는 대표적인 저장 프로시저는 MS-SQL 에 있는 xp_cmdshell윈도우 명령어를 사용할 수 있게 된다.

공격자가 시스템 권한을 획득해야 하므로 공격난이도가 높으나 공격에 성공한다면, 서버에 직접적인 피해를 입힐 수 있는 공격이다.

 

 

Mass SQL Injection

다량의 SQL Injection 공격

2008년에 처음 발견된 공격기법으로 기존 SQL Injection 과 달리 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미한다. 보통 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며, 쿼리문은 HEX 인코딩 방식으로 인코딩 하여 공격한다. 보통 데이터베이스 값을 변조하여 데이터베이스에 악성스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비PC로 감염되게 한다. 이렇게 감염된 좀비 PC들은 DDoS 공격에 사용된다.

 

 

 

[참고한 포스트]

SQL Injection 이란? (SQL 삽입 공격) — 보안과 개발을 다 하고싶은 욕심쟁이 (tistory.com)

[해킹] SQL Injection : 개념 및 공격 기법 (tistory.com)

 

'WEB HACKING' 카테고리의 다른 글

[SWING] Web Hacking 06  (0) 2022.11.19
[SWING] Web Hacking 05  (0) 2022.11.12
[SWING] Web Hacking 03  (0) 2022.09.24
[SWING] Web Hacking 02  (0) 2022.09.20
[SWING] Web Hacking 01  (0) 2022.09.11