Как запустить python от имени администратора
Перейти к содержимому

Как запустить python от имени администратора

  • автор:

Статья Запускаем скрипт Python от имени администратора в Windows

Иногда, для того чтобы выполнить скрипт на Python нам нужны права администратора. В противном случае, никаких предупреждений от операционной системы вы не увидите, просто будет запрещен доступ на выполнение тех или иных действий. Как пример, могу привести изменение/создание ключа реестра в статье «Изменение MAC-адреса в Linux и Windows с помощью Python». И тогда нужно будет запустить все еще раз, но уже с правами администратора или суперпользователя в Linux.

000.jpg

А как бы сделать так, чтобы скрипт сам проверял, запущена ли оболочка командной строки от имени администратора или нет, и если нет, перезапускал бы скрипт, но уже в оболочке, запущенной с правами администратора?

Вот, что произойдет, если запустить скрипт из статьи указанной выше без прав администратора в Windows:

Запуск скрипта в Windows

001.png

Запуск скрипта в Linux

002.png

Для Windows есть довольно простое решение. Давайте рассмотрим его подробнее.

Для начала нам нужно будет импортировать несколько модулей:

import ctypes import sys import psutil

В том же случае, если интерпретатор заругается и скажет, что у вас не установлен модуль psutil, его надо установить с помощью команды:

pip install psutil

Теперь пишем код который выполнит проверку, запущена ли программа от имени админа или нет, как раз перед тем, как выполнять проверку на имя программы. В этом коде делается проверка, запущена ли оболочка с правами администратора. Если да, то проверка вернет True и запустить функция main(). В противном случае, перезапускается процесс с именем запускаемого файла и повышением прав до администратора. Если у вас не отключен UAC, то нужно будет подтвердить запуск.

if ctypes.windll.shell32.IsUserAnAdmin(): if __name__ == "__main__": main() else: ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)

И все будет работать. Но, тут есть небольшой нюансик. Так как скрипт перезапускается, то остается открытым то окно из которого он запускался изначально. И это не есть хорошо. Можно его закрыть вручную, но если уж автоматизировать, то нужно двигаться дальше. После запука с правами админа нужно будет закрыть окно Командной строки или PowerShell, из которой и запускался изначально скрипт на Python.

Здесь нужно «прибить» сам процесс. И логичнее всего сделать это получив его PID. Собственно PID это идентификатор процесса и является уникальным номером, который присваивается процессу на этапе выполнения. Возникает вопрос, а как этот PID получить? И вот тут на помощь нам придет модуль psutil.

Давайте напишем небольшую функцию для примера, как работает код. Запускаем цикл, в котором пробегаемся по каждому экземпляру объекта созданного psutil и отфильтрованного по значениям pid и name. Где name, это имя запущенного процесса. Не заголовок программы, а именно имя процесса. Далее, в переменную sys_app получаем значение экземпляра с именем, которое обрезаем от лишних точек, так как имя процесса будет выглядеть, к примеру, «cmd.exe». Берем первый элемент получившегося списка и приводим его, на всякий случай к нижнему регистру.

Затем делаем проверку, является ли полученное имя процесса PowerShell или Командной строкой. Так же можно добавить и проверку на то, является ли процесс Windows Terminal. И если это так, запускается процесс в котором получаем pid запущенного приложения и с помощью функции terminate() его завершаем.

Если же запущенный процесс не подходит по нужные параметры, не делаем ничего и продолжаем выполнение цикла.

def printing(): print('Тут мы чего-то печатаем, якобы с правами админа.') for app in psutil.process_iter(['pid', 'name']): sys_app = app.info.get('name').split('.')[0].lower() if 'powershell' in sys_app or 'cmd' in sys_app: try: psutil.Process(app.info.get('pid')).terminate() break except: continue input()

