6

I've managed to get the cmd being opened by python. However, using runas administrator comes with a password check before cmd.exe is executed.

I'm using this to open cmd...

import subprocess

subprocess.call(["runas", "/user:Administrator", "cmd.exe"])

I'm looking for a way to automatically enter the password into the runas.exe prompt which opens when i run the code. Say if i were to create var = "test" and add it after import subprocess how would i make it so that this variable is passed to and seen as an input to the runas.exe?

The solution would require only python modules which are in version 3.4 or higher.


Update

I have found some code which appears to input straight into runas.exe. However, the apparent input is \x00\r\n when in the code the input is supposed to be test I am fairly certain that if i can get the input to be test then the code will be successful.

The code is as follows :

import subprocess

args = ['runas', '/user:Administrator', 'cmd.exe']

proc = subprocess.Popen(args, 
                        stdin=subprocess.PIPE, 
                        stdout=subprocess.PIPE, 
                        stderr=subprocess.PIPE)

proc.stdin.write(b'test\n')
proc.stdin.flush()

stdout, stderr = proc.communicate()
print (stdout)
print (stderr)
ExoticScarf
  • 75
  • 1
  • 2
  • 8
  • 1
    you can use pexpect module. http://stackoverflow.com/questions/11160504/simplest-way-to-run-expect-script-from-python ; password encryption you need to take-care, if needed. – Hara May 18 '17 at 17:21
  • @Jean-FrançoisFabre the other question you reference is 6 years old with no activity during that time and the answers given are not applicable to my circumstances. – ExoticScarf May 18 '17 at 17:59
  • you're right. But it has no answers maybe because it's not possible using pure python... Someone wants to answer that? I'll reopen. – Jean-François Fabre May 18 '17 at 18:04
  • note: http://stackoverflow.com/questions/4011245/pass-password-to-runas-from-python is an exact duplicate, but the answers are poor. Reopened. Others feel free to close if you're feeling it's not right. – Jean-François Fabre May 18 '17 at 18:05
  • @Jean-FrançoisFabre Potentially. However, it should be possible for python to interact with applications which are running. My hopes is to find a way to take a variable and read it as an input in such an application or alternatively for the shell output to be interpreted as an input for the application. I would be surprised if python didnt allow for this kind of interactions. – ExoticScarf May 18 '17 at 18:11
  • and thank you for reopening the question. – ExoticScarf May 18 '17 at 18:11
  • found that: http://stackoverflow.com/questions/40850563/how-to-send-the-password-after-user-name-in-command-prompt-using-python. As expected no definitive answer on windows. – Jean-François Fabre May 18 '17 at 19:03

2 Answers2

2

This piece of code actually works (tested on a Windows 2008 server). I've used it to call runas for a different user and pass his password. A new command prompt opened with new user context, without needing to enter password.

Note that you have to install pywin32 to have access to the win32 API.

The idea is:

  • to Popen the runas command, without any input redirection, redirecting output
  • read char by char until we encounter ":" (last char of the password prompt).
  • send key events to the console using win32 packages, with the final \r to end the password input.

(adapted from this code):

import win32console, win32con, time
import subprocess

username = "me"
domain = "my_domain"
password ="xxx"

free_console=True
try:
    win32console.AllocConsole()
except win32console.error as exc:
    if exc.winerror!=5:
        raise
    ## only free console if one was created successfully
    free_console=False

stdin=win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)
    
p = subprocess.Popen(["runas",r"/user:{}\{}".format(domain,username),"cmd.exe"],stdout=subprocess.PIPE)
while True:
    if p.stdout.read(1)==b":":
        for c in "{}\r".format(password):  # end by CR to send "RETURN"
            ## write some records to the input queue
            x=win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
            x.Char=unicode(c)  # remove unicode for python 3
            x.KeyDown=True
            x.RepeatCount=1
            x.VirtualKeyCode=0x0
            x.ControlKeyState=win32con.SHIFT_PRESSED
            stdin.WriteConsoleInput([x])

        p.wait()
        break
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • i'm encountering an error with the code regarding the modules with the prefix win32: `ModuleNotFoundError: No module named 'win32console'` I've tried using these modules previously to open cmd and on multiple machines, getting the same error each time. – ExoticScarf May 18 '17 at 19:39
  • even after installation im continuing to get the same error – ExoticScarf May 18 '17 at 19:51
  • 2 versions of python? try to `print(sys.executable)` and see if it's the one you're expecting. – Jean-François Fabre May 18 '17 at 20:05
  • its the version i was expecting. However, i am no longer receiving the error. A window is opening with name of the dir of `pythonw.exe`, i cannot interact with the window in any way and it definitely isnt a cmd window. – ExoticScarf May 18 '17 at 20:10
  • I have edited to change "cmd" by "cmd.exe" (just in case cmd is something else in your system) – Jean-François Fabre May 18 '17 at 21:23
  • I took a crack at generalizing this as a [`runas`](https://pastebin.com/7YQdRyDH) function. – Eryk Sun May 19 '17 at 02:34
  • It supports the `/savecred` option, so it can be called without a password in which case runas.exe will be run detached (without a console). If a password is provided with savecred, it'll be saved in the user's credential vault to be used in the future. It doesn't assume the `StandardInput` handle is a console. It could be a file or pipe in general, so it opens `CONIN$` instead, and ensures these handles and allocated console are freed before returning. It writes the input records for the password in one call instead of a character at a time, and without the shift key. – Eryk Sun May 19 '17 at 02:35
2

Although not an answer to your question, this can be a solution to your problem. Use psexec instead of runas. You can run it like this:

psexec -u user -p password cmd

(or run it from Python using subprocess.Popen or something else)

zmbq
  • 38,013
  • 14
  • 101
  • 171
  • @Jean-FrançoisFabre, but it doesn't answer the question and should have been a comment instead. You answered the question, which in general is the problem of working with commands that insist on reading from the console. – Eryk Sun May 19 '17 at 13:49
  • @eryksun: true (and thanks :)), but if OP's goal is to become someone else without any typing, that works (also needs a third party software). – Jean-François Fabre May 19 '17 at 14:35
  • @Jean-FrançoisFabre, using psexec for the OP's particular problem will work fine, but it doesn't answer the question as asked. A comment can suggest an alternate approach to the overall problem, and the OP can ask a new question to which that's the best answer. ISTM that, as a general rule, we need clear, specific questions with specific answers, which makes it much easier for people to find answers to problems without having to weed through a lot of false positives or information spread thinly across several questions. – Eryk Sun May 19 '17 at 15:15
  • @eryksun you made your point. If the answer specified "as a workaround" it would be better, but I still think that it's better than 2 upvotes for recommending a Windows obsolete command line tool (SANUR) on a non-existent page to do the job. SO quality is improving over the years :) – Jean-François Fabre May 19 '17 at 15:21
  • @Jean-FrançoisFabre, I see your comment on the old question that links to this question. I think you should add your answer there and comment on the old accepted answer to highlight a working alternative. Then close this question. That will make your contribution more obvious to users arriving from Google and other search engines. – Eryk Sun May 19 '17 at 17:25
  • I cannot close since I already closed but I reopened, thinking that that would leave more chance to someone to answer (which was not a good idea I admit). After that I dug a while and could provide an answer. But I closed the _other_ question as a duplicate (to my surprise it worked). So both questions are now linked. – Jean-François Fabre May 19 '17 at 21:22