Home Requestbin Development
Post
Cancel

Requestbin Development

업무를 진행하면서 Data 탈취가 가능한 경우 공격자의 서버로 가져올 수 있습니다.
아직 부족하고 다른 좋은 도구들도 많지만 하나씩 해보는게 좋지않나라는 생각에 개발을 해보았습니다.


requestbin?

requestbin 이란 client가 요청하는 정보를 받아서 확인할 수 있는 서비스입니다. 여러가지 구현되어 있는 기술들이 많지만 저는 간단하게 GET, POST로 데이터를 보낼 때 보낸 데이터, 헤더, 시간을 구현했습니다.

Development

Server는 Flask로 구현 했고, 모듈 설치가 필요합니다.

  • pip install flask
  • pip install pandas
  • pip install openpyxl

구현 방법은 다음과 같습니다.

  1. Client -> Server로 데이터를 전송(GET, POST 방식)
  2. Server는 데이터를 받아 저장 후 Client에게 View

구현 방법

기본 적인 View는 아래와 같습니다. Method, Headers, Data, Time, delete 가 있습니다.

View

GET, POST로 데이터를 전달 시 서버에 잘 저장이 되었습니다.

데이터 통신

결과

이번에는 요청중에 이상한게 있으면 지워야될수도 있기 때문에 삭제하는 로직을 만들었습니다. 2번째의 GET 통신에 있는 delete 버튼을 누르면 삭제가 됩니다.

삭제 결과

기능 추가

결과를 엑셀로 저장하는 기능을 추가했습니다.

excel 저장

Code

코드는 requestbin.py/templates/data.html 두개의 파일있습니다.

requestbin.py

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from flask import Flask, request, jsonify, render_template,redirect, url_for,send_file
from datetime import datetime
import pandas

app = Flask(__name__)

# 데이터를 저장할 리스트
data_list = []

# HTTP 요청을 받아서 데이터를 저장하는 라우트
@app.route('/save', methods=['GET','POST'])
def save_data():
    now = datetime.now()
    get_param = request.query_string.decode() #GET 파라미터 저장
    post_param =""
    if request.is_json:
        post_param = request.json
    else:
        post_param = request.form.to_dict()
    print(post_param)
    data = {
        'id': len(data_list)+1, #데이터 구분 하기 위한 id
        'method': request.method, #메소드
        'headers': dict(request.headers), #데이터 전송 헤더
        'getdata': f"{get_param}", #get파라미터
        'postdata': f"{post_param}", #post파라미터
        'time' : now.strftime('%Y-%m-%d %H:%M:%S') #데이터 전송 시간
    }
    data_list.append(data)
    return redirect(url_for('get_data'))

# 저장된 데이터를 조회하는 라우트
@app.route('/data', methods=['GET'])
def get_data():
    return render_template('/data.html', data_list=data_list)

# 저장된 데이터를 삭제하는 라우트
@app.route('/delete', methods=['GET'])
def delete_data():
    id = request.args.get('id')
    for data in data_list:
        if data['id'] == int(id):
            data_list.remove(data)
            print(len(data_list))
    return jsonify({'message': 'Data deleted successfully!'})

#데이터를 엑셀 파일로 저장하는 라우트
@app.route('/save_excel', methods=['GET'])
def save_excel():
    df = pandas.DataFrame(data_list)
    filename = 'data.xlsx'
    df.to_excel(filename, index=False)
    return send_file(filename, mimetype='test/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', download_name='data.xlsx', as_attachment=True)



if __name__ == '__main__':
    app.run(debug=True)


if __name__ == '__main__':
    app.run(host="0.0.0.0",port=5555,debug=True)

/templates/data.html

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!DOCTYPE html>
<html>
<head>
    <title>glasses RequestBin</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        th {
            background-color: lightgray;
            text-align: center;
          }
    </style>
</head>
<body>
    <div class="container">
        <div class="d-flex justify-content-between align-items-center">
            <h1>glasses96</h1>
            <button onclick="saveExcel()">Save Excel</button>
        </div>
        <table class="table" style="table-layout: fixed">
            <thead>
                <tr>
                    <th width="10%">Method</th>
                    <th width="35%">Headers</th>
                    <th width="12.5%">GET Data</th>
                    <th width="12.5%">POST Data</th>
                    <th width="20%">Time</th>
                    <th width="10%">delete</th>
                </tr>
            </thead>
            <tbody>
                
            </tbody>
        </table>
    </div>
</body>
    <script>
        function deleteData(id) {
            if (confirm("Are you sure you want to delete this data?")) {
                fetch('/delete?id='+id, {method: 'GET'})
                .then(response => {
                    if (response.ok) {
                        location.reload();
                    } else {
                        alert("Failed to delete data.");
                    }
                });
            }
        }
        function saveExcel() {
            if (confirm("Are you sure you want to save this data?")) {
                fetch('/save_excel', {method: 'GET'})
                .then(response => {
                    if (response.ok) {
                        return response.blob();
                    } else {
                        alert("Failed to save data.");
                    }
                })
                .then(blob => {
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = 'data.xlsx';
                    a.click();
                });
            }
        }

    </script>
</html>