Web Hacking/Study

Non-Relational DBMS

박연준 2023. 7. 1. 22:56

RDBMS는 스키마를 정의하고 해당 규격에 맞는 데이터를 2차원 테이블 형태로 저장한다. 이는 복잡할 뿐만 아니라, 저장해야 하는 데이터가 많아지면 용량의 한계에 다다를 수 있다는 단점이 있다. 이를 해결하기 위해 등장한 것이 비관계형 데이터베이스 즉, Non-Relational DBMS (NRDBMS, NoSQL) 이다.

관계형 데이터베이스에서 발생할 수 있는 문제점으로 SQL Injection이 있었다. 공격자는 이를 통해 데이터베이스의 정보를 알아내거나 임의의 결과를 반환해 인증을 우회하는 등의 행위가 가능했다. NoSQL 또한 이용자의 입력값을 통해 동적으로 쿼리를 생성해 데이터를 저장하기 때문에 이와 같은 문제점이 발생할 수 있다.

비관계형 데이터베이스(NRDBMS)

  • RDBMS는 SQL을 사용해 데이터를 조회 및 추가 그리고 삭제할 수 있었다.
  • NoSQL은 SQL을 사용하지 않고 복잡하지 않은 데이터를 저장해 단순 검색 및 추가 검색 작업을 위해 매우 최적화된 저장 공간인 것이 큰 특징이자 RDBMS와의 차이점이다.
  • 이 와에도, 키-값을 사용해 데이터를 저장하는 차이점이 존재한다.

  • RDBMS는 SQL이라는 정해진 문법을 통해 데이터를 저장하기 때문에 한 가지의 언어로 다양한 DBMS을 사용할 수 있다.
  • 반면에 NoSQL은 Redis, Dynamo, CouchDB, MongoDB 등 다양한 DBMS가 존재하기 때문에 각각의 구조와 사용 문법을 익혀야 한다는 단점이 있다.

💡
No SQL 유래
NoSQL이 가지는 의미에 대한 Non SQL, Non relational SQL, Not only SQL 등의 다양한 의견이 있지만 Not Only SQL로 통용되고 있다. Not Only SQL은 SQL을 사용하지 않고 데이터를 다룰 수 있다는 의미를 가진다.

