본문 바로가기

1. Web hacking (웹 해킹)/2) 개념 정리

[2020.11.21] Dream Hack - Server-Side Advanced-NoSQL

01 NoSQL 개요

Memcached, HBase, Cassandra, Hypertable

 

Memcached

: 분산 메모리 캐싱 시스템

데이터 베이스의 부하를 줄여 동적 웹 어플리케이션이 속도개선을 위해 사용되기도 한다.

Key-value 쌍으로 이뤄진 간단한 데이터 타입을 저장하며, NoSQL 데이터베이스와 유사하지만 NoSQL처럼 영구적이진 않다. 모든 key-value 쌍을 메모리에 저장하므로 서버장애나 오류가 발생했을 때 저장된 데이터가 모두 손실된다.

Memcached의 용도는 데이터 요청을 가로채어 가능한 경우 이를 캐시(시스템 메모리)에서 직접 서비스하게 만들고, 백엔드 데이터베이스에 연결된 디스크 스토리지 access를 줄이는 것이 목적이다.

미리 계산된 값을 캐시에서 저장하고 조회하게 하며, 요청할 때마다 많은 양의 계산을 피할 수도 있다. 필요량보다 많은 메모를 가졌을 때, 시스템으로부터 메모리를 사용하고 필요로하는 메모리가 부족한 경우 이를 더 쉽게 가져다 사용할 수 있도록 만들어준다.

Memcached를 사용하지 않을 때 분리되어 있는 메모리에 대해 각각의 서버에서 사용할 수 있는 것은 할당된 메모리의 크기만큼인데, Memcached를 적용할 경우에는 논리적으로 결합되어 있기 때문에 각 웹서버는 전체 메모리 캐시만큼의 용량을 사용할 수 있어 효율적으로 메모리를 운영할 수 있다.

 

[ 4가지 주요 데이터 구조 ]

- 캐시 항목을 찾기 위한 해시 테이블

- 캐시가 가득 찼을 때 캐시 항목 제거 순서를 결정하는 LRU

- 키,데이터,플래그 및 포인터들을 담고 있는 캐시 데이터 구조

- 캐시 항목 데이터 메모리 관리자인 슬랩 할당자

 

Memcached 서버는 3가지 기본 명령어를 지원

GET 캐시 항목을 조회, STORE 캐시 항목 추가, DELETE 캐시 항목 제거



Hbase

 

Hadoop의 자체의 한계로 인해 파생되었고 분산된 Columnar DB이며,

Hadoop File System(HDFS)위에 구축되었다.

 

Cassandra

페이스북 플랫폼에서 파생된 카산드라는 성능(performance)을 유지하면서 확장성(scalability)유용성(availability)을 극대화시키는 전략을 위해 아마존과 구글의 다이나모와 빅테이블의 장점을 취했다. 특히 빅테이블에서 가져온 수퍼컬럼 패밀리(supercolumn family) 데이터 모델은 컬럼 인덱스의 편리함, 로그 스트럭처 업데이트, 쿼리 결과 미리보기(materialized view), 그리고 빌트인 캐시를 가능케 해 주었다. 카산드라에 도입된 다이나모의 주요 피처(feature)들은 다음과 같다.

 

Symmetric, P2P 아키텍처

Gossip-based 클러스터 매니지먼트

분산 해시 테이블

- Pluggable partitioning

- Pluggable topology discovery

- Pluggable placement strategies

튜닝 가능한 eventual consistency

구글 빅테이블과 아마존 다이나모의 특징적 장점들을 모두 취해 분산 환경을 위한 최적의 데이터베이스로 발전한 카산드라는 특히 확장성과 데이터 쓰기 속도에 있어 그 장점이 있다. 카산드라는 기존의 RDBMS 시스템에 비해 데이터 변화가 있을 시 오리지널 데이터 파일에 다시 쓰여지지 않는다. 이는 데이터 읽기와 랜덤 데이터 액세스를 일으키지 않는다. 커밋로그와 SSTable은 순차적 쓰기와 함께 새로운 파일로서 디스크로 플러시되기(flushed) 때문이다.

 

Hypertable

 

구글의 대규모 확장형 데이터베이스인 빅테이블을 원형으로 한 오픈소스 분산형 DB,높은 성능과 편의성을 가지고 있다.

 

<특징>

체크포인트

테이블 데이터를 임의의 순서대로 출력하여 하이퍼테이블에 백업시키고,

하이퍼테이블은 항상 체크포인트에서 일관되고 작동 가능한 상태로 되돌아올 수 있다

 

동시성 제어

