Малка задна врата на 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 'Сървърът работи и чака команди...'
    if json_string['command'] == 'openweb':
        webbrowser.open(url='https:\/\www.'+json_string['data'], new=0)
        return 'Отварям сайт ' + json_string['data'] + '...'
    if json_string['command'] == 'shell':
        os.system(json_string['data'])
        return 'Изпълнение на команда ' + 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 'Стартиране ' + 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',
        '******      ********',
        '*******     *********',
        '**    **    **     **',
        '**    **    **     **      Написано на Python',
        '*******     **     **',
        '********    **     **',
        '**     **   **     **      Автор: 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.

P.S. Командата set добавих, за да може, ако на компютъра в локалната мрежа бъде зададен друг ip, да може директно от клиента да бъде променен.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster