Open jcroy opened 5 years ago
So I noticed that I forgot to include a press("DOWN") action, which seems to help. But even prior to the code posted above we were getting problems.
Have you tried to increase the delays, to assure key presses aren't issued too fast?
So messing with delays helped (and fixed the issue). So I threw the modified script into a function assuming it would work exactly the same. But I had a add another left press for some reason, is there some sort a of change that occurs when putting a script under a function (I dont see why there should be)? The script below works, but I'm curious why the additional left key press is required.
layout('us'); //sets to us function startPS(){ press("GUI"); delay(500); type("powershell.exe") delay(500); press("CTRL SHIFT ENTER"); delay(500); press("LEFT") delay(500); press("LEFT") delay(500); press("SPACE") } startPS();
Hard to answer. It's a fact that delays have to be tweaked to match the target, which could be more or less responsive (the time it takes to open dialogs and get them ready for input could hardly be estimate, as it depends on a ton of factors). Additionally the P4wnP1 stack runs 8 JavaVMs in concurrent threads (go routines to be specific) and scheduling behavior of Go runtime is black magic. In simple words: short delays could never be 100 percent accurate, so HID Scripts should be tuned for worst case (having target host under heavy load during testing is a good starting point).
The answer to your last question is a bit technical, and again has to do with the concurrent VMs.
The JavaScript engine is backed by "Otto" (a Go native JS stack). This engine isn't built for running in Threads, as JavaScript itself isn't built for multi-threading. So to run concurrent JS Scripts, I manage a pool of those VMs in background. During development, it turned out that those VM can't be destroyed without memory leaks once their job is done (script finished execution). To compensate for this, I keep 8 VMs running and scheduled scripts are distributed to those VMs, until there's no free VM left. This worked quite well in terms of ressource usage (no memory leaks), but a VM which is used by a script can't be easily cleaned from leftovers of preceding scripts.
F.e. if you declare and set a global variable and this script is executed in, let's say VM 7, all successive scripts which are ran in VM7 could access this variable. But you can't access the same variable on all the other VMs. So the VMs are left in inconsistent state, each time a script was executed.
This gets even more problematic if a script is executed from a TriggerAction, which defines runtime variables depending on the Trigger used (f.e. TRIGGER
).
To account for this, all HIDScripts are already wrapped into a function, to keep variables in local scope (function gets overwritten each time a new Script is started).
This quick fix is a bit hacky and was deployed shortly before release (one of the reasons for alpha stage).
As JS supports function declarations within functions, this is more or less transparent to the enduser.
So the short answer: I doubt that wrapping Scripts into functions is causing your issues, because this is done anyways. A timing issue with delays is more likely.
The need to play with timing is natural to keystroke injections, especially when it comes to behavior driven endpoint protection.
General rule: delays should be aligned to worst case (full load on target host) to get scripts working reliably. For typing out string sequence the typingspeed
function supports this kind of tuning. Delays between calls to press
have to be added manually
hmm thanks for the detailed response. I made the delays longer (around 1000) and havent run into as many issues. Il update this when I get more consistent results and get the core script I'm throwing together finished so thats its not a issue due to my editing.
Few other questions that don't warrant a new issue being opened/sorta related to p4wnp1. How would you go around converting the string below into a proper type command. I've tried variations of escape characters which works but then the $dl is turned into a string which breaks it. Is there a simpler char that I am missing?
Invoke-Expression "& $dl'\CyLR\CyLR.exe' -od $dl'\Output'"
Also has someone created a conversion tool for power shell scripts to get them into proper hid language?
Not sure if I got you right, as this is about double escaping (for P4wnP1 JS and PowerShell string parsing/variable sibstitution).
Typing out iex
followed by a (hard to escape) string, which again holds a script isn't needed for keystroke injection, because it is much easier to type command directly into the interpreter (and less suspicious, especially when iex comes into play).
Please understand, that I don't want to give further advice on exploitation/obfuscation techniques fo PS... there are plenty of resources out there and well known frameworks which built properly encoded PS payloads which could serve as example (of course not FUD).
But as a generic tip: Encoding is the magic word if you want to avoid dealing with complex escaping/character substitution schemes of different parsers/interpreters. In PS case base64 is your friend (adds to character count, but could be reduced again with compression).
For the P4wnP1 part: To send the characters to the input which you would expect from a legacy keyboard, you have to use default JS escaping. F.e. to send a tabulator in between a string, while using type
instead of press
, escaping would look sth loke this
type('row1\trow2\nline2');
The tip on encoding was helpful. Thanks for that, I was able to get everything encoded and interpreted by power shell properly. As for the iex thing, I was not to concerned about being stealthy as I'm working on throwing together a automated incident response tool (as opposed to a red team tool) using P4wnP1_aloa and cylr (which in retrospect should have only taken me under a week or less than how long it took me).
Seem to be getting inconsistent results at best. Two days ago we got closer to 50% chances of success but now it does not event bypass uac (building an IR tool). The code below was copied based off the helper.js script built in.
//tested each line independently and each line works but when you combine them together it //fails layout('us'); //sets to us press("GUI"); delay(200); type("%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe") delay(500); press("CTRL SHIFT ENTER"); delay(500); press("LEFT") delay(500); press("SPACE")