MongoDB

  • MongoDB는 JSON 형태인 도큐먼트(Document)를 저장하며, 다음과 같은 특징을 갖고 있다.
    1. 스키마를 따로 정의하지 않아 각 콜렉션(Collection)에 대한 정의가 필요하지 않다.
    1. JSON 형식으로 쿼리를 작성할 수 있다.
    1. _id 필드가 Primary Key 역할을 한다.

  • 각 DBMS에서 status의 값이 “A”이고, qty의 값이 30보다 작은 데이터를 조회하는 쿼리는 다음과 같다. MongoDB의 경우 $문자를 통해 연산자를 사용할 수 있다.
    • RDBMS
      SELECT * FROM inventory WHERE status = "A" and qty < 30;
    • MongoDB
      db.inventory.find( { $and: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

  • 다음은 MongoDB에서 데이터를 삽입하고, 조회하는 쿼리의 예시이다.
    • MongoDB 사용 예시
      $ mongo
      > db.user.insert({uid: 'admin', upw: 'sercretpassword'])
      WriteResult({ nInserted" : 1 })
      
      > db.user.find({uid: 'admin'})
      { "_id" : ObjectId('5e71d395b050a2511caa827d"), "uid" : 
      "admin", "upw" : "secretpassword" }
💡
콜렉션(Collection)
콜렉션은 데이터베이스의 하위에 속하는 개념으로, RDBMS의 테이블과 비슷하다.

MongoDB 연산자

Comparison

  • $eq
    • 지정된 값과 같은 값을 찾는다. (equal)
  • $in
    • 배열 안의 값들과 일치하는 값을 찾는다. (in)
  • $ne
    • 지정된 값과 같지 않은 값을 찾는다. (not equal)
  • $nin
    • 배열 안의 값들과 일치하지 않는 값을 찾는다. (not in)

Logical

  • $and
    • 논리적 AND, 각각의 쿼리를 모두 만족하는 문서가 반환된다.
  • $not
    • 쿼리 식의 효과를 반전시킨다. 쿼리 식과 일치하지 않는 문서를 반환한다.
  • $nor
    • 논리적 NOR, 각각의 쿼리를 모두 만족하지 않는 문서가 반환된다.
  • $or
    • 논리적 OR, 각각으 ㅣ쿼리 중 하나 이상 만족하는 문서가 반환된다.

Element

  • $exists
    • 지정된 필드가 있는 문서를 찾는다.
  • $type
    • 지정된 필드가 지정된 유형인 문서를 선택한다.

Evaluation

  • $expr
    • 쿼리 언어 내에서 집계 식을 사용할 수 있다.
  • $regex
    • 지정된 정규식과 일치하는 문서를 선택한다.
  • $text
    • 지정된 텍스트를 검색한다.

MongoDB 기본 문법

  • 다음은 조회, SQL과 MongoDB의 문법을 비교한 표이다.

SELECT

SQL

SELECT * FROM account;
SELECT * FROM account WHERE user_id=
"admin";
SELECT user_idx FROM account WHERE
user_id="admin"

MongoDB

db.account.find()
db.account.find( {user_id: "admin"} )
db.account.find( {user_id: "admin" },
{ user_idx:1, _id:0 } )

INSERT

SQL

INSERT INTO account( 
user_id,
user_pw,
) VALUES ("guest", "guest");

MongoDB

db.account.insert({
user_id: "guest",
user_pw: "guest"
})

DELETE

SQL

DELETE FROM account;
DELETE FROM account WHERE
user_id="guest";

MongoDB

db.account.remove()
db.account.remove(
{user_id: "guest"} )

UPDATE

SQL

UPDATE account SET
user_id="guest2" WHERE
user_idx=2;

MongoDB

db.account.update(
{user_idx: 2},
{ $set: { user_id:
"guest" } } 
}

Redis

  • Redis는 키 값(Key-Value)의 쌍을 가진 데이터를 저장한다.
  • 제일 큰 특징은 다른 데이터베이스와 다르게 메모리 기반의 DBMS이다.
  • 메모리를 사용해 데이터를 저장하고 접근하기 때문에 일고 쓰는 작업을 다른 DBMS보다 훨씬 빠르게 수행한다.
  • 다양한 서비스에서 임시 데이터를 캐싱하는 용도로 주로 사용하고 있다.

  • 다음은 Redis에서 데이터를 추가하고 조회하는 명령어의 예시이다.
    $ redis-cli
    127.0.0.1:6379 > SET test 1234 # SET key value
    OK
    127.0.0.1:6379 > GET test # GET key
    "1234"

  • 아래 쪽의 표는 Redis에서 데이터를 관리할 때 자주 사용하는 명령어이다.

    데이터 조회 및 조작 명령어

    명령어구조설명
    GETGET key데이터 조회
    MGETMGET key [key …]여러 데이터 조회
    SETSET key value새로운 데이터 추가
    MSETMSET key value [key value …]여러 데이터를 추가
    DELDEL key [key …]데이터 삭제
    EXISTSEXISTS key [key …]데이터 유무 확인
    INCRINCR key데이터 값에 1 더함
    DECRDECR key데이터 값에 1 뺌

    관리 명령어

    명령어구조설명
    INFOINFO [section]DBMS 정보 조회
    CONFIG GETCONFIG GET parameter설정 조회
    CONFIG SETCONFIG SET parameter value새로운 설정을 입력

CouchDB

  • CouchDB 또한 MongoDB와 같이 JSON 형태인 도큐먼트(Document)를 저장한다.
  • 이는 웹 기반의 DBMS로, REST API 형식으로 요청을 처리한다.

  • 다음은 각 메소드에 따른 기능 설명이다.
    메소드기능 설명
    POST새로운 레코드를 추가한다.
    GET레코드를 조회한다.
    PUT레코드를 업데이트한다.
    DELETE레코드를 삭제한다.

  • 다음은 HTTP 요청으로 레코드를 업데이트하고 조회하는 예시이다.
    $ curl -X PUT http://{username}:{password}@localhost:5984/users/guest -d '{"upw":"guest"}'
    {"ok":true,"id":"guest","rev":"1-22a458e50cf189b17d50eeb295231896"}
    
    $ curl http://{username}:{password}@localhost:5984/users/guest
    {"_id":"guest","_rev":"1-22a458e50cf189b17d50eeb295231896","upw":"guest"}

CouchDB 특수 구성 요소

  • CouchDB에서는 서버 또는 데이터베이스를 위해 다양한 기능을 제공한다. 그 중 _ 문자로 시작하는 URL, 필드는 특수 구성 요소를 나타낸다.
  • 다음은 각 구성 요소에 대한 설명이다. 이 외 자세한 정보는 아래 첨부한 공식 문서를 통해 확인할 수 있다.

    SERVER

    요소설명
    /인스턴스에 대한 메타 정보를 반환한다.
    /_all_dbs인스턴스의 데이터베이스 목록을 반환한다.
    /_utils관리자페이지로 이동한다.

    Database

    요소설명
    /db지정된 데이터베이스에 대한 정보를 반환한다.
    /{db}/_all_docs지정된 데이터베이스에 포함된 모든 도큐먼트를 반환한다.
    /{db}/_find지정된 데이터베이스에서 JSON 쿼리에 해당하는 모든 도큐먼트를 반환한다.

    💡
    CouchDB API 공식 문서

    https://docs.couchdb.org/en/latest/api/index.html

'Web Hacking > Study' 카테고리의 다른 글

File Upload 취약점과 대응방안  (0) 2023.07.01
SQL Injection 실습(2)  (0) 2023.07.01
Relational DBMS  (0) 2023.07.01
SQL Injection 취약점  (0) 2023.07.01
CSS Injection 취약점  (0) 2023.06.26