Skip to content

Commit

Permalink
Fixes #14
Browse files Browse the repository at this point in the history
  • Loading branch information
Qyn committed Aug 23, 2022
1 parent 9aafcf4 commit 41899c7
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 13 deletions.
9 changes: 7 additions & 2 deletions frontend/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ class TulipApi {
return await response.text()
}

async toPythonRequest(body: string, id: string, tokenize: boolean) {
const response = await fetch(`${this.API_ENDPOINT}/to_python_request?tokenize=${tokenize ? "1" : "0"}&id=${id}`, {
async toSinglePythonRequest(body: string, id: string, tokenize: boolean) {
const response = await fetch(`${this.API_ENDPOINT}/to_single_python_request?tokenize=${tokenize ? "1" : "0"}&id=${id}`, {
method: "POST",
headers: {
"Content-Type": "text/plain;charset=UTF-8"
Expand All @@ -133,6 +133,11 @@ class TulipApi {
return await response.text()
}

async toFullPythonRequest(id: string) {
const response = await fetch(`${this.API_ENDPOINT}/to_python_request/${id}`);
return await response.text()
}

async toPwnTools(id: string) {
const response = await fetch(`${this.API_ENDPOINT}/to_pwn/${id}`);
return await response.text();
Expand Down
35 changes: 31 additions & 4 deletions frontend/src/pages/FlowView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function PythonRequestFlow({ full_flow, flow }: {full_flow:FullFlow, flow: FlowD

useEffect(() => {
const fetchData = async () => {
const data = await api.toPythonRequest(btoa(flow.data), full_flow._id.$oid,true);
const data = await api.toSinglePythonRequest(btoa(flow.data), full_flow._id.$oid,true);
setData(data);
};
// TODO proper error handling
Expand Down Expand Up @@ -290,8 +290,9 @@ export function FlowView() {
}
return "";
}


const { statusText, copy } = useCopy({
const { statusText: pwnCopyStatusText, copy: copyPwn } = useCopy({
getText: copyAsPwn,
copyStateToText: {
copied: "Copied",
Expand All @@ -301,6 +302,25 @@ export function FlowView() {
},
});

async function copyAsRequests() {
if (flow?._id.$oid) {
let content = await api.toFullPythonRequest(flow?._id.$oid);
return content;
}
return "";
}


const { statusText: requestsCopyStatusText, copy: copyRequests } = useCopy({
getText: copyAsRequests,
copyStateToText: {
copied: "Copied",
default: "Copy as requests",
failed: "Failed",
copying: "Generating payload",
},
});

if (flow === undefined) {
return <div>Loading...</div>;
}
Expand All @@ -314,9 +334,16 @@ export function FlowView() {
<div className="flex align-middle p-2 gap-3 ml-auto">
<button
className="bg-gray-700 text-white px-2 text-sm rounded-md"
onClick={copy}
onClick={copyPwn}
>
{pwnCopyStatusText}
</button>

<button
className="bg-gray-700 text-white px-2 text-sm rounded-md"
onClick={copyRequests}
>
{statusText}
{requestsCopyStatusText}
</button>
</div>
</div>
Expand Down
43 changes: 40 additions & 3 deletions services/data2req.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ def send_error(self, code, message):
self.error_code = code
self.error_message = message

# tokenize used for automatically fill data param of request
def convert_http_requests(raw_request, flow, tokenize=True, use_requests_session=False):
def decode_http_request(raw_request, tokenize):
request = HTTPRequest(raw_request)

data = {}
Expand Down Expand Up @@ -92,8 +91,13 @@ def convert_http_requests(raw_request, flow, tokenize=True, use_requests_session
# try to extract files
if content_type.startswith("multipart/form-data"):
data_param_name = "files"
return "Forms with files are not yet implemented"
return "Forms with files are not yet implemented", None, None, None
return request, data, data_param_name, headers

# tokenize used for automatically fill data param of request
def convert_single_http_requests(raw_request, flow, tokenize=True, use_requests_session=False):

request, data, data_param_name, headers = decode_http_request(raw_request, tokenize)
rtemplate = Environment(loader=BaseLoader()).from_string("""import os
import requests
import sys
Expand All @@ -118,3 +122,36 @@ def convert_http_requests(raw_request, flow, tokenize=True, use_requests_session
use_requests_session=use_requests_session,
port=flow["dst_port"]
)


def render(template, **kwargs):
return Environment(loader=BaseLoader()).from_string(template).render(kwargs)

def convert_flow_to_http_requests(flow, tokenize=True, use_requests_session=True):
port = flow["dst_port"]
script = render("""import os
import requests
import sys
host = sys.argv[1]
{% if use_requests_session %}
s = requests.Session()
{% endif %}""",use_requests_session=use_requests_session,
port=port)
for message in flow['flow']:
if message['from'] == 'c':
request, data, data_param_name, headers = decode_http_request(bytes.fromhex(message['hex']), tokenize)
script += render("""
{% if use_requests_session %}
s.headers = {{headers}}
{% else %}
headers = {{headers}}
{% endif %}
data = {{data}}
{% if use_requests_session %}s{% else %}requests{% endif %}.{{request.command.lower()}}("http://{}:{{port}}{{request.path}}".format(host), {{data_param_name}}=data{% if not use_requests_session %}, headers=headers{% endif %})""", headers=str(dict(headers)),
data=data,
request=request,
data_param_name=data_param_name,
use_requests_session=use_requests_session,
port=port)
return script
2 changes: 2 additions & 0 deletions services/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ def getFlowList(self, filters):
f["dst_ip"] = filters["dst_ip"]
if "dst_port" in filters:
if int(filters["dst_port"]) == -1:
# remove dst_ip
f.pop('dst_ip', None)
f["dst_port"] = {
"$nin": [service["port"] for service in services]
}
Expand Down
22 changes: 18 additions & 4 deletions services/webservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from flask import Flask, Response

from configurations import services
from data2req import convert_http_requests
from data2req import convert_flow_to_http_requests, convert_single_http_requests
from base64 import b64decode
from db import DB
from bson import json_util
Expand Down Expand Up @@ -84,8 +84,8 @@ def getFlowDetail(id):
return to_ret


@application.route('/to_python_request', methods=['POST'])
def convertToRequests():
@application.route('/to_single_python_request', methods=['POST'])
def convertToSingleRequest():
flow_id = request.args.get("id", "")
if flow_id == "":
return return_text_response("There was an error while converting the request:\n{}: {}".format("No flow id", "No flow id param"))
Expand All @@ -97,7 +97,21 @@ def convertToRequests():
tokenize = request.args.get("tokenize", False)
use_requests_session = request.args.get("use_requests_session", False)
try:
converted = convert_http_requests(data, flow, tokenize, use_requests_session)
converted = convert_single_http_requests(data, flow, tokenize, use_requests_session)
except Exception as ex:
return return_text_response("There was an error while converting the request:\n{}: {}".format(type(ex).__name__, ex))
return return_text_response(converted)

@application.route('/to_python_request/<id>')
def convertToRequests(id):
#TODO check flow null or what
flow = db.getFlowDetail(id)
if not flow:
return return_text_response("There was an error while converting the request:\n{}: {}".format("Invalid flow", "Invalid flow id"))
tokenize = request.args.get("tokenize", True)
use_requests_session = request.args.get("use_requests_session", True)
try:
converted = convert_flow_to_http_requests(flow, tokenize, use_requests_session)
except Exception as ex:
return return_text_response("There was an error while converting the request:\n{}: {}".format(type(ex).__name__, ex))
return return_text_response(converted)
Expand Down

0 comments on commit 41899c7

Please sign in to comment.