Но, будьте внимательны. Данный код «прибьёт» первый процесс, который будет найден. То есть тот, что запущен позже всех. Если вы запустите скрипт в процессе, который был запущен ранее, то он «прибит» не будет. А если убрать прерывание break в цикле, в этом случае будут «прибиты» все процессы.

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

Код со скриптом перезапуска от имени админа

import ctypes import sys import psutil def printing(): print('Тут мы чего-то печатаем, якобы с правами админа.') for app in psutil.process_iter(['pid', 'name']): sys_app = app.info.get('name').split('.')[0].lower() if 'powershell' in sys_app or 'cmd' in sys_app: try: psutil.Process(app.info.get('pid')).terminate() break except: continue input() def main(): printing() if ctypes.windll.shell32.IsUserAnAdmin(): if __name__ == "__main__": main() else: ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)

Для Linux же подобных решений я не нашел. Наткнулся не небольшой модуль elevate. Но, как по мне, он работает несколько кривовато. Слишком много нужно произвести действий для того, чтобы запустить программу с его использованием. Если интересно, то вот код для его запуска:

import os from elevate import elevate def is_root(): return os.getuid() == 0 print("before ", is_root()) elevate() print("after ", is_root())

Тут собственно проверяется, запущен ли терминал под пользователем или рутом. И если под пользователем, о чем и сообщает возвращаемый код, запускается модуль elevate. По сути, он запускает запрос пароля в графическом режиме. Впрочем, этот режим можно отключить. Но, тут есть одна проблемка. Или даже не одна. Под пользователем root нужного модуля не найдется, так как он не установлен. Дальше, даже если вы установите этот модуль, вас ждет разочарование, так как перезапустившись в терминале под рутом вы получите сообщение, что скрипт, который вы запускаете, не найдет. И да, он не будет найден, потому, что вы запускали его от другого пользователя. И он лежит в другом месте. В этом случае нужно будет запускать скрипт с указанием полного пути к скрипту. Что очень неудобно. Проще, как на мой взгляд, просто выполнить тогда повышение привилегий до рута с помощью sudo su, а дальше уж злодействовать как пожелаете.

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

Python Запуск команды от Админа Windows

PowerShel+Python = RunAsAdmin

Ух… полдня нервов, криков, пота и крови. Я искал как запустить от доменного админа программу. Это жесть. Перепробовал тысячи вариантов и способов. А также пытался понять как мне с reg.exe удаленно работать. Также понял что comanda password у знаменитой утилиты PsExec не работает как должна. Но все по порядку…

Os.system против Subprocess.popen

А началось все с того, что мне надо было как-то незаметно запустить для пользователя архивацию. И тут есть замечательная команда os.system:

import os zip_pass = 'SuperPassword' log_path = 'E:\\path\\to\\dir' os.system('7zip a -tzip -ssw -mx1 -p'+zip_pass+' -r0 -sdel ' + log_path + '\\back_%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%.zip ' + log_path + '\\*.png > nul' )

Однако я это делаю в цикле и при выполнении команды появляется окно cmd. Это меня не устраивало и я искал другой путь. Попробовал subprocess. Все заработало:

import pyscreeze ,subprocess from time import sleep zip_pass = 'SuperPassword' log_path = 'E:\\path\\to\\dir' def screnshot(): # скрин цикл while True: sleep(120) # Pereod making screnshot in sec. try: pyscreeze.screenshot(log_path + '\\' + strftime("%Y-%m-%d-%H.%M.%S", localtime()) + '.png') except Exception: pass subprocess.run(str(exe7z + ' a -tzip -ssw -mx1 -p'+zip_pass+' -r0 -sdel ' + log_path + '\\back_%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%.zip ' + log_path + '\\*.png > nul').split(' '), shell=True) # Making arhive screnshot()

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

Пути неисповедимы или чертов RunAs

На просторах интернета полно рекомендаций с примерно следующем содержанием:

echo password | runas /use:admin@domen c:\programma.exe

