[shellcode, stager] ARM stager restore r0 in loop
r0 has return value instead of sockfd in second loop iteration
After first iteration r0 is filled with recv() return code, however we expect it to have sockfd for the next iteration, otherwise recv() will attempt to read from bad file descriptor (aka return value of previous recv() call)
It might require to modify stager inside modules directory.
There might be the same problem with linux/armle/bind_tcp
Thanks for the pull request!
Is this PR related to this issue? https://github.com/rapid7/metasploit-framework/issues/16107 :eyes:
@adfoster-r7 I just looked through this issue. It might be related to this (reading from bad file descriptor causes segfault).
We also need to reassemble shellcode from external directory and put it to modules/payload/stager/linux/armle/reverse_tcp.rb. As you can see in this PR I only modified source code of shellcode and applied a small change to ruby payload, however I think I made a mistake and we need to recalculate the location where payload jumps (inside the read loop). It is quite difficult to modify payload when we only have machine code. I think using metasm to assemble code right on payload generation will simplify the modification of the payload without the need to recompile it every time. (Some metasploit payloads use metasm though)
P.S. I am currently working on creating an alternative platform in Python (like Metasploit) and store all payloads in assembly code and then invoke assembler on them only when user needs it. - You can take a look at it here - https://github.com/EntySec/HatSploit/blob/main/hatsploit/payloads/single/linux/x64/shell_reverse_tcp.py
metasm isn't always viable/reliable, but if it is - that works for me :+1:
In the scenarios were metasm isn't viable, which is an issue we ran into with the osx aarch64 payloads that landed recentlyish - we added a quick pipe of objdump to ruby to grab out the hex representation and comments, example: https://github.com/rapid7/metasploit-framework/pull/17129/files#diff-23f0b96528cb168853ac403470d4c09a500213b5b39d82fff073a04eab42aac0R1-R2 - it might be possible to follow suit with this pattern so it's easier to change the payloads again in the future
@adfoster-r7 I have an idea. You can actually use keystone-engine instead of metasm. It seems more advanced and powerful and supports most of the CPU architectures. I used it to write shellcodes for macOS too and on M1 (arm64) it works well. I compiled few sources from external directory here and they seem to work just fine. In fact, my tool that I mentioned above where I store all payloads in assembly and then assemble them in keystone-engine has no issues with this approach.
@dledda-r7 Thank you for detailed explanation, I see where I made a mistake. I've just changed this instruction in payload.
Release Notes
This fixes the ARM stager to properly download the second stage by fixing the recv() loop