Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors with long commands in psexec.py #319

Open
tlathm opened this issue Sep 14, 2017 · 25 comments
Open

Errors with long commands in psexec.py #319

tlathm opened this issue Sep 14, 2017 · 25 comments
Labels
help wanted Help is needed to solve or implement something

Comments

@tlathm
Copy link

tlathm commented Sep 14, 2017

First of all thanks for all the work that's gone into all of this. Great stuff!

I'd be glad to see if I could assist with this one, though I'd need some guidance for sure. I've noticed, as have others apparently, that the psexec.py example seems to fail with a status 1 on longer commands. It's hard to be sure, but it appears that this happens with commands longer than about 257 characters. Testing this with a command like "cmd /c echo 'some-long-string'" it appears that the full command is in fact running (I see the entire string echoed) but it exits with a status 1. If the command is long enough to cause this, it will fail that way every time.

Some failures attempting to run SQL with the SQLCMD program show evidence that the commands may be getting truncated. That's hard to tell however, as SQLCMD in general, although it seems to work with winexe, behaves rather strangely...sometimes outputting literal backspace characters or even nothing at all.

Again, I'd be glad to dig into this with a little guidance. I see that the command is put into a Structure with apparently 4096 characters reserved, which should be large enough for anything I've tested...so the issue must be elsewhere. Thanks!

@asolino
Copy link
Collaborator

asolino commented Sep 15, 2017

Hey @tlathm

Thanks for the issue report. Don't know exactly where the limitation is, might need to take a deeper look at it.
Just in case, did you try the same tests with wmiexec.py?

@tlathm
Copy link
Author

tlathm commented Sep 15, 2017

Thanks for the reply! I just tried with wmiexec.py and that does NOT have the same issue. Thanks!

@asolino
Copy link
Collaborator

asolino commented Sep 15, 2017

That is good to know :) I think the psexec.py is not in my Python code but inside the RemCom service, and that will take more time to understand/fix.
wmiexec.py is actually a better approach when it works.

@asolino asolino added the help wanted Help is needed to solve or implement something label Sep 15, 2017
@tlathm
Copy link
Author

tlathm commented Sep 15, 2017

Thanks. I may look into that. I'm not sure if access to the DCOM ports will be an issue for us or not. Do you have any idea why wmiexec.py would hang if I try to redirect it to a file or pipe it to "tee "? Thanks!

asolino added a commit that referenced this issue Sep 16, 2017
* This was preventing using tee or redirect output to a file
* Reported by @tlathm in #319
@asolino
Copy link
Collaborator

asolino commented Sep 16, 2017

Hey @tlathm

Yes, and it's happening to me as well.. and that had to do with some character encodings that wmiexec.py uses. Give it another try now (git pull first).

Now.. going back to psexec.py maybe you can use the -c switch. A workaround solution would be to save the commands in a BAT file, upload it, and execute it at the target. That's what the -c is for:

$ cat /tmp/cmd.bat 
echo Hello World!
$ ./psexec.py -c /tmp/cmd.bat [email protected] 
Impacket v0.9.16-dev - Copyright 2002-2017 Core Security Technologies

Password:
[*] Requesting shares on 192.168.30.170.....
[*] Found writable share ADMIN$
[*] Uploading file ahExQFAH.exe
[*] Opening SVCManager on 192.168.30.170.....
[*] Creating service SHYj on 192.168.30.170.....
[*] Starting service SHYj.....
[*] Uploading file cmd.bat
[!] Press help for extra shell commands

C:\Windows\system32>echo Hello World! 
[*] Process cmd.bat cmd.exe finished with ErrorCode: 0, ReturnCode: 0
[*] Opening SVCManager on 192.168.30.170.....
Hello World!
[*] Stoping service SHYj.....
[*] Removing service SHYj.....
[*] Removing file ahExQFAH.exe.....
$ 

@tlathm
Copy link
Author

tlathm commented Sep 16, 2017

Awesome! Thanks. I'll give that change related to wmiexec.py a try. We're thinking of possibly pursuing that in place of psexec.py actually. You're probably correct that sending the batch file would work, though I'm not sure we could always get away with that. I take that the long command limit may be occurring in the RemComSvc executable itself? That would make sense.

