Flaskтеги кичинекей бэкдор же локалдык тармактагы компьютерди кантип башкаруу керек

Эй Хабр!

Мен жакында “Фласкта өзүңүздүн веб тиркемеңизди кантип түзсө болот” программалоо агымынын жүктөлүп алынган версиясын көрдүм. Ал эми билимимди кандайдыр бир долбоордо бекемдөөнү чечтим. Мен көптөн бери эмне жазарымды билбей жүрдүм жана мага: "Эмне үчүн Flask менен мини-бэкдор жасашпайт?"

Ишке ашыруунун биринчи варианттары жана бэкдордун мүмкүнчүлүктөрү менин башымда дароо пайда болду. Бирок мен дароо эле бэкдордук мүмкүнчүлүктөрдүн тизмесин түзүүнү чечтим:

  1. Вебсайттарды ачууну билиңиз
  2. Буйрук сабына кирүү мүмкүнчүлүгү бар
  3. Программаларды, сүрөттөрдү, видеолорду ача билүү

Ошентип, биринчи пункт веб-браузер модулу аркылуу ишке ашыруу үчүн абдан жеңил болуп саналат. Мен 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’}

Ооба, "буйрук" бул биз аткаргыбыз келген буйрук экени түшүнүктүү. Ал эми "маалыматтар" - бул буйруктун аргументтери.

Сервер менен кол менен иштешүү үчүн 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 – буйрук сабы үчүн буйруктар (логика масштабдуу эмес).

Сыноо - сервер иштеп жатканын текшериңиз (backdoor)
Шилтеме - "кыска жолду" колдонуу
Openweb – веб-сайтты ачуу
Чыгуу – кардардан чыгуу
Орнотуу – жергиликтүү тармактагы компьютериңиздин IP дарегин орнотуу

Ал эми азыр шилтеме жөнүндө көбүрөөк.

Сервердин жанында link.txt файлы бар. Ал файлдарга (видеолорго, сүрөттөргө, программаларга) шилтемелерди (толук жол) камтыйт.

структурасы мындай:

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

жыйынтык

Бизде локалдык тармактагы (wi-fi тармагынын ичинде) компьютерди башкаруу үчүн бэкдор серверибиз бар. Техникалык жактан биз кардарды питон котормочусу бар каалаган түзмөктөн иштете алабыз.

PS Мен орнотулган команданы коштум, эгерде локалдык тармактагы компьютерге башка IP ыйгарылган болсо, аны түздөн-түз кардарда өзгөртүүгө болот.

Source: www.habr.com

Комментарий кошуу