다중 버전 동시성 제어(MVCC)란 하이퍼테이블이 가지고 있는 기능 중 하나로 수정된 번호로 자동으로 할당된 타임 스탬프를 사용한다.

 

데이터 모델

일련의 관련 열을 사용

 

쿼리 인터페이스

테이블을 생성하고 수정 및 쿼리하기 위한 HQL을 제공하고 이를 통해서 관리 명령을 호출할 수도 있다.

 

스토리지 아키텍처

 

 

02 MongoDB

- 특징

  : Scheme가 존재하지 않아 각 테이블에 대한 특별한 정의 필요 없음

  : JSON형식으로 쿼리 작성 가능

  : 관계형 데이터베이스와 MongoDB의 비교 표 (아래)

 

 

:Query Operator 표 (아래)

- 주요 기능

 

1) 애드혹 쿼리

: 몽고 DB는 필드, 레인지 쿼리, 정규 표현식 검색을 지원한다. 쿼리는 특정 필드의 도큐먼트를 반환할 수 있으며 사용자 지정 자바스크립트 함수를 포함할 수 있다. 쿼리는 주어진 크기의 임의의 결과 샘플을 반환하도록 설정할 수도 있다

 

2) 색인

: 몽고DB 도큐먼트의 필드는 프라이머리 인덱스와 세컨더리 인덱스로 인덱싱 가능

 

3) 리플리케이션

: 몽고DB는 리플리카 세트와 함께 고가용성을 제공한다. 리플리카 세트는 둘 이상의 데이터 사본으로 구성된다. 모든 쓰기와 읽기는 기본값으로 프라이머리 리플리카에서 수행되고, 세컨더리 리플리카는 그 사본을 관리하는 역할을 한다

 

4) 로드 밸런싱

: 몽고DB는 *샤딩을 사용하여 수평으로 스케일링한다. 

*샤드란? 데이터베이스나 웹 검색 엔진의 데이터의 수평 분할

 

5) 파일 스토리지

: 몽고DB는 파일 저장을 위해 로드 밸런싱, 데이터 리플리케이션 기능과 더불어 GridFS라는 이름의 파일 시스템으로 사용할 수 있다. 

*그리드 파일 시스템: 파일 하나를 여러 부분이나 덩어리로 분리시키며 해당 덩어리들 각각을 별도의 도큐먼트로 저장한다.

 

6) 에그리게이션 

: 사용자들이 SQL GROUP BY절이 사용되는 결과의 종류를 취득할 수 있다.

 

- Blind Injection

: DBMS의 함수 또는 연산 과정 등을 이용해 데이터베이스 내에 존재하는 데이터와 사용자 입력을 비교하며, 특정한 조건 발생 시 특별한 응답을 발생시켜 해당 비교에 대한 검증을 수행

: $where, $regex 등을 사용

 

 

03 Redis

  1. NoSQL - Redis
    키-값 기반의 인 - 메모리 데이터 저장소

*  인-메모리: 데이터 스토리지의 메인 메모리에 설치되어 운영되는 방식의 데이터베이스 관리 시스템

메모리 기반이라 Read/Write 속도가 빠름

 

1) node-Redis 모듈 : NodeJS에서 Redis를 사용

 

* NodeJS

 

구글 크롬의 자바스크립트 엔진에 기반해 만들어진 서버 사이드 플랫폼

-> 하지만 웹서버가 아니라 HTTP 서버를 직접 작성해야하는, 코드를 실행 할 수 있는 수단

=> NodeJS를 이용하여, command 첫 번째 인자에 array 타입이 오게하여 기존 방식과 다르게 처리가 되도록함. 때문에 개발 시 의도된 Value로 값이 설정되지 않고 임의의 Value 값 사용 가능.

 

2) SSRF 공격

 

=> Redis는 유효하지 않은 명령어가 있어도 연결을 끊지 않고 이어서 다음 유효 명령어를 처리함. 이것을 이용하여 HTTP body 부분에 원하는 공격 함수 등의 명령어를 포함시켜 공격함.

-> Redis는 HTTP의 주요 키워드가 명령어로 입력되면 해당 연결을 끊어버리는 방식을 통해 방어함. 

-> 하지만 HTTP 프로토콜을 제외한 프로토콜을 이용한 공격 방법에는 취약.

 

3) Django-Redis-cache, pickle 모듈 사용

* Django

파이썬으로 만들어진 무료 오픈소스 웹 어플리케이션 프레임워크

쉽고 빠르게 웹사이트를 개발할 수 있도록 돕는 구성요소로 이루어진 웹 프레임워크

* pickle 모듈

