mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 00:01:36 +00:00
289 lines
9.7 KiB
Python
289 lines
9.7 KiB
Python
|
#!/usr/bin/env python3
|
|||
|
|
|||
|
from clidirector import MitmCliDirector
|
|||
|
|
|||
|
|
|||
|
def record_user_interface(d: MitmCliDirector):
|
|||
|
tmux = d.start_session(width=120, height=36)
|
|||
|
window = tmux.attached_window
|
|||
|
|
|||
|
d.start_recording("recordings/mitmproxy_user_interface.cast")
|
|||
|
d.message("Welcome to the mitmproxy tutorial. In this lesson we cover the user interface.")
|
|||
|
d.pause(1)
|
|||
|
d.exec("mitmproxy")
|
|||
|
d.pause(3)
|
|||
|
|
|||
|
d.message("This is the default view of mitmproxy.")
|
|||
|
d.message("mitmproxy adds rows to the view as new requests come in.")
|
|||
|
d.message("Let’s generate some requests using `curl` in a separate terminal.")
|
|||
|
|
|||
|
pane_top = d.current_pane
|
|||
|
pane_bottom = window.split_window(attach=True)
|
|||
|
pane_bottom.resize_pane(height=12)
|
|||
|
|
|||
|
d.focus_pane(pane_bottom)
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.type("curl")
|
|||
|
d.message("Use curl’s `-x` option to specify a proxy, e.g., `curl -x http://127.0.0.1:8080` to use mitmproxy.")
|
|||
|
|
|||
|
d.type(" -x http://127.0.0.1:8080")
|
|||
|
|
|||
|
d.message("We use the text-based weather service `wttr.in`.")
|
|||
|
d.exec(" \"http://wttr.in/Paris?0\"")
|
|||
|
|
|||
|
d.pause(2)
|
|||
|
d.press_key("Up")
|
|||
|
d.press_key("Left", count=3)
|
|||
|
d.press_key("BSpace", count=5)
|
|||
|
d.exec("Miami")
|
|||
|
|
|||
|
d.pause(2)
|
|||
|
d.press_key("Up")
|
|||
|
d.press_key("Left", count=3)
|
|||
|
d.press_key("BSpace", count=5)
|
|||
|
d.exec("Tokio")
|
|||
|
|
|||
|
d.pause(2)
|
|||
|
d.press_key("Up")
|
|||
|
d.press_key("Left", count=3)
|
|||
|
d.press_key("BSpace", count=5)
|
|||
|
d.exec("London")
|
|||
|
|
|||
|
d.pause(2)
|
|||
|
d.exec("exit", target=pane_bottom)
|
|||
|
|
|||
|
d.focus_pane(pane_top)
|
|||
|
|
|||
|
d.message("You see the requests to `wttr.in` in the list of flows.")
|
|||
|
|
|||
|
d.message("mitmproxy is controlled using keyboard shortcuts.")
|
|||
|
d.message("Use your arrow keys `↑` and `↓` to change the focused flow (`>>`).")
|
|||
|
d.press_key("Down", count=3, pause=0.5)
|
|||
|
d.press_key("Up", count=2, pause=0.5)
|
|||
|
d.press_key("Down", count=2, pause=0.5)
|
|||
|
|
|||
|
d.message("The focused flow (`>>`) is used as a target for various commands.")
|
|||
|
|
|||
|
d.message("One such command shows the flow details, it is bound to `↵`.")
|
|||
|
|
|||
|
d.message("Press `↵` to view the details of the focused flow.")
|
|||
|
d.press_key("Enter")
|
|||
|
|
|||
|
d.message("The flow details view has 3 panes: request, response, and detail.")
|
|||
|
d.message("Use your arrow keys `←` and `→` to switch between panes.")
|
|||
|
d.press_key("Right", count=2, pause=2.5)
|
|||
|
d.press_key("Left", count=2, pause=1)
|
|||
|
|
|||
|
d.message("Press `q` to exit the current view.",)
|
|||
|
d.type("q")
|
|||
|
|
|||
|
d.message("Press `?` to get a list of all available keyboard shortcuts.")
|
|||
|
d.type("?")
|
|||
|
d.pause(2)
|
|||
|
d.press_key("Down", count=20, pause=0.25)
|
|||
|
|
|||
|
d.message("Press `q` to exit the current view.")
|
|||
|
d.type("q")
|
|||
|
|
|||
|
d.message("Each shortcut is internally bound to a command.")
|
|||
|
d.message("You can also execute commands directly (without using shortcuts).")
|
|||
|
d.message("Press `:` to open the command prompt at the bottom.")
|
|||
|
d.type(":")
|
|||
|
|
|||
|
d.message("Enter `console.view.flow @focus`.")
|
|||
|
d.type("console.view.flow @focus")
|
|||
|
|
|||
|
d.message("The command `console.view.flow` opens the details view for a flow.")
|
|||
|
|
|||
|
d.message("The argument `@focus` defines the target flow.")
|
|||
|
|
|||
|
d.message("Press `↵` to execute the command.")
|
|||
|
d.press_key("Enter")
|
|||
|
|
|||
|
d.message("Commands unleash the full power of mitmproxy, i.e., to configure interceptions.")
|
|||
|
|
|||
|
d.message("You now know basics of mitmproxy’s UI and how to control it.")
|
|||
|
d.pause(1)
|
|||
|
d.save_instructions("recordings/mitmproxy_user_interface_instructions.json")
|
|||
|
d.end()
|
|||
|
|
|||
|
|
|||
|
def record_intercept_requests(d: MitmCliDirector):
|
|||
|
tmux = d.start_session(width=120, height=36)
|
|||
|
window = tmux.attached_window
|
|||
|
|
|||
|
d.start_recording("recordings/mitmproxy_intercept_requests.cast")
|
|||
|
d.message("Welcome to the mitmproxy tutorial. In this lesson we cover the interception of requests.")
|
|||
|
d.pause(1)
|
|||
|
d.exec("mitmproxy")
|
|||
|
d.pause(3)
|
|||
|
|
|||
|
d.message("We first need to configure mitmproxy to intercept requests.")
|
|||
|
|
|||
|
d.message("Press `i` to prepopulate mitmproxy’s command prompt with `set intercept ''`.")
|
|||
|
d.type("i")
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.message("We use the flow filter expression `~u <regex>` to only intercept specific URLs.")
|
|||
|
d.message("Additionally, we use the filter `~q` to only intercept requests, but not responses.")
|
|||
|
d.message("We combine both flow filters using `&`.")
|
|||
|
|
|||
|
d.message("Enter `~u /Paris & ~q` between the quotes of the `set intercept` command and press `↵`.")
|
|||
|
d.exec("~u /Paris & ~q")
|
|||
|
d.message("The bottom bar shows that the interception has been configured.")
|
|||
|
|
|||
|
d.message("Let’s generate a request using `curl` in a separate terminal.")
|
|||
|
|
|||
|
pane_top = d.current_pane
|
|||
|
pane_bottom = window.split_window(attach=True)
|
|||
|
pane_bottom.resize_pane(height=12)
|
|||
|
|
|||
|
d.focus_pane(pane_bottom)
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.type("curl")
|
|||
|
d.message("Use curl’s `-x` option to specify a proxy, e.g., `curl -x http://127.0.0.1:8080` to use mitmproxy.")
|
|||
|
|
|||
|
d.type(" -x http://127.0.0.1:8080")
|
|||
|
|
|||
|
d.message("We use the text-based weather service `wttr.in`.")
|
|||
|
d.exec(" \"http://wttr.in/Paris?0\"")
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.focus_pane(pane_top)
|
|||
|
|
|||
|
d.message("You will see a new line in in the list of flows.")
|
|||
|
d.message("The new flow is displayed in red to indicate that it has been intercepted.")
|
|||
|
d.message("Put the focus (`>>`) on the intercepted flow. This is already the case in our example.")
|
|||
|
d.message("Press `a` to resume this flow without making any changes.")
|
|||
|
d.type("a")
|
|||
|
|
|||
|
d.focus_pane(pane_bottom)
|
|||
|
|
|||
|
d.message("Submit another request and focus its flow.")
|
|||
|
d.press_key("Up")
|
|||
|
d.press_key("Enter")
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.focus_pane(pane_top)
|
|||
|
d.press_key("Down")
|
|||
|
|
|||
|
d.message("Press `X` to kill this flow, i.e., discard it without forwarding it to its final destination `wttr.in`.")
|
|||
|
d.type("X")
|
|||
|
d.pause(3)
|
|||
|
d.save_instructions("recordings/mitmproxy_intercept_requests_instructions.json")
|
|||
|
d.end()
|
|||
|
|
|||
|
|
|||
|
def record_modify_requests(d: MitmCliDirector):
|
|||
|
tmux = d.start_session(width=120, height=36)
|
|||
|
window = tmux.attached_window
|
|||
|
|
|||
|
d.start_recording("recordings/mitmproxy_modify_requests.cast")
|
|||
|
d.message("Welcome to the mitmproxy tutorial. In this lesson we cover the modification of intercepted requests.")
|
|||
|
d.pause(1)
|
|||
|
d.exec("mitmproxy")
|
|||
|
d.pause(3)
|
|||
|
|
|||
|
d.message("We configure and use the same interception rule as in the last tutorial.")
|
|||
|
d.message("Press `i` to prepopulate mitmproxy’s command prompt, enter the flow filter `~u /Paris & ~q`, and press `↵`.")
|
|||
|
d.type("i")
|
|||
|
d.pause(2)
|
|||
|
d.exec("~u /Paris & ~q")
|
|||
|
|
|||
|
d.message("Let’s generate a request using `curl` in a separate terminal.")
|
|||
|
|
|||
|
pane_top = d.current_pane
|
|||
|
pane_bottom = window.split_window(attach=True)
|
|||
|
pane_bottom.resize_pane(height=12)
|
|||
|
|
|||
|
d.focus_pane(pane_bottom)
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.type("curl -x http://127.0.0.1:8080")
|
|||
|
d.exec(" \"http://wttr.in/Paris?0\"")
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.focus_pane(pane_top)
|
|||
|
|
|||
|
d.message("We now want to modify the intercepted request.")
|
|||
|
d.message("Put the focus (`>>`) on the intercepted flow. This is already the case in our example.")
|
|||
|
|
|||
|
d.message("Press `↵` to open the details view for the intercepted flow.")
|
|||
|
d.press_key("Enter")
|
|||
|
|
|||
|
d.message("Press `e` to edit the intercepted flow.")
|
|||
|
d.type("e")
|
|||
|
|
|||
|
d.message("mitmproxy asks which part to modify.")
|
|||
|
|
|||
|
d.message("Select `path` by using your arrow keys and press `↵`.")
|
|||
|
d.press_key("Down", count=3, pause=0.5)
|
|||
|
d.pause(1)
|
|||
|
d.press_key("Enter")
|
|||
|
|
|||
|
d.message("mitmproxy shows all path components line by line, in our example its just one element: `Paris`.")
|
|||
|
d.message("Press `↵` to modify the selected path component.")
|
|||
|
d.press_key("Down", pause=2)
|
|||
|
d.press_key("Enter")
|
|||
|
|
|||
|
d.message("Replace `Paris` with `Tokio`.")
|
|||
|
d.press_key("BSpace", count=5, pause=0.5)
|
|||
|
d.type("Tokio", pause=0.5)
|
|||
|
|
|||
|
d.message("Press `ESC` to confirm your change.")
|
|||
|
d.press_key("Escape")
|
|||
|
|
|||
|
d.message("Press `q` to go back to the flow details view.")
|
|||
|
d.type("q")
|
|||
|
|
|||
|
d.message("Press `a` to resume the intercepted flow.")
|
|||
|
d.type("a")
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.message("You see that the request URL was modified and `wttr.in` replied with the weather report for `Tokio`.")
|
|||
|
|
|||
|
d.save_instructions("recordings/mitmproxy_modify_requests_instructions.json")
|
|||
|
d.end()
|
|||
|
|
|||
|
|
|||
|
def record_replay_requests(d: MitmCliDirector):
|
|||
|
tmux = d.start_session(width=120, height=36)
|
|||
|
window = tmux.attached_window
|
|||
|
|
|||
|
d.start_recording("recordings/mitmproxy_replay_requests.cast")
|
|||
|
d.message("Welcome to the mitmproxy tutorial. In this lesson we cover replaying requests.")
|
|||
|
d.pause(1)
|
|||
|
d.exec("mitmproxy")
|
|||
|
d.pause(3)
|
|||
|
|
|||
|
d.message("Let’s generate a request that we can replay. We use `curl` in a separate terminal.")
|
|||
|
|
|||
|
pane_top = d.current_pane
|
|||
|
pane_bottom = window.split_window(attach=True)
|
|||
|
pane_bottom.resize_pane(height=12)
|
|||
|
|
|||
|
d.focus_pane(pane_bottom)
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.exec("curl -x http://127.0.0.1:8080 \"http://wttr.in/Paris?0\"")
|
|||
|
d.pause(2)
|
|||
|
|
|||
|
d.focus_pane(pane_top)
|
|||
|
|
|||
|
d.message("We now want to replay the intercepted request.")
|
|||
|
d.message("Put the focus (`>>`) on the intercepted flow. This is already the case in our example.")
|
|||
|
d.message("Press `r` to replay this flow.")
|
|||
|
d.type("r")
|
|||
|
|
|||
|
d.message("Note that no new rows are added for replayed flows, but the existing row is updated.")
|
|||
|
d.message("Every time you press `r`, mitmproxy sends this request to the server again and updates the flow.")
|
|||
|
d.press_key("r", count=6, pause=0.75)
|
|||
|
|
|||
|
d.message("You can also modify a flow before replaying it.")
|
|||
|
d.message("It works as shown in the previous tutorial by pressing `e`.")
|
|||
|
|
|||
|
d.save_instructions("recordings/mitmproxy_replay_requests_instructions.json")
|
|||
|
d.end()
|