یک درب پشتی کوچک در Flask یا نحوه کنترل رایانه در یک شبکه محلی

هی هابر!

من اخیراً یک نسخه دانلود شده از جریان برنامه نویسی "چگونه برنامه وب خود را در Flask ایجاد کنیم" تماشا کردم. و تصمیم گرفتم دانش خود را در پروژه ای تثبیت کنم. برای مدت طولانی نمی دانستم چه بنویسم و ​​این ایده به ذهنم خطور کرد: "چرا یک درب پشتی کوچک در فلاسک درست نکنیم؟"

اولین گزینه ها برای پیاده سازی ها و قابلیت های Backdoor بلافاصله در ذهن من ظاهر شد. اما تصمیم گرفتم فوراً لیستی از قابلیت های درب پشتی تهیه کنم:

  1. نحوه باز کردن وب سایت ها را بدانید
  2. دسترسی به خط فرمان داشته باشید
  3. قادر به باز کردن برنامه ها، عکس ها، فیلم ها باشید

بنابراین، اولین نکته با استفاده از ماژول مرورگر وب بسیار آسان است. تصمیم گرفتم نکته دوم را با استفاده از ماژول os پیاده سازی کنم. و سومی نیز از طریق ماژول OS است، اما من از "پیوندها" استفاده خواهم کرد (در ادامه در مورد آن بیشتر خواهد شد).

نوشتن سرور

بنابراین، *drumroll* همه کد سرور:

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’}

خوب، منطقی است که "فرمان" فرمانی است که می خواهیم اجرا کنیم. و "داده" آرگومان های فرمان هستند.

می‌توانید درخواست‌های JSON را بنویسید و ارسال کنید تا به صورت دستی با سرور تعامل داشته باشید (درخواست‌ها به شما کمک می‌کنند). یا می توانید یک کلاینت کنسول بنویسید.

نوشتن مشتری

کد:

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

توضیحات:

اول از همه، ماژول درخواست ها (برای تعامل با سرور) وارد می شود. در زیر توضیحاتی در مورد عملکردهای شروع و آزمایش آورده شده است. و سپس چرخه ای که در آن جادو اتفاق می افتد. آیا کد را خوانده اید؟ بنابراین معنی جادویی که در چرخه اتفاق می افتد را درک می کنید. دستور را وارد کنید - اجرا می شود. Shell – دستورات خط فرمان (منطق خارج از مقیاس است).

تست - بررسی کنید که آیا سرور در حال اجرا است (درپشتی)
پیوند - استفاده از "میانبر"
Openweb - باز کردن یک وب سایت
خروج - خروج از مشتری
تنظیم - تنظیم IP رایانه خود در شبکه محلی

و اکنون بیشتر در مورد پیوند.

یک فایل link.txt در کنار سرور وجود دارد. این شامل لینک (مسیر کامل) به فایل ها (فیلم، عکس، برنامه).

ساختار به این صورت است:

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

مجموع

ما یک سرور درب پشتی برای کنترل کامپیوتر در یک شبکه محلی (در یک شبکه وای فای) داریم. از نظر فنی، ما می‌توانیم کلاینت را از هر دستگاهی که مفسر پایتون دارد اجرا کنیم.

PS دستور set را اضافه کردم تا اگر به رایانه ای در شبکه محلی IP متفاوتی اختصاص داده شود، بتوان آن را مستقیماً در کلاینت تغییر داد.

منبع: www.habr.com

اضافه کردن نظر