WEB] NOSQL Injection

노션으로 옮김·2020년 3월 18일
1

skills

목록 보기
14/37
post-thumbnail

NOSQL

여러가지 의미가 있는데
Not Only SQL의 의미로 가장 많이 사용된다고 한다.

NOSQL은 다음과 같은 특징을 갖는다.

https://tribal1012.tistory.com/138

  1. 속성 별 schema를 규정하지 않는다(자료형)
  2. Join은 두 가지 이상의 테이블의 관계로 데이터를 검색하는 것 인데 NOSQL은 비관계형이라 불가능하다.
  3. NOSQL은 분산처리에 트랜잭션을 사용하는 것은 어려움이 있다고 한다.
  4. NOSQL은 분산처리 작업을 위해 나온 만큼 분산처리 작업이 쉽다.

종류는 다음과 같다.

https://jwprogramming.tistory.com/70

1) Key-Value DB(널리 쓰임)
: Key와 Value의 쌍으로 데이터가 저장되는 유형으로써 Amazon의 Dynamo Paper에서 유래되었습니다. Riak, Vodemort, Tokyo등의 제품이 알려져 있습니다.

2) Wide Columnar DB
: Big Table DB라고도 하며, Google의 BigTable Paper에서 유래되었습니다. Column Family 데이터 모델을 사용하고 있고, HBase, Cassandra, Hypertable이 이에 해당됩니다.

3) Document DB
: Lotus Notes에서 유래되었으며, JSON, XML과 같은 Collection 데이터 모델 구조를 채택하고 있습니다. Mongo DB, Cough DB가 이 종류에 해당됩니다.

4) Graph DB
: Euler & Graph Theory에서 유래한 DB입니다. Nodes, Relationship, Key-Value 데이터 모델을 채용하고 있습니다. Neo4J 등의 제품이 있습니다.

이 중에서 주로 사용되는 MongoDB의 인젝션 기법을 살펴보겠다.

연산자 in MongoDB

인젝션을 하려면 원하는 데이터를 조작하기 위한 특수 연산자를 알아야 한다.

몽고DB에서 특정 데이터를 질의하기 위해 사용되는 논리연산자 중 하나를 살펴보자.

https://www.zerocho.com/category/MongoDB/post/57a17d114105f0a03bc55f74

$ne

해당 값과 일치하지 않는 값을 가진 필드를 찾습니다.
{ 필드 : { $ne: 값 } }

usernametest가 아닌 값을 조회할 때 다음과 같이 사용된다.

{'username' : { $ne: 'test' } }

use MongoDB in php

php에서 mongoDB를 사용하는 코드를 보자
GET 파라미터로 아이디와 비밀번호를 입력받는 상황이다.

$param = $_GET['parameter'];
$query = [ "username" => $param ]; //딕셔너리 선언 [ key => value]
// Example of PHP REGEX search syntax, which we want to inject
// $query = [ 'username' => [ '$regex': => '\d+' ]];

$query = new MongoDB\Driver\Query($query, []);

몽고 DB에서 연산자를 사용하기 위해선 앞서 살펴본대로 딕셔너리 형태로 명령문이 전달되어야 한다.
다음에서

[ "username" => $param];

$param의 값을 test[$ne] = 'test'의 형태로 전달할 때

[ "username" => { $ne : 'test' }

위와같이 "username"에 내가 전달한 값이 딕셔너리로 변환되어
연산자가 정상적으로 실행될 수 있다.

또다른 php 코드 형태

위에서 사용한
new MongoDB\Driver\Query($query, []);
가 아닌

다음처럼 find를 이용하여 몽고DB를 조회할 수 있다.

db->logins->find(array(“username”=>$_POST[“username”],
“password”=>$_POST[“password”]));

인젝션하는 방식은 동일하다.


실습

Rootme.org의 NOSQL 인젝션 문제를 통해 실습해보겠다.
다음처럼 로그인 페이지가 존재한다.

아이디, 패스워드를 다음과 같이 전달한다.

login=admin&pass[$ne]=1

아이디(login)는 admin이고 패스워드(pass)는 1이 아닌 값을 조회하는 명령어이다.

0개의 댓글