Completely unrelated question at the risk of being very OT, but this just didn't warrant opening an issue: In code such as the wmiquery.py example, is it possible to determine when a single WMI command run via onecmd() failed? What I've found is that some errors like invalid namespaces get caught as an exception in that code, but others such as an invalid class don't. So far those errors seem buried in there somewhere. Thanks!

@tlathm
Copy link
Author

tlathm commented Sep 16, 2017

Oh...and yes, that UTF-8 default does correct that redirection of stdout in wmiexec.py. Thanks!

@asolino
Copy link
Collaborator

asolino commented Sep 18, 2017

In code such as the wmiquery.py example, is it possible to determine when a single WMI command run via onecmd() failed? What I've found is that some errors like invalid namespaces get caught as an exception in that code, but others such as an invalid class don't. So far those errors seem buried in there somewhere.

Could you elaborate this a lil bit more? Feel free to issue PRs if you see something not working (and know how to fix it ;) )

@tlathm
Copy link
Author

tlathm commented Sep 18, 2017

Maybe I should start a new issue on that one, as it'll get way OT(?). Actually I have the same question with wmiexec.py, which is similar. Basically I'm looking for a way that the calling script (in these cases the wmiexec.py and wmiquery.py) can reliable know whether or not a command run with onecmd() worked or not, so it can exit with a non-zero status if it didn't. The scripts seem to report errors from code buried somewhere, but the calling script only really knows about errors that cause it to catch an exception.

@asolino
Copy link
Collaborator

asolino commented Sep 18, 2017

Yep.. better off that start a new Issue.

@tlathm
Copy link
Author

tlathm commented Sep 20, 2017

A few observations, back to the issue topic: There's no question that full commands well in excess of the problem length are running correctly. I've even been able to run rather long base64 encoded PowerShell scripts using the -EncodedCommand option. That runs the script, which proves that the entire command is running...otherwise the base64 decode would fail for sure.

It is in fact the RemComSvc executable that's failing with the longer command. See this from the application event log after one of the status 1 failures:

``Faulting application name: jpZemQKu.exe, version: 0.0.0.0, time stamp: 0x5023cfb1

Faulting module name: jpZemQKu.exe, version: 0.0.0.0, time stamp: 0x5023cfb1
Exception code: 0xc0000409
Fault offset: 0x000016a8
Faulting process id: 0xafc
Faulting application start time: 0x01d33220b8590f54
Faulting application path: C:\WINDOWS\jpZemQKu.exe
Faulting module path: C:\WINDOWS\jpZemQKu.exe
Report Id: 0aba7e29-0f14-4150-841a-2ad57baa1fde
Faulting package full name:
Faulting package-relative application ID: ``

So it's clearly an issue there. Question: As far as I've been able to tell, that service executable is compiled as x86. Is that correct?

Forum side note: For some reason, the forum code quoting isn't properly retaining new lines unless I add that extra break after the first line...odd.

Thanks!

@tlathm
Copy link
Author

tlathm commented Sep 20, 2017

Check it out. There's as issue logged against the RemCom project regarding a 0x100 (256) limit on commands:

kavika13/RemCom#13

The issue says something about sending a patch, though I see no attachment etc.

EDIT: It appears that may have been referring the the RecCom client and not the service:

RemCom.cpp:#define SIZEOF_BUFFER 0x500

@asolino
Copy link
Collaborator

asolino commented Sep 20, 2017

Hey @tlathm

So it's clearly an issue there. Question: As far as I've been able to tell, that service executable is compiled as x86. Is that correct?

That is correct.. That's on purpose in order avoid detecting the target infrastructure and having two different binaries.

Just in case you're wondering, the binary is located here, compilated statically so it works in the biggest amounts of OSes.

@tlathm
Copy link
Author

tlathm commented Sep 20, 2017

Thanks! Yes I've seen that. I sort of hope someone who's way more of a Windows person than I can look into this one. Just attempting to install visual studio and compile that was pretty much just a rathole to hell for me ;).

@tlathm
Copy link
Author

tlathm commented Sep 22, 2017

A few things I've tested, and one thing that's very frustrating: Since I haven't been able to compile RemComSvc I decided to try the RemCom binary version to see if it had issues with longer commands, and it apparently does not.

Then I wanted to isolate it's actual service executable file. I simply cannot figure out how to do so. The RemCom client program is a single executable. Even when I use it running "cmd", which stays at a program until you exit, I simply cannot find any trace of it's running service or executable.

