added services_payload + psexec patch + asm shellcode service #903

wants to merge 1 commit into


None yet
3 participants

agix commented Oct 14, 2012

refer to

In psexec, exe is generated by "generate_payload_exe_service" which uses a template that all the AVs know.
The purpose of this stagers is to add the "service" functions to the payload so you can use "generate_payload_exe" instead of "generate_payload_exe_service".
Used with exe-only, you can bypass a lot of AVs at the moment ;).
To run and to keep running, a service must change his status from START_PENDING to RUNNING.
Here is how the shellcode does :
It first loads advapi32.dll
it constructs a ServiceTableEntry with the ServiceName randomly generated by psexec. And a pointer on ScvMain.
It then calls StartServiceCtrlDispatcherA with the ServiceTableEnry before calling ExitProcess.
The service controller will now load ScvMain
This functions must call RegisterServiceCtrlHandlerExA with the ServiceName and a pointer on a SvcCtrlHandler.
(SvcCtrlHandler just return NO_ERROR all the time)
The shellcode can pass in RUNNING status by calling SetServiceStatus function on the Handler returned by RegisterServiceCtrlHandlerExA with a SERVICE_STATUS structure with dwCurrentState = SERVICE_RUNNING.
It can now do the reverse_tcp stuff or bind_tcp...


jlee-r7 commented Oct 16, 2012

I think it makes more sense to modify to_win32pe_service rather than create a bunch of new payloads that will be useless except in exploits that need a service exe, which is basically just psexec right now.


agix commented Oct 17, 2012

Yes, that seems logical, but the purpose is to encode the "services stuff" and I don't know how to do this after the payload generation, in to_win32pe_service for exemple...


jlee-r7 commented Oct 18, 2012

Ah, I see your point. By the time to_win32pe gets called, the payload is already encoded. Easiest way is probably to use Util::EXE.encode_stub to encode just the service stub in the same way as the rwx stub.


agix commented Oct 19, 2012

Okay, it seems complicated, the service stub has to be push after the winapi_call hash based functions. So I wonder how we can guess where to put the freshly encoded service stub in the middle of the other endoded bytes...


jlee-r7 commented Oct 22, 2012

encode_stub will add a new decoder around the code you give it, there's no need to use the same encoder as for the original payload. Since it's building an exe, you don't have to worry about size.


agix commented Oct 25, 2012

Oh right, I understand. I will try to do that, thanks for the advice.


bperry-r7 commented Jan 12, 2013

Closing due to inactivity and the inability to merge cleanly.

bperry-r7 closed this Jan 12, 2013


agix commented Mar 30, 2013

@jlee-r7 Hi, I'm back on this commit and I have another question now. Even if you encode the service stub with a different encoder. How can you put the payload in the middle of the encoded original payload ? If I understand clearly, you get "encoder(encoded_payload_size)+encoded_payload" and you want I put "encoder2(encoded_payload_service_size)+encoded_payload_service" in the middle of encoded_payload ? But it will break the decoded process of the first decoder no ?

agix referenced this pull request May 19, 2013


Service payloads #1850

@agix agix added a commit to agix/metasploit-framework that referenced this pull request Jan 2, 2014

@agix agix related to rapid7#903
as egyp7 suggested I modified to_win32pe_service instead of create all _service payloads.
Now services are created with any EXE::Template so AV evasion is much more better and psexec will reborn :D
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment