Невеликий бекдор на Flask або як керувати комп'ютером у локальній мережі

Привіт, Хабре!

Нещодавно я подивився завантажену версію стриму з програмування "Як створити свій веб-додаток на Flask". І вирішив закріпити свої знання у якомусь проекті. Довго не знав, що написати і мені прийшла ідея: А чому б не зробити міні-бекдор на Flask?.

У голові тут же з'явилися перші варіанти реалізацій та можливостей бекдору. Але я вирішив одразу скласти список можливостей бекдору:

  1. Вміти відкривати сайти
  2. Мати доступ до командного рядка
  3. Вміти відкривати програми, фото, відео

Отже, перший пункт украй легко реалізувати за допомогою модуля webbrowser. Другий пункт вирішив реалізувати за допомогою модуля os. І третій – теж через модуль os, але я використовуватиму «посилання» (про це пізніше).

Написання сервера

Отже, *барабанний дріб* весь код сервера:

from flask import Flask, request
import webbrowser
import os
import re

app = Flask(__name__)
@app.route('/mycomp', methods=['POST'])
def hell():
    json_string = request.json
    if json_string['command'] == 'test':
        return 'The server is running and waiting for commands...'
    if json_string['command'] == 'openweb':
        webbrowser.open(url='https://www.'+json_string['data'], new=0)
        return 'Site opening ' + json_string['data'] + '...'
    if json_string['command'] == 'shell':
        os.system(json_string['data'])
        return 'Command execution ' + json_string['data'] + '...'
    if json_string['command'] == 'link':
        links = open('links.txt', 'r')
        for i in range(int(json_string['data'])):
            link = links.readline()
        os.system(link.split('>')[0])
        return 'Launch ' + link.split('>')[1]
if __name__ == '__main__':
    app.run(host='0.0.0.0')

Я вже вивалив весь код, настав час пояснювати суть.

Весь код запускається на локальному комп'ютері на 5000 портів. Для взаємодії з сервером ми повинні надсилати запит JSON POST.

Структура JSON запиту:

{‘command’:  ‘comecommand’, ‘data’: ‘somedata’}

Ну, логічно, що Command - команда, яку ми хочемо виконати. А data – аргументи команди.

Можна писати та відправляти JSON запити для взаємодії з сервером ручками(вам на допомогу requests). А можна написати консольний клієнт.

Написання клієнта

Код:

import requests

logo = ['nn',
        '******      ********',
        '*******     *********',
        '**    **    **     **',
        '**    **    **     **      Written on Python',
        '*******     **     **',
        '********    **     **',
        '**     **   **     **      Author: ROBOTD4',
        '**     **   **     **',
        '**     **   **     **',
        '********    *********',
        '*******     ********',
        'nn']

p = ''
iport = '192.168.1.2:5000'
host = 'http://' + iport + '/mycomp'

def test():
    dict = {'command': 'test', 'data': 0}
    r = requests.post(host, json=dict)
    if r.status_code == 200:
        print (r.content.decode('utf-8'))

def start():
    for i in logo:
        print(i)

start()
test()

while True:
    command = input('>')
    if command == '':
        continue
    a = command.split()
    if command == 'test':
        dict = {'command': 'test', 'data': 0}
        r = requests.post(host, json=dict)
        if r.status_code == 200:
            print (r.content.decode('utf-8'))
    if a[0] == 'shell':
        for i in range(1, len(a)):
            p = p + a[i] + ' '
        dict = {'command': 'shell', 'data': p}
        r = requests.post(host, json=dict)
        if r.status_code == 200:
            print (r.content.decode('utf-8'))
        p = ''
    if a[0] == 'link':
        if len(a) > 1:
            dict = {'command': 'link', 'data': int(a[1])}
            r = requests.post(host, json=dict)
            if r.status_code == 200:
                print (r.content.decode('utf-8'))
        else:
            print('Комманда не содержит аргументов!')
    if a[0] == 'openweb':
            if len(a) > 1:
                dict = {'command': 'openweb', 'data': a[1]}
                r = requests.post(host, json=dict)
                if r.status_code == 200:
                    print (r.content.decode('utf-8'))
            else:
                print('Комманда не содержит аргументов!')
    if a[0] == 'set':
        if a[1] == 'host':
            ip = a[2] + ':5000'
    if command == 'quit':
        break

Пояснення:

Насамперед імпортується модуль requests(для взаємодії з сервером). Далі опис функцій start і test. А далі цикл у якому відбувається чаклунство. Читали код? Значить вам зрозумілий сенс чаклунства, що відбувається в циклі. Введіть команду – вона виконується. Shell - команди для командного рядка (логіка зашкалює).

Test – перевірка, чи працює сервер (бекдор)
Link – використання «ярлика»
Openweb – відкриття сайту
Quit – вихід із клієнта
Set - завдання ip вашого комп'ютера в локальній мережі

А зараз детальніше про link.

Поруч із сервером лежить файл link.txt. У ньому знаходяться посилання (повний шлях) до файлів (відео, фото, програми).

Структура така:

полный_путь>описание
полный_путь>описание

Підсумок

Ми маємо сервер-бекдор для керування комп'ютером у локальній мережі (всередині wi-fi мережі). Технічно ми можемо запустити клієнт з будь-якого пристрою, на якому є python інтерпретатор.

PS Команду set я додав для того, щоб якщо комп'ютера в локальній мережі привласнять інший ip, можна було просто в клієнті його змінити.

Джерело: habr.com

Додати коментар або відгук