Только есть одно «НО» — это не работает начиная с Vista Windows. А все потому, что ради безопасности runas не читает stdin. По этой же причине я 4 часа не мог запустить следующее:

cmd =subprocess.popen('runas /user:admin@domen cmd', stdin=subprocess.PIPE,shell=True) cmd.stdin.write(b'Password\n')

В общем я понял проблему и начал искать обходные пути. Потратив еще час и перебрав разные варианты я нашел ка это можно сделать с помощью PowerShell . Но не все так просто.

Первое знакомство с PowerShell и…

Ни хрена не понятно. Хотя вроде ни чего сложного. Но найденный тут рецепт а именно :

$username = 'user' $password = 'password' $securePassword = ConvertTo-SecureString $password -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential $username, $securePassword Start-Process Notepad.exe -Credential $credential

Не сработал. А вот спустя еще час мучения и лицезрения неверно задано имя папки я понял. Это же DOS! Я вспомнил как у меня были проблемы с тем что я не мог находясь в одном разделе диска вызвать программу из другого. Поняв это я решил проблему, а заодно понял как написать все в одну строку:

powershell $username = 'admin@domen';$password = 'password';$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;c:; Start-Process C:\zabbix\install.bat -Credential $credential

Но и тут не без нюансов. Все команды через «;» а путь у Start-Process не должен выходить в TMP папку. Ну и полный запуск на python.

Запуск батника из python с правами админа

impor os, subprocess if not os.path.exists('C:\\zabbix\\install.log'): subprocess.run(str('xcopy \\\\samba\\shara\\zabbix\\install.bat '+getenv('APPDATA')+' /Y').split(' '), shell=True) subprocess.Popen("powershell $username = 'admin@domen';$password = 'password';$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;c:; Start-Process "+getenv('APPDATA')+"\\install.bat -Credential $credential", shell=True)

Вот так я про#бал мой первый день отпуска. Надеюсь еще напишу более подробную статью о том как я свой кейлогер с бекджеком и шлюхами писал…. Удачи!

Как запустить файл от имени администратора python?

dimonchik2013

Maxim Siomin, Как программа запущенная не от имени администратора, и не администратором, может запустить что-то от имени администратора? Не ну ты чего, Максим?

dimonchik2013

Dimonchik @dimonchik2013
ну там код тот длинный поковыряй, общая идея понятна

phaggi

Алан Гибизов @phaggi Куратор тега Python

javedimka, в принципе может. Ну, раньше могла, давно не пробовал. Была такая утилитка sanur, она умела правильно запустить runas, если конечно знаешь логин/пароль админские.

Как сделать запуск файла Python от имени администратора?

Пытаюсь сделать сниффер пакетов. При выполнении получаю ошибку OSError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions Попытался решить при помощи

import admin if not admin.isUserAdmin(): admin.runAsAdmin() 

получаю -> AttributeError: module ‘admin’ has no attribute ‘isUserAdmin’ Как пофиксить?

Отслеживать

230 1 1 серебряный знак 8 8 бронзовых знаков

задан 12 июл 2021 в 14:09

Alex — stop hating Russia Alex — stop hating Russia

1 1 1 бронзовый знак

Модуль отсюда брали?

12 июл 2021 в 14:49

Никак нет. Наткнулся на такой вариант решения, не помогло(

12 июл 2021 в 14:52

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Можно проверить админ ли вы и при необходимости перезапустить скрипт с правами админа.

import ctypes import os import sys def is_admin(): """Проверяем права""" try: # Если админ вернет True return ctypes.windll.shell32.IsUserAnAdmin() except: return False if is_admin(): # Если админ продолжаем скрипт дальше input(" As Admin. \n Press Enter!") else: # Перезапускаем скрипт с правами админа ctypes.windll.shell32.ShellExecuteW( None, "runas", sys.executable, __file__, None, 1 ) exit() # выходим из старой версии скрипта print("your code. ") # что-бы скрипт не закрылся мгновенно os.system("pause") 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *