Sign in to follow this  
Followers 0
inopia

Error when using ($STDIN_CHILD, $STDOUT_CHILD)

7 posts in this topic

Hey fellow scripters!

I wanted to create a script to change the bitlocker PIN of our Win7 machines for users without admin rights. While researching I found out, that this doesn't seem to be an easy task. I came up with a pretty dirty solution:

$gui=GUICreate("Bitlocker PIN",180,180,-1,-1,$WS_SYSMENU,-1)
GUICtrlCreateLabel("PIN eingeben (min. 6 Zeichen):",15,15,150,15,-1,-1)
$bit1=GUICtrlCreateInput("",15,30,150,20,$ES_PASSWORD,$WS_EX_CLIENTEDGE)
GUICtrlCreateLabel("PIN bestätigen:",15,60,77,15,-1,-1)
$bit2=GUICtrlCreateInput("",15,75,150,20,$ES_PASSWORD,$WS_EX_CLIENTEDGE)
$button=GUICtrlCreateButton("Neue PIN Setzen",35,110,110,30, $BS_DEFPUSHBUTTON, -1)
GUISetState(@SW_SHOW,$gui)

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
                ExitLoop
            Case $button
                $res1=GUICtrlRead($bit1)
                $res2=GUICtrlRead($bit2)
                If $res1 = $res2 And StringLen($res1) >= 6 Then
                    GUISetState(@SW_HIDE,$gui)
                    ClipPut ($res1)
                    BlockInput(1)
                    $proc=RunAs($o1acc, $domain, $o1pwd, 2, @ComSpec & " /c C:\Windows\System32\manage-bde.exe -changepin c:")
                    WinWaitActive("C:\Windows\system32\cmd.exe","")
                    Sleep(2000)
                    Send ("!{Space}")
                    Sleep(20)
                    Send ("B")
                    Sleep(20)
                    Send ("E")
                    Sleep(20)
                    Send ("{ENTER}")
                    Sleep(100)
                    Send ("!{Space}")
                    Sleep(20)
                    Send ("B")
                    Sleep(20)
                    Send ("E")
                    Sleep(20)
                    Send ("{ENTER}")
                    WinWaitClose("C:\Windows\system32\cmd.exe")
                    Sleep(100)
                    BlockInput(0)
                    ExitLoop
                ElseIf StringLen($res1) < 6 Then
                    MsgBox($MB_ICONERROR,"Fehler","PIN zu kurz. Minimum 6 Zeichen.")
                Else
                    MsgBox($MB_ICONERROR,"Fehler","PINs sind nicht gleich."&@WindowsDir)
                EndIf
        EndSwitch
    Sleep(20)
WEnd

It works on my test system, but the problem here is, that a user could easily pause the script and have a nice cmd with elevated rights.

So I wanted to give $STDIN_CHILD + $STDOUT_CHILD and StdoutRead + StdinWrite a try. The problem here was, that when I executed the command it would give me the following output:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

C:\Windows\System32>manage-bde.exe -changepin c:

BitLocker-Laufwerkverschlüsselung: Konfigurationstoolversion 6.1.7601
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.


FEHLER: Ein Fehler ist aufgetreten (Code 0x80070006):
Das Handle ist ungültig.

~ Error: An error occured (Code 0x80070006)

    Invalid handle .

This is the code that I tried:

