usiegl00 / tamatoa

If you have any questions, please open an issue.
The Unlicense
23 stars 6 forks source link

Unable to retrieve stdout from shellcode #9

Closed slyd0g closed 2 years ago

slyd0g commented 2 years ago

+------------------------+ | Describe Your Question | +------------------------+

Hello, I've been doing some testing with obtaining/redirecting stdout/stderr from various shellcode loaders. I've tested it within C, ObjC, and Swift. I'm unable to get stdout, but can get stderr. I've taken some screenshots to show this.

I'm able to redirect stdout/stderr when invoking the program normally, but when converted to shellcode and executed, it appears that stdout is lost. Do you know why this might occur? I've tried other file descriptors (https://stackoverflow.com/questions/29593556/directing-shellcode-output-to-a-file-c) and trying to redirect output with freopen in the shellcode loader itself, but no luck. Thank you so much for your time!

image image image

usiegl00 commented 2 years ago

The MacOS native loader dyld will handle flushing the output when you run an executable. Making a call to fflush(0) will flush the output manually. I can add one into the loader if you'd like?

slyd0g commented 2 years ago

I just looked up fflush and think that would be helpful for this case. Do you see any potential adverse affects to adding it?

usiegl00 commented 2 years ago

I have added a call to fflush(0) after the shellcode is run and munmaped. You should be able to redirect stdout now. : )

slyd0g commented 2 years ago

Thank you so much for the quick turnaround!! Just pulled your latest updates in and I'm still not able to get stdout though: image

usiegl00 commented 2 years ago

Yikes, I made a mistake with my test before I pushed. Let me take another look.

usiegl00 commented 2 years ago

Okay, I have a working solution. It relies on guessing the pointer __stdoutp.

Could you run the following c code and tell me the number that you get?

#include <stdio.h>
int main() {
  printf("__stdoutp: %llu\n", __stdoutp);
  printf("stdout: %llu\n", stdout);
  return 0;
}
slyd0g commented 2 years ago
slyd0g@Justins-MacBook-Pro~$ cat test.c
#include <stdio.h>
int main() {
  printf("__stdoutp: %llu\n", __stdoutp);
  printf("stdout: %llu\n", stdout);
  return 0;
}
slyd0g@Justins-MacBook-Pro~$ ./a.out
__stdoutp: 140735350170024
stdout: 140735350170024
usiegl00 commented 2 years ago

Well, I might have to load a second macho to get the pointer to stdout. What do you think?

slyd0g commented 2 years ago

Hm are there any other alternatives without loading the second macho?

Just trying to keep the fingerprint of the loader as small as possible. If not, I think that would be a good alternative!

usiegl00 commented 2 years ago

Ok, I have got the second macho load to work. The resulting shellcode size is increased by 3337 bytes. There is a make directive to disable the second macho load. (make nofflush) Let me know if you have any questions.

slyd0g commented 2 years ago

image Just tested and this works perfectly! I'll close this one out, awesome work :)