Any ideas what's going on there? It certainly appears that RemCom would have a service installed and running while it was in use just like psexec.py(???). Totally lost.

@asolino
Copy link
Collaborator

asolino commented Sep 22, 2017

Hey @tlathm

Any ideas what's going on there? It certainly appears that RemCom would have a service installed and running while it was in use just like psexec.py(???). Totally lost.

Probably everything is included in the same executable that exports the necessary functions to act as a service and also as a standalone executable.

Hey btw.. I just tried psexec.py against a machine, with a long command and everything seems to be working well.

This is the command I ran:

./psexec.py Administrator@freefly-dc "cmd.exe /c echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEND > \btobto"

Quotes are very important. After executing this, I get a btobto file created at the root directory (3806 bytes long) with the right contents.

@tlathm
Copy link
Author

tlathm commented Sep 22, 2017

I think you're missing what I've been saying above: All of my tests including one just like yours appear to work as well, however they exit with a status 1 and crash the RemConSvc on the Windows side. Try your test followed by "echo $?". If you get 1 then you'll probably see the service crash in the Windows Application event log.

@asolino
Copy link
Collaborator

asolino commented Sep 22, 2017

You absolutely correct @tlathm. I see the eventlog (EventID 1000) entry at the target machine. Thanks for the clarification.

@tlathm
Copy link
Author

tlathm commented Sep 22, 2017

Also, when I use the RemCom binary running the long command, it works and gets a %ERRORLEVEL% of 0.

I'm still totally confused with that RemCom binary though. I don't see it creating ANY running service at all with any binary. I thought that might have been because I was running it on the same machine against the machines IP address, so I tried it from another and couldn't get it to work at all. I keep getting errors that the file is not found when it's trying to start the service. Totally lost of all that.

@asolino
Copy link
Collaborator

asolino commented Sep 22, 2017

Running it in the same machine takes a different route.. https://github.com/kavika13/RemCom/blob/master/RemCom.cpp#L2016, starting a local process and not creating a service.

@tlathm
Copy link
Author

tlathm commented Sep 22, 2017

That makes sense. Running it against another machine with your long command above did in fact cause a failure. In fact a GUI failure dialog popped up. It appears that it takes a much longer command to cause a failure than with psexec.py, but I'm having a VERY hard time testing that. The binary RemCom does very strange things for me. It keeps going into a state where it can't start the remote service, which I can only correct by rebooting that machine. I'm frankly a little afraid to use it.

@tlathm
Copy link
Author

tlathm commented Sep 23, 2017

This is odd: When I use the binary RemCom client and execute cmd.exe remotely, I simply can NOT find any trace of the running service or it's executable on the remote machine while I'm in there at the command prompt. Totally stumped. Doesn't RemCom create some random service / exe just like psexec.py?

@tlathm
Copy link
Author

tlathm commented Sep 25, 2017

I was finally able to find the binary service executable installed by the binary RemCom client (at c:\Windows\system32\RemComSvc.exe). I noticed that for whatever reason, it was 16384 bytes, as compared to the 56320 exe that gets installed by psexec.py. I was however able to test psexec.py using that executable, and it too fails on the longer commands.

Trying to assess whether or not the RemCom binary itself fails for any of these has been VERY difficult. For me at least (running on and against Windows 10) that RemCom binary has been fragile as eggs for some reason. I was in fact able to test several remote "cmd /c echo" commands that worked and where far longer than the ones failing in pspexec.py. For whatever reason however, that RemCom client/service keeps getting into a state where it gets this:
Couldn't start remote service The system cannot find the file specified.
...at which point only a reboot of the remote system will fix it. Maddening to say the least.

@tlathm
Copy link
Author

tlathm commented Sep 26, 2017

As I briefly mentioned on another issue, I may see if I can get a friend who's a very knowledgable Windows programmer to help with the RemCom side of this. One quick question regarding the hexlified binary that's currently in remcomsvc.py: You mentioned that that was statically compiled. Did you actually compile that or was that from the RemCom project itself? Thanks!

@asolino
Copy link
Collaborator

asolino commented Sep 26, 2017

Hey @tlathm
Yes indeed, the binary that is inside impacket was compiled by me (a long time ago actually), with most of the libraries statically linked so it could work on many different OS versions (If I remember well it works from Windows 2000 on).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Help is needed to solve or implement something
Projects
None yet
Development

No branches or pull requests

2 participants