(일반 텍스트를 파일로 저장할 떄는 파일 입출력을 이용, 하지만 리스트나 클래스같은 텍스트가 아닌 자료형은

일반적인 파일 입출력 방법으로는 데이터를 저장하거나 불러올 수 없음)

그래서 파이썬에서는 이와 같은 텍스트 이외의 자료형을 파일로 저장하기 위하여 pickle이라는 모듈을 제공

=> pickle 모듈을 이용하면 원한는 데이터 자료형의 변경없이 파일로 저장하여 그대로 로드할 수 있음

+ pickle로 데이터를 저장하거나 불러올 때는 파일을 바이트 형식으로 읽거나 써야함

-> 파이썬의 객체를 일련의 바이트들로 변환한 후 나중에 다시 파이썬 객체로 복원하게 할 수 있는데, 

이렇게 파이썬 객체를 일련의 바이트들로 변환하는 것을 직렬화 / 다시 바이트들을 파이썬 객체로 메모리 상에 복원하는 것을 역직렬화

=>  cache_memo 값을 확인하여 Pickle로 dump된 값을 확인 가능. 그리고 Redis가 원하는 데이터 저장 후, 해당 데이터가 다른 행위를 발생시키거나 타입을 이용해 악의적인 행위를 일으켜 특정 상황에서 호출 되는 메소드를 이용하여 공격

  1. Redis 명령어

- SAVE

Redis의 쓰기 권한이 있는 경로에 원하는 파일 생성 후, 공격 수행

 

- SLAVEOF / REPLACEOF

마스터 노드 연결시 발생하는 네트워크 트래픽을 통해 공격 수행

 

- MODULE LOAD

4.0 버전부터 추가된 module load 명령어를 통해 공격.

공격 함수나 코드가 포함된 공유 라이브러리 제작 후, 위 명령어를 통해 로드 하여 공격

- Dreamheck

 

04 CouchDB

 

  1. 개요

- Cluster Of Unreliable Commodity Hardware의 약어로,

2008년 2월 아파치 인큐베이팅 프로젝트에 편입된 문서 기반 데이터베이스임

-> 관계형 데이터베이스가 아닌 문서 기반 데이터베이스이므로 SQL 대신 JSON(데이터 표현)과 자바스크립트(쿼리)를 사용함

 

- 얼랭의 분산처리 능력을 데이터베이스로 옮겨온 것

   

   2. 주요 특징

 

    1) 문서저장소

   - 문서는 CouchDB에서 가장 기본적인 데이터 단위이며, 다수의 필드와 첨부 파일로 구성됨

   - CouchDB는 데이터베이스 파일이 항상 무결한 상태임을 보장하기 위해 이미 커밋된 데이터나 자료구조를 덮어쓰지 않음 -> crash-only 설계

장점: 데이터베이스 중지 시 별 다른 과정 거치지 않아도 가능

단점: 디스크 용량 많이 사용

   - CouchDB의 문서 모델은 데이터가 문서 안에 모두 저장되어 있으므로 ACID 구현이 단순함

*ACID: 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어

 

2) 보안과 유효성 검증

   - CouchDB는 누가 문서를 읽고 수정할 수 있는지 제한할 수 있도록, 간단하면서도 확장 가능한 보안 모델을 가짐



관리자 접근

- 관리자 계정의 경우 다른 관리자 계정을 만들거나 설계 문서를 수정 가능

리더 접근

- CouchDB 문서에 리더(Reader) 목록을 저장함. 따로 정의된 게 없으면 누구나 읽을 수 있지만, 목록이 정의되어 있는 경우에는 지정된 사용자만 읽기가 가능.

업데이트 접근

-디스크에 문서를 쓰는 시점에 자바스크립트 함수를 이용하여 유효성 검증이 이루어짐. 

-유효성 검증을 통과하면 그대로 업데이트를 진행할 수 있는 반면, 그렇지 않은 경우에는 작업이 중단되고 클라이언트는 오류 응답을 받음. 

(ex. 최초 작성자만 문서를 수정할 수 있도록 하고 싶다면 간단히 문서의 author 필드와 현재 사용자 계정을 비교하도록 코드를 작성)

 

3) REST API

   - REST는 Representational State Transfer의 약자로 소프트웨어 프로그램 아키텍처의 한 형식임

   - 대표적인 메소드: GET, POST, PUT, DELETE

 

$ curl -X PUT http://{username}:{password}@localhost:5984/users/guest -d '{"upw":"guest"}'{"ok":true,"id":"guest","rev":"1-22a458e50cf189b17d50eeb295231896"}

-user Database에 데이터 추가 

*_rev: 문서의 버전 정보 

*_id: 처음에 설정하지 않으면 랜덤 값으로 설정되며 primary key 역할을 함