Writing the first actions
Each action is defined by a name and a subtype. A subtype defines what the action is able to do: For example “HTTP request” is a subtype that allows to send an HTTP request and inspect responses.
Let’s start building our fingerprinting step with a very simple action:
actions: {
name: "fingerprinting"
http_request: {
method: GET
uri: "/version"
}
}
In that action, named fingerprinting
we simply send a GET
HTTP request to
/version
on the currently targeted service.
Note that Tsunami will only send HTTP requests to services that have been identified as HTTP services during the port scanning phase.
But that action will always succeed because it does not verify anything in the
response. Let’s use the response
field and add a condition on the status code:
actions: {
name: "fingerprinting"
http_request: {
method: GET
uri: "/version"
response: {
http_status: 200
}
}
}
Now we want to ensure the header contains MyVulnerableApp
: we need to use
expectations. We can either use expect_all
or expect_any
, which perform
checks on the response that must respectively “all be true” or
“at least one true”. Here, we have only one expectation, so we will use
expect_all
with one conditions
:
actions: {
name: "fingerprinting"
http_request: {
method: GET
uri: "/version"
response: {
http_status: 200
expect_all: {
conditions: [
{ header: { name: "Server" } contains: "MyVulnerableApp" }
]
}
}
}
}
The condition is that the header
with name
Server
contains
the string
MyVulnerableApp
.
Now, let’s build a POST
request for our exploitation step:
actions: {
name: "exploitation"
http_request: {
method: POST
uri: "/exploit"
data: "process=%{ print(\"tsunami_%d_marker\", 1250*1+3) }%"
response: {
http_status: 200
expect_all: {
conditions: [
{ body: {} contains: "tsunami_1253_marker" }
]
}
}
}
}
This action is very similar to the previous one but:
- It sends a
POST
request instead of aGET
one; - As part of the
POST
it sendsprocess=%{ print(\"tsunami_%d_marker\", 1250*1+3) }%
as data; - The expectation has been changed to check that the response body
contains
tsunami_1253_marker
.
Redirects
Note that by default, the HTTP client will follow any HTTP redirects.
If you wish to change that behavior, you can configure your HTTP request using
the client_options
stanza. For example, with our previous request:
actions: {
name: "exploitation"
http_request: {
method: POST
uri: "/exploit"
data: "process=%{ print(\"tsunami_%d_marker\", 1250*1+3) }%"
client_options: {
disable_follow_redirects: true
}
response: {
http_status: 200
expect_all: {
conditions: [
{ body: {} contains: "tsunami_1253_marker" }
]
}
}
}
}