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

Reverse TCP x64 RC4 via max3raza's rc4_x64 asm #9565

Merged

Conversation

sempervictus
Copy link
Contributor

To round out the work done by mihi for x86 stages back in the day,
this PR provides x64 Windows stage encryption in RC4 via assembly
written/modified by max3raza during adjacent work on DNS tunneled
transport.

Stage encryption differs from encoding in that there is no decoder
stub or key materiel carried with the stage which can be used by
defensive systems to decode and identify the contents. Persistence
payloads, oob-delivered stage0, and other contexts benefit heavily
from this as their subsequent stage is difficult to detect/identify,
and the chance of accidental execution of the wrong payload/stage
is drastically reduced if separate keys are in play for individual
targets - acquiring the wrong stage will result in decryption
failure and prevent further execution.

For historical context, all of the RC4 stagers implement in-place
decryption via stage0 for the contents of stage1 using the provided
passphrase converted to a key and embedded in stage0 as part of the
payload.

Testing:
In-house testing with Max - we got sessions, loaded extensions.

Notes:
All credit for the work goes to Max3raza - big ups for getting
this knocked out.

Next steps:

  1. Bind payloads
  2. Repeat the dns piece in x64, get rev_http payloads working in x86 and x64 with rc4 asm blocks (they're not exactly like the rev_tcp blocks, so not a direct port).
  3. Implement same for mettle payloads (how many architectures is that across how many platforms?) - L4 rev/bind, l7
  4. Stop getting caught for our stages

ping @max3raza - the man of the hour, deserving of a beer or two if anyone's in his neck of the woods. The defconrussia guys (Max and Alex) are expanding our core functionality pretty significantly, hat's off to them both.
ping @busterb, @acammack-r7, @OJ, and @schierlm for review

To round out the work done by mihi for x86 stages back in the day,
this PR provides x64 Windows stage encryption in RC4 via assembly
written/modified by max3raza during adjacent work on DNS tunneled
transport.

Stage encryption differs from encoding in that there is no decoder
stub or key materiel carried with the stage which can be used by
defensive systems to decode and identify the contents. Persistence
payloads, oob-delivered stage0, and other contexts benefit heavily
from this as their subsequent stage is difficult to detect/identify,
and the chance of accidental execution of the wrong payload/stage
is drastically reduced if separate keys are in play for individual
targets - acquiring the wrong stage will result in decryption
failure and prevent further execution.

For historical context, all of the RC4 stagers implement in-place
decryption via stage0 for the contents of stage1 using the provided
passphrase converted to a key and embedded in stage0 as part of the
payload.

Testing:
  In-house testing with Max - we got sessions, loaded extensions.

Notes:
  All credit for the work goes to Max3raza - big ups for getting
this knocked out.
mov [r8+rax], dl
add dl, [r8+rbx] ; DL = S[AL]+S[BL]
mov dl, [r8+rdx] ; DL = S[DL]
xor [r9], dl ; [EBP] ^= DL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That comment should be changed to refer to R9 instead of EBP. By the way, good idea to avoid clobbering EBP ....

pop rsi ; rsi = RC4 key
#{asm_decrypt_rc4}
pop rdi ; restrore socket handle
pop rbp ; restore rbp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... but then you can remove this pop RBP and the associated push RBP in line 170 as well .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from that, I don't see any obvious mistakes. Did not test it though (and the payload creation changed a lot since I last touched it :D )

@sempervictus
Copy link
Contributor Author

@schierlm: thanks for looking into it. Not much has changed under the skin, i just took your original shellcode and converted it to metasm a couple of years back; we repeated that pattern here. This is a bunch easier since we're not injecting values at offsets anymore, but actually assembling the interpolated strings of asm on the fly.

@sempervictus
Copy link
Contributor Author

Been using this a few days now, seems to work. Still seeing packet forwarding issues, but that's something in the windows bins (not just mine, upstream too) as it doesn't happen w mettle...

@busterb: we should add mettle windows stagers for this too :-)

@bwatters-r7
Copy link
Contributor

bwatters-r7 commented Feb 20, 2018

image

I'm seeing failures across the board on x64 Windows for file creation (upload) using post/test/meterpreter. The error is present in reverse_tcp and reverse_tcp_rc4. It is not there on upstream/master. On this branch, the payload works great, but when running the tests, it hits this every time:

