비관계형 데이터베이스
RDBMS는 SQL을 사용해 데이터를 조회 및 추가 그리고 삭제할 수 있었습니다. NoSQL은 SQL을 사용하지 않고 복잡하지 않은 데이터를 저장해 단순 검색 및 추가 검색 작업을 위해 매우 최적화된 저장 공간인 것이 큰 특징이자 RDBMS와의 차이점입니다. 이 외에도, 키-값을 통해 데이터를 저장하는 차이점이 존재합니다.
RDBMS는 SQL이라는 정해진 문법을 통해 데이터를 저장하기 때문에 한 가지의 언어로 DBMS를 사용할 수 있었습니다. 반면에 NoSQL은 Redis, Dynamo, CouchDB, MongoDB등 다양한 DBMS가 존재하기 때문에 각각의 구조와 사용 문법을 익혀야 한다는 단점이 있습니다.
MongoDB
기본적인 연산자 종류입니다. 그냥 외웁시다.
Redis
Redis는 키-값(Key-Value)의 쌍을 가진 데이터를 저장합니다. 제일 큰 특징은 다른 데이터베이스와 다르게 메모리 기반의 DBMS입니다. 메모리를 사용해 데이터를 저장하고, 접근하기 때문에 읽고 쓰는 작업이 다른 DBMS보다 훨씬 빠릅니다. 따라서 다양한 서비스에서 임시 데이터를 캐싱하는 용도로 주로 사용하고 있습니다.
CouchDB
CouchDB또한 MongoDB와 같이 JSON형태인 도큐먼트(Document)를 제정합니다. 이는 웹 기반의 DBMS로, REST API 형식으로 요청을 처리합니다.
NoSQL Injection
NoSQL Injection은 이전에 학습한 SQL Injection과 공격 목적 및 방법이 매우 유사합니다. 두 공격 모두 이용자의 입력값이 쿼리에 포함되면서 발생하는 문제점입니다. MongoDB의 NoSQL Injection 취약점은 주로 이용자의 입력값에 대한 타입 검증이 붗충분할 때 발생합니다.
Express로 짠 코드를 보면, req.query의 타입이 문자열로 지정되어 있지 않기 때문에 문자열 외의 타입이 입력될 수 있음을 볼 수 있습니다.
MongoDB는 문자열이 아닌 타입의 값을 입력할 수 있고, 이를 통해 연산자를 사용할 수 있다고 했습니다. 그렇다면, 연산자를 이용해서 어떻게 NoSQL Injection을 수행할 수 있는지 알아보겠습니다.
위 코드는 user콜렉션에서 이용자가 이볅한 uid와 upw에 해당하는 데이터를 찾고, 출력하는 예제 코드입니다. 이용자의 입력값에 대해 타입을 검증하지 않기 때문에 오브젝트 타입의 값을 입력할 수 있습니다.
이전에 본 $ne 연산자는 not equal의 약자로, 입력한 데이터와 일치하지 않는 데이터를 반환합니다. 따라서 공격자는 계정 정보를 모르더라도 다음과 같이 입력해 해당 정보를 알아낼 수 있습니다.
// 임베드된 쿼리문
db.collection('user').find({
'uid': {
$ne: 'a'
},
'upw': {
$ne 'a'
}
})
즉 $ne연산자를 사용해 uid와 upw가 'a'가 아닌 데이터를 조회하는 공격 쿼리와 실행 결과입니다.
실습
이와 같은 코드에서는 post로 다음과 같은 object값을 넣으면 admin계정을 알아낼 수 있습니다.
'School > Security' 카테고리의 다른 글
[ Web Hacking ] - SQL Injection (0) | 2022.05.29 |
---|---|
[ Reverse Engineering ] - ABOUT (0) | 2022.05.28 |
[ Web Hacking ] - CSRF (0) | 2022.05.28 |
[ Web Hacking ] - XSS Bypass (0) | 2022.05.28 |
[ Web Hacking ] - XSS (0) | 2022.05.27 |