$pid = RunAs($acc, $domain, $pwd, 2, @ComSpec, "C:\Windows\System32\", @SW_SHOW, BitOR($STDERR_CHILD, $STDIN_CHILD, $STDOUT_CHILD))
StdinWrite($pid, "manage-bde.exe -changepin c:" & @CRLF)

While Sleep(50)
    $sOut = StdoutRead($pid)
    If @error Then ExitLoop
    If $sOut <> "" Then ConsoleWrite($sOut & @CRLF)
WEnd

Has anyone experienced errors like this (or has a better solution for changing the bitlocker PIN)?

 

Regards

ino

Share this post


Link to post
Share on other sites



Try

$pid = RunAs($acc, $domain, $pwd, 2, @ComSpec, "C:\Windows\System32\", @SW_SHOW, BitOR($STDERR_MERGED,$STDIN_CHILD))

 

Share this post


Link to post
Share on other sites
5 minutes ago, AutoBert said:

Try

$pid = RunAs($acc, $domain, $pwd, 2, @ComSpec, "C:\Windows\System32\", @SW_SHOW, BitOR($STDERR_MERGED,$STDIN_CHILD))

 

Thank you for your response. 

It didn't work. The result is still the same.

Share this post


Link to post
Share on other sites

First few things.  Using the RunAs or RunAsWait function does not give you the full admin token under Windows 7.  It only runs the process under the context of the user specified, even if that user is an Admin on the PC.  You can check to see if the RunAs user has the full admin token with the IsAdmin function.  If it does not, the manage-bde command will fail for not having full admin rights.  You are trying to StdinWrite to cmd.exe, instead of manage-bge.exe directly.  Also, is the script running as 32, 64 bit, or both PC?

Here is an example script to run with the full admin token from a user that is not an admin.  To do what you would like to do, it could be modified to do that. 

Concerning manage-bde, run it directly, after you get the script elevated correctly.   Read the output for the prompt to enter the PIN with StdoutRead, and then use StdinWrite to enter the new PIN.  The Run command would be the following.  I used @SW_SHOW for testing to see what is going on.  Normally you would want to use @SW_HIDE.  

$iPID = Run("C:\Windows\System32\manage-bde.exe -changepin c:", "C:\Windows\System32\", @SW_SHOW, BitOR($STDERR_MERGED, $STDIN_CHILD))

 

Adam

Share this post


Link to post
Share on other sites

Hello Adam, 

thank you for answering.

All of our machines are running on 64-Bit Win7. Your Script results in IsAdmin => 1 so it seems that we have full admin access. Nonetheless executing the manage-bde.exe with BitOR($STDERR_MERGED, $STDIN_CHILD) will result in the same error as I stated above. Without it the console windows appears just fine asking for a new PIN.

 

~ino

Share this post


Link to post
Share on other sites

Your welcome.  Did you run the Run command at the end of the example script, or did you run it separately?  Invalid handle sounds like a permission issue.  That is why I ask.  

Adam

Share this post


Link to post
Share on other sites

I tried both, running it after your example script as well as running it standalone in my code.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • hcI
      By hcI
      Hello I would like to know if there is a way to return a sentence in cmd when I launch from it (because I add arguments).
      For example, diskpart.exe which help to manage the key and hdd connected, when you launch it with the parameter "/f" the app return a sentence saying that it don't recognize the parameter "/f" and it return the sentence in the cmd where i started the application, not a new one.
      That's what I want to do but I couldn't find anything that would solve my problem on internet and on AutoIt like ConsoleWrite / ConsoleWriteError (don't work).
       
      Thanks
    • Duck
      By Duck
      I'm attempting to capture the output from the command line tool PSEXEC. I'm using AutoIT to run an instance of PSEXEC against a remote PC to audit Local Admins in my environment using net.exe (C:\Windows\System32> net localgroup administrators). However the usual trick I use to capture command line output does not appear to work well with PSEXEC, as the bottom portion of the output is missing from the return. Any ideas or recommendations are greatly appreciated.  
       
      Here is what I'm working with: 
      ;This script will read from a list of hosts and report who has local admin privileges on the machine #RequireAdmin Global $fileName = @ScriptDir & '\test.txt' ;hostlist, one host per line readHostList() ;Read list of hosts Func readHostList() Local $file = FileOpen($fileName, 0) While 1 $line = FileReadLine($file) If @error = -1 Then ExitLoop ConsoleWrite($line & @CRLF) ;MsgBox(0,0,$line) getLocalAdmins($line) WEnd FileClose($file) EndFunc ;run PSEXEC to list local admins Func getLocalAdmins($remotePC) Local $testFile = @ScriptDir &'\test234.txt' FileOpen($testFile, 1) Local $psexec = 'psexec \\' & $remotePC & ' net localgroup administrators' FileWriteLine($testFile, _RunCmd($psexec) ) FileClose($testFile) EndFunc ;Used to return CLI output Func _RunCmd($sCommand) Local $nPid = Run(@Comspec & " /c" & $sCommand, @SystemDir, @SW_Hide, 8), $sRet = "" If @Error then Return "ERROR:" & @ERROR ProcessWait($nPid) While 1 $sRet &= StdoutRead($nPID) If @error Or (Not ProcessExists ($nPid)) Then ExitLoop WEnd Return $sRet EndFunc  
      ## If i manually run the command on the remote PC via PSEXEC I will get the following output: 
      PsExec v2.11 - Execute processes remotely
      Copyright (C) 2001-2014 Mark Russinovich
      Sysinternals - www.sysinternals.com
      Starting net on PCNAME... on PCNAME...
      net exited on PCNAME with error code 0.
      -------------------------------------------------------------------------------
      admin
      Administrator
      Alias name     administrators
      Domain\Domain Admins
      Comment        Administrators have complete and unrestricted access to the computer/domain
      Members
      The command completed successfully.
       
      ## The returned output from running the above script is as follows:
      PsExec v2.11 - Execute processes remotely
      Copyright (C) 2001-2014 Mark Russinovich
      Sysinternals - www.sysinternals.com
      Alias name     administrators
      Connecting to PCNAME...
      Starting PSEXESVC service on PCNAME...
      Connecting with PsExec service on PCName...
      Starting net on PCNAME..
      net exited on PCNAME with error code 0.
       
      **Note to test this script PSEXEC must be in the system dir or the path in the script changed 
      PSEXEC tool: https://docs.microsoft.com/en-us/sysinternals/downloads/psexec
    • luckyluke
      By luckyluke
      Hello,
      Im trying to read the output from CMD using Dllcall, here is my code:
      #include <WinAPI.au3> #include <array.au3> Global Const $STD_OUTPUT_HANDLE = -11 Global Const $_CONSOLE_SCREEN_BUFFER_INFO = _ "struct;int dwSizeX;" & _ "short dwSizeY;" & _ "short dwCursorPositionX;" & _ "short dwCursorPositionY;" & _ "short wAttributes;" & _ "short Left;" & _ "short Top;" & _ "short Right;" & _ "short Bottom;" & _ "short dwMaximumWindowSizeX;" & _ "short dwMaximumWindowSizeY;endstruct" $pCmd = Run( "cmd.exe" ) Sleep(1000) $hCmd = WinGetHandle("") ConsoleWrite('handle:' & $hCmd & @CRLF) $aRet = DllCall("kernel32.dll", "int", "AttachConsole", "dword", $pCmd) ;_ArrayDisplay($aRet) If $aRet[0] <> 0 Then $vHandle_data='' $vHandle='' $vHandle_data = DllStructCreate($_CONSOLE_SCREEN_BUFFER_INFO) ; Screen Buffer structure $aRet1 = DllCall("kernel32.dll", "hwnd", "GetStdHandle", "dword", $STD_OUTPUT_HANDLE) if not @error Then $vHandle = $aRet1[0] $aRet = DllCall("kernel32.dll", "int", "GetConsoleScreenBufferInfo", "hwnd", $vHandle, _ "ptr", $vHandle_data) MsgBox(0, '1',DllStructGetData($vHandle_data, 'dwSizeX') & _WinAPI_GetLastErrorMessage()) EndIf It did not work, i got the message 'The handle is invalid'. Please help?
      Thank you in advance!
    • mihaijulien
      By mihaijulien
      Hello,
      I compiled a script I made that takes a command line parameter (the version of a .msi installer) when launched. The script was compiled with the /console option. The script (.au3) works fine but the executable returns  the following error:  
      Error: array variable has incorrect number of subscripts or subscript dimension range exceeded  
    • fosil
      By fosil
      Hi everyone.

      I'm currently working a program that constantly prints out log files through "consolewrite" and the "#AutoIt3Wrapper_Change2CUI=y" wrapper.

      Part of this program requires me to run a batch script.

      My issue is the batch script launches from the same window as consolewrite. I need the batch file to be launched through a different window as currently this causes an issue with the logs (which need to be very precise) but also causes the batch file to produce some funny behavior...

      Does anyone know how I can force the file to run on a second DOS window?

      Thanks in advance!!!
       
      Edit: Im using the "run" command if that helps. I tried "shellexecute" but that seemed to not launch the batch scripts at all.