> use post/test/meterpreter
> set verbose true
verbose => true
> set addentropy true
addentropy => true
> set session 1
session => 1
> run
[*] Setup: changing working directory to C:\Windows\TEMP
[*] Running against session 1
[*] Session type is meterpreter and platform is windows
[*] Starting process tests
[*] Pid: 1620
[+] should return its own process id
[*] PID info: {"pid"=>1620, "ppid"=>2820, "name"=>"windows-x64-meterpreter-reverse_tcp_rc4-192x168x134x119-30001.exe", "path"=>"C:\\payload_test\\windows-x64-meterpreter-reverse_tcp_rc4-192x168x134x119-30001.exe", "session"=>0, "user"=>"WIN7X64SP1\\vagrant", "arch"=>"x64"}
[+] should return a list of processes
[*] Starting system config tests
[+] should return a user id
[+] should return a sysinfo Hash
[*] Starting networking tests
[+] should return network interfaces
[+] should have an interface that matches session_host
[+] should return network routes
[*] Starting filesystem tests
[+] should return the proper directory separator
[*] CWD: C:\Windows\TEMP
[+] should return the current working directory
[+] should list files in the current directory
[*] Current directory: "C:\\Windows\\TEMP"
[*] Stat of current directory: #<#<Class:0x0000000008f60970>:0x0000000008972680 @stathash={"st_dev"=>0, "st_ino"=>0, "st_mode"=>16895, "st_nlink"=>0, "st_uid"=>0, "st_gid"=>0, "pad1"=>0, "st_rdev"=>0, "st_size"=>8192, "st_atime"=>1519154970, "st_mtime"=>1519154970, "st_ctime"=>1247541614}>
[+] should stat a directory
[*] Directory Name: meterpreter-test-dir-ygklpevn
[*] Directory created successfully
[*] Directory removed successfully
[+] should create and remove a dir
[*] Directory Name: meterpreter-test-dir-ygklpevn
[*] Directory created successfully
[*] Old CWD: C:\Windows\TEMP
[*] New CWD: C:\Windows\TEMP\meterpreter-test-dir-ygklpevn
[*] Back to old CWD: C:\Windows\TEMP
[*] Directory removed successfully
[+] should change directories
[*] File Name: meterpreter-test-ygklpevn
[*] Wrote to meterpreter-test-ygklpevn, checking contents
[*] Wrote test
[+] should create and remove files
[*] Remote File Name: meterpreter-test-file-ygklpevn.txt
[*] uploading
[-] FAILED: should upload a file
[-] Exception: NoMethodError : undefined method `call' for nil:NilClass
[*] Source File Name: meterpreter-test-ygklpevn
[*] Destination File Name: meterpreter-test-ygklpevn-moved
[+] should move files
[*] Source File Name: meterpreter-test-ygklpevn
[*] Destination File Name: meterpreter-test-ygklpevn-copied
[+] should copy files
[*] Remote File Name: meterpreter-test-file-ygklpevn.txt
[*] uploading
[-] FAILED: should do md5 and sha1 of files
[-] Exception: NoMethodError : undefined method `call' for nil:NilClass
[*] Testing complete in 4.311788908
[*] Passed: 18; Failed: 0
[*] Cleanup: changing working directory back to C:\Windows\system32
[*] Post module execution completed

@bwatters-r7
Copy link
Contributor

I had a few minutes to run the test, but I'm on something else currently. If no one runs this down before I get a chance, I'll try and figure out what's happening when I get some spare cycles.

@bcook-r7
Copy link
Contributor

@bwatters-r7 note that upload was temporarily broken (like 24 hours), so you may need to rebase or merge master to get the fix. Probably unrelated to this PR, just bad timing!

@bwatters-r7
Copy link
Contributor

@bcook-r7 Thanks; that makes sense. I did a quick scan and was at a loss to explain why this code broke that functionality.

@sempervictus
Copy link
Contributor Author

Yeah we are all done executing any of this by the time you're in stdapi... I call gremlins.

@bwatters-r7
Copy link
Contributor

FYI, when merged with master (4b8a8fa), everything passes:
image

@bwatters-r7 bwatters-r7 self-assigned this Feb 26, 2018
@bwatters-r7 bwatters-r7 merged commit 80779f7 into rapid7:master Mar 2, 2018
@bwatters-r7
Copy link
Contributor

bwatters-r7 commented Mar 2, 2018

Release Notes

RC4 encryption support has been added for windows/x64/meterpreter/reverse_tcp payloads.

bwatters-r7 added a commit that referenced this pull request Mar 2, 2018
bwatters-r7 added a commit to bwatters-r7/metasploit-framework that referenced this pull request Mar 2, 2018
bwatters-r7 added a commit that referenced this pull request Mar 2, 2018
jmartin-tech pushed a commit that referenced this pull request Mar 2, 2018
jmartin-tech pushed a commit that referenced this pull request Mar 2, 2018
@tdoan-r7 tdoan-r7 added the rn-enhancement release notes enhancement label Mar 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature payload rn-enhancement release notes enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants