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
Make sure winexec is 16 byte aligned and add nCmdShow option #2308
Conversation
Email z niedzieli 26 listopada 2023 od Chrisa Yuena:
WinExec currently errors out when tested on Windows 11 x64. After some diagnosis it appears that `pushstr` aligns to 8 bytes but Windows calling convention [requires 16 byte](https://learn.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-170). Perhaps this was not enforced in previous versions of Windows but apparently that is the standard requirement.
Not sure this is correct. I would prefer the stack move to be in a separate variable, and then the extra alignment to be just `stack_move & 8`, because the tons of math involved seem too convoluted to read.
I also intend to stress that Windows is not a primary exploitation target for pwntools, as there are better tools for that (metasploit for instance), and there is no easy way to test the shellcraft payloads on the CI. I see that the payloads are used, which is great, because I did not even expect that. Thanks for taking your time to fix it.
…--
Wysłane z mojego urządzenia Sailfish
|
Thanks for the reply!
My experience suggests otherwise. It is extremely convoluted, if not impossible (I never managed to get it work after some trials and errors) to get any Metaploit shellcode to work on modern Windows without Defender flagging it, due to its popularity. (That's how I landed here ;) Metasploit's address loader (to get position independence) with its customized "hashing algorithm" is probably too popular. Even something like
Anyway, regarding this PR -- happy to change it in a way that's more obvious but not sure what you meant by a "separate variable"? Anyway to shed some clarity this is what the math is basically trying to do:
To see what it does:
pad = align(8, len(cmd) + 1) // 8 % 2 ^ 1 * 8 # * 8 because we do 8 bytes multiple. Surprisingly the operator precedences just worked out without extra parentheses
Yes, thus tried to add screenshots and sufficient PoC codes so this can be hopefully easier to verify. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thank you!
The shellcode should be null and newline free and so those dynamic stack shifts feel bad. Could we get away with some and rsp, -32
to align it down?
https://github.com/masthoon/pwintools/blob/master/pwintools.py#L951
Edit: I guess it's not about the sub
with the 0x30 or 0x38 constants, but more about the add
if it exceeds 0x7f?
Co-authored-by: peace-maker <peacemakerctf@gmail.com>
Sure, just pushed that please take a look |
Thanks, this looks good now. The only problem I still see with this shellcode (while we're at it) is the
to let |
Pwntools Pull Request
Thanks for contributing to Pwntools! Take a moment to look at
CONTRIBUTING.md
to make sure you're familiar with Pwntools development.WinExec currently errors out when tested on Windows 11 x64. After some diagnosis it appears that
pushstr
aligns to 8 bytes but Windows calling convention requires 16 byte. Perhaps this was not enforced in previous versions of Windows but apparently that is the standard requirement.Example programs to reproduce the issue:
Screenshot:
As seen above,
rsp
is not 16 byte aligned causesmovaps
to error outAdditionally,
nCmdShow
argument support is addedTesting
Pull Requests that introduce new code should try to add doctests for that code. See
TESTING.md
for more information.Target Branch
Depending on what the PR is for, it needs to target a different branch.
You can always change the branch after you create the PR if it's against the wrong branch.
dev
dev
stable
stable
branchbeta
beta
branch, but notstable
dev
Changelog
After creating your Pull Request, please add and push a commit that updates the changelog for the appropriate branch.
You can look at the existing changelog for examples of how to do this.