Removed references to printable streams
Also added the initial tests for all GTFO bins.
This commit is contained in:
parent
052bf9b00d
commit
78b12ff915
|
@ -172,11 +172,6 @@
|
|||
"payload": "{command} 'BEGIN {{system(\"{shell} -p\")}}'",
|
||||
"exit": "exit"
|
||||
},
|
||||
{
|
||||
"type": "read",
|
||||
"stream": "print",
|
||||
"payload": "{command} // {lfile}"
|
||||
},
|
||||
{
|
||||
"type": "read",
|
||||
"stream": "raw",
|
||||
|
@ -439,7 +434,7 @@
|
|||
{
|
||||
"type": "read",
|
||||
"stream": "print",
|
||||
"payload": "{command}",
|
||||
"payload": "{command} 2>/dev/null",
|
||||
"args": [
|
||||
"--line-format=%L",
|
||||
"/dev/null",
|
||||
|
@ -909,8 +904,9 @@
|
|||
{
|
||||
"type": "read",
|
||||
"stream": "print",
|
||||
"payload": "{command}",
|
||||
"payload": "{command} | {head} --bytes=-1",
|
||||
"args": [
|
||||
"-a",
|
||||
"''",
|
||||
"{lfile}"
|
||||
]
|
||||
|
@ -1368,11 +1364,6 @@
|
|||
"type": "shell",
|
||||
"payload": "{command} 'BEGIN {{system(\"{shell} -p\")}}'"
|
||||
},
|
||||
{
|
||||
"type": "read",
|
||||
"stream": "print",
|
||||
"payload": "{command} // {lfile}"
|
||||
},
|
||||
{
|
||||
"type": "read",
|
||||
"stream": "raw",
|
||||
|
@ -1445,11 +1436,6 @@
|
|||
"type": "shell",
|
||||
"payload": "{command} 'BEGIN {{system(\"{shell} -p\")}}'"
|
||||
},
|
||||
{
|
||||
"type": "read",
|
||||
"stream": "print",
|
||||
"payload": "{command} // {lfile}"
|
||||
},
|
||||
{
|
||||
"type": "read",
|
||||
"stream": "raw",
|
||||
|
@ -2386,7 +2372,7 @@
|
|||
{
|
||||
"type": "read",
|
||||
"stream": "print",
|
||||
"payload": "{command}",
|
||||
"payload": "{command} | {head} --bytes=-1",
|
||||
"args": [
|
||||
"-m",
|
||||
"{lfile}"
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
import pkg_resources
|
||||
|
||||
from pwncat.util import random_string
|
||||
from pwncat.gtfobins import Stream, Capability
|
||||
from pwncat.platform.linux import LinuxReader, LinuxWriter
|
||||
|
||||
|
||||
def do_file_test(session, content):
|
||||
|
@ -47,3 +54,231 @@ def test_large_binary(session):
|
|||
|
||||
contents = bytes(list(range(32))) * 400
|
||||
do_file_test(session, contents)
|
||||
|
||||
|
||||
# Load the GTFObins database to get test cases
|
||||
with open(pkg_resources.resource_filename("pwncat", "data/gtfobins.json")) as filp:
|
||||
gtfobins = json.load(filp)
|
||||
gtfobin_raw_writers = [
|
||||
key
|
||||
for key, payloads in gtfobins.items()
|
||||
if any(
|
||||
[
|
||||
payload["type"] == "write"
|
||||
and "stream" in payload
|
||||
and payload["stream"] == "raw"
|
||||
for payload in payloads
|
||||
]
|
||||
)
|
||||
]
|
||||
gtfobin_print_writers = [
|
||||
key
|
||||
for key, payloads in gtfobins.items()
|
||||
if any(
|
||||
[
|
||||
payload["type"] == "write"
|
||||
and ("stream" not in payload or payload["stream"] == "print")
|
||||
for payload in payloads
|
||||
]
|
||||
)
|
||||
]
|
||||
gtfobin_raw_readers = [
|
||||
key
|
||||
for key, payloads in gtfobins.items()
|
||||
if any(
|
||||
[
|
||||
payload["type"] == "read"
|
||||
and "stream" in payload
|
||||
and payload["stream"] == "raw"
|
||||
for payload in payloads
|
||||
]
|
||||
)
|
||||
]
|
||||
gtfobin_print_readers = [
|
||||
key
|
||||
for key, payloads in gtfobins.items()
|
||||
if any(
|
||||
[
|
||||
payload["type"] == "read"
|
||||
and ("stream" not in payload or payload["stream"] == "print")
|
||||
for payload in payloads
|
||||
]
|
||||
)
|
||||
]
|
||||
gtfobin_shells = [
|
||||
key
|
||||
for key, payloads in gtfobins.items()
|
||||
if len([payload["type"] == "shell" for payload in payloads])
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("binary", gtfobin_print_readers)
|
||||
def test_gtfobin_read_print(binary, linux):
|
||||
|
||||
# Find the local binary
|
||||
binary_path = linux.platform.which(binary)
|
||||
|
||||
# Skip if binary not available
|
||||
if binary_path is None:
|
||||
pytest.skip("binary not available")
|
||||
|
||||
for method in linux.platform.gtfo.iter_binary(
|
||||
binary_path, caps=Capability.READ, stream=Stream.PRINT
|
||||
):
|
||||
payload, input_data, exit_cmd = method.build(
|
||||
gtfo=linux.platform.gtfo, lfile="/tests/print", suid=False
|
||||
)
|
||||
|
||||
popen = linux.platform.Popen(
|
||||
payload,
|
||||
shell=True,
|
||||
stdin=subprocess.PIPE,
|
||||
bootstrap_input=input_data.encode("utf-8"),
|
||||
)
|
||||
stream = LinuxReader(
|
||||
popen,
|
||||
on_close=lambda filp: filp.popen.platform.channel.send(
|
||||
exit_cmd.encode("utf-8")
|
||||
),
|
||||
name="/tests/print",
|
||||
)
|
||||
|
||||
with stream:
|
||||
assert stream.read() == "Hello\nWorld".encode("utf-8")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("binary", gtfobin_raw_readers)
|
||||
def test_gtfobin_read_raw(binary, linux):
|
||||
|
||||
# Find the local binary
|
||||
binary_path = linux.platform.which(binary)
|
||||
|
||||
# Skip if binary not available
|
||||
if binary_path is None:
|
||||
pytest.skip("binary not available")
|
||||
|
||||
for method in linux.platform.gtfo.iter_binary(
|
||||
binary_path, caps=Capability.READ, stream=Stream.RAW
|
||||
):
|
||||
payload, input_data, exit_cmd = method.build(
|
||||
gtfo=linux.platform.gtfo, lfile="/tests/raw", suid=False
|
||||
)
|
||||
|
||||
popen = linux.platform.Popen(
|
||||
payload,
|
||||
shell=True,
|
||||
stdin=subprocess.PIPE,
|
||||
bootstrap_input=input_data.encode("utf-8"),
|
||||
)
|
||||
stream = LinuxReader(
|
||||
popen,
|
||||
on_close=lambda filp: filp.popen.platform.channel.send(
|
||||
exit_cmd.encode("utf-8")
|
||||
),
|
||||
name="/tests/raw",
|
||||
)
|
||||
|
||||
with stream:
|
||||
assert stream.read() == bytes(list(range(256)))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("binary", gtfobin_raw_writers)
|
||||
def test_gtfobin_write_raw(binary, linux):
|
||||
|
||||
# Find the local binary
|
||||
binary_path = linux.platform.which(binary)
|
||||
|
||||
# Skip if binary not available
|
||||
if binary_path is None:
|
||||
pytest.skip("binary not available")
|
||||
|
||||
for method in linux.platform.gtfo.iter_binary(
|
||||
binary_path, caps=Capability.WRITE, stream=Stream.RAW
|
||||
):
|
||||
payload, input_data, exit_cmd = method.build(
|
||||
gtfo=linux.platform.gtfo, lfile="/tmp/write_raw", suid=False
|
||||
)
|
||||
|
||||
popen = linux.platform.Popen(
|
||||
payload,
|
||||
shell=True,
|
||||
stdin=subprocess.PIPE,
|
||||
bootstrap_input=input_data.encode("utf-8"),
|
||||
)
|
||||
stream = LinuxWriter(
|
||||
popen,
|
||||
on_close=lambda filp: filp.popen.platform.channel.send(
|
||||
exit_cmd.encode("utf-8")
|
||||
),
|
||||
name="/tmp/write_raw",
|
||||
)
|
||||
|
||||
with stream:
|
||||
assert stream.write(bytes(list(range(256)))) == 256
|
||||
|
||||
with linux.platform.open("/tmp/write_raw", "rb") as filp:
|
||||
assert filp.read() == bytes(list(range(256)))
|
||||
|
||||
linux.platform.unlink("/tmp/write_raw")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("binary", gtfobin_print_writers)
|
||||
def test_gtfobin_write_print(binary, linux):
|
||||
|
||||
content = b"Hello\nWorld"
|
||||
|
||||
# Find the local binary
|
||||
binary_path = linux.platform.which(binary)
|
||||
|
||||
# Skip if binary not available
|
||||
if binary_path is None:
|
||||
pytest.skip("binary not available")
|
||||
|
||||
for method in linux.platform.gtfo.iter_binary(
|
||||
binary_path, caps=Capability.WRITE, stream=Stream.PRINT
|
||||
):
|
||||
payload, input_data, exit_cmd = method.build(
|
||||
gtfo=linux.platform.gtfo, lfile="/tmp/write_print", suid=False
|
||||
)
|
||||
|
||||
popen = linux.platform.Popen(
|
||||
payload,
|
||||
shell=True,
|
||||
stdin=subprocess.PIPE,
|
||||
bootstrap_input=input_data.encode("utf-8"),
|
||||
)
|
||||
stream = LinuxWriter(
|
||||
popen,
|
||||
on_close=lambda filp: filp.popen.platform.channel.send(
|
||||
exit_cmd.encode("utf-8")
|
||||
),
|
||||
name="/tmp/write_print",
|
||||
)
|
||||
|
||||
with stream:
|
||||
assert stream.write(content) == len(content)
|
||||
|
||||
with linux.platform.open("/tmp/write_print", "rb") as filp:
|
||||
assert filp.read() == content
|
||||
|
||||
linux.platform.unlink("/tmp/write_print")
|
||||
|
||||
|
||||
# @pytest.mark.parametrize("binary", gtfobin_writers)
|
||||
# def test_gtfobin_write(binary, session):
|
||||
#
|
||||
# # Skip if binary not available
|
||||
# if session.platform.which(binary) is None:
|
||||
# pytest.skip("binary not available")
|
||||
#
|
||||
# return
|
||||
#
|
||||
#
|
||||
# @pytest.mark.parametrize("binary", gtfobin_shells)
|
||||
# def test_gtfobin_shell(binary, session):
|
||||
#
|
||||
# # Skip if binary not available
|
||||
# if session.platform.which(binary) is None:
|
||||
# pytest.skip("binary not available")
|
||||
#
|
||||
# return
|
||||
|
|
Loading…
Reference in New Issue