Unraveling a REMOTE ACCESS TROJAN (VBScript Deobfuscation)

Futurescience
40 followers
4 Video Views·Nov 9, 2022
Malware comes in a lot of different shapes and sizes.
As you might know, some of my favorite is de-obfuscating layers of nested
stages of scripting languages, native, inherent, and always available and
always installed default languages that the target operating system, like
Microsoft Windows, might willingly execute and run stuff like Jscript, stuff
like PowerShell or Batch in the Windows command line, even Visual Basic Script
or MSHTA in the HTML application language.
There's so much cool, fun stuff.
And it's been a little while since we got a chance to de-obfuscate some
strange shenanigans, malicious code.
So that's what we're going to do in this video.
We're going to start to play with one of my favorite languages to
tinker with, Visual Basic Script.
Let's get to it.
Before we dive into the video, here's a quick note from today's sponsor.
Developers are constantly changing the digital landscape, but building
secure software isn't always easy, especially in growing applications
worked on across massive teams.
Companies end up with mountains of code and they have to make a choice,
stay competitive or stay secure.
But with Snyk, you don't have to choose.
Snyk helps bake security into the software development life cycle.
Snyk helps you scale and streamline by automatically scanning your code,
dependencies, containers, and configuration files, finding and fixing
vulnerabilities in real time.
And it is super easy to use.
You can sign up for free with my link below, import your repositories, and
there, Snyk just finds your vulnerabilities.
You can fix all these issues with just a single click.
Snyk automatically opens a fixing pull request so you can just merge them
into your repository and move on.
And it fits seamlessly into all of your existing tools, IDEs, the command
line, CICD pipelines, cloud infrastructure, and more.
Millions of developers love Snyk.
And you can see for yourself, get started for free with my link below and
develop fast and stay secure with Snyk.
Okay.
So I am inside of my Remnux virtual machine, Remnux being the reverse
engineering malware and analysis Linux distribution, and I have hit control
alt T on my keyboard to open up a command line terminal.
I have a directory called VBScript.
And in this directory, I have a file called server-tilde1.vbs.
Now this is a file that was found added as a persistence mechanism
on the target victim computer.
It was added into their startup folder.
So one of the applications and one of the programs that would just kick off as the
machine booted up or logged in via user, something that would just automatically
go ahead and run this code.
Now, again, being a visual basic script, it is something that Windows will just
naturally execute with its own interpreter.
It has some interesting code here.
However, I'm noticing a pattern and you probably are just as well.
There is a significant amount of commented blocks here that are
trying to maybe impersonate PHP.
I don't really know.
It just seemingly has these in square braces here and then random message
boxes with numbers that just seem to be getting in the way of the code that
we might actually want to read here.
So the first order of business is trying to remove these.
I'm going to see if I can finagle some regular expressions to be
able to cut up these blocks.
But, you know, I failed at this before and the very first malware
analysis video that I put together.
So let me have some time to figure this out.
I'm going to control F on my keyboard so I can go ahead and search for specific
things and that's the control find functionality and I'm going to use the
opening square braces and closing square braces with PHP present and then a dot
slash, excuse me, a dot star to glob everything following.
I believe I can use backslash N to get a new line, but I'm going to need to try
and multiply that out across multiple things that might be across multiple lines.
And it looks like that worked for me, but I want to have a terminator on another
backslash or excuse me, a single quote here.
I might've been using the wrong wording that entire time.
I'll use the backslashes to escape the ending of the PHP portion.
Now this is going to be a greedy regular expression and it's going to capture
literally everything following, you know, the first occurrence here.
So this probably won't work all that well for me.
I want to try and make this lazy.
So I believe I can add a question mark following the plus sign plus being one or
more multiplying the previous group that it detected and the asterisk here, that
star is already going to be collecting at least zero or more of the previous thing.
So I believe I have selected all of those blocks now.
And if I hit control alt, uh, actually I think it's control H that will allow me
to find and replace.
So I have this regular expressions here already created, but I am going to
replace this with control alt enter.
So I've replaced it with nothing.
And now just like that, all of those have been removed.
Okay.
I have a couple extra blank lines now though.
So I do not like that.
I'm going to look with another regular expression to find the start of a line
that has a new line character just following it and nothing else.
And if I control alt enter to replace all of those.
Now I have a little bit, at least easier to read syntax.
Okay.
With that, we can start to dive into this code here.
We have the usual prelude for some, uh, visual basic script code on error resume
next, so we just ignore any issues that come through here and then we go ahead
and use the set keyword to set a, a, a, a, a, a, a, a, a, uh, and that's going
to end up being the return value of this get object function call.
Now it does some weird thing here by concatenating and in visual basic
script, the ampersand is a concatenate operator with CHRW being a function
call to get, you know, the character representation of a number.
And what that means is it's going to do an ASCII table lookup to find, okay,
what actual printable character could be represented in the ASCII table with
numbers like zero to two 55, or Hey, I might have those bounds wrong,
inclusive, exclusive, whatever.
But this is something that sure we could try to figure out by going through here
one by one, exploring each and every single one of these, but I like to try
and let the language deobfuscate itself.
Just naturally unravel.
And that's a technique I'm sure you've seen me use through a ton of these
videos, but this is visual basic script, which will not run on my Linux operating
system that I'm in right now.
Remnux as a distribution and as Linux, this isn't going to know how to execute
interpret visual basic script.
So I need to hop over to windows.
So I am going to open up my flare virtual machine as another, Hey, uh,
malware sandbox that I might be able to work with.
I believe this is FireEyes labs, you know, I don't know, analysis
and reverse engineering.
I totally getting the acronym wrong here, but I should go ahead and be able to
download a tool that I want to use called VBS edit.
This is just an interpreter.
It's just another editor for visual basic script.
And that's one that I tend to really like because it gives me a little bit of a
playground to work with digital basic script.
If you haven't used this before, something that I recommend, I think I might have
showcased in other videos, but I'll go ahead and get this installed and
we'll get right back to it.
Okay.
Now VBS edit is present here on my desktop, so I can open that up.
It is going to be asking for a license key or just say some actual registered
saying that you bought this software.
However, you can just kind of hit evaluate and let it cruise through.
Now I should be able to just go ahead and paste this line in.
And that text is a little small.
Uh, let me make this all bigger here for you.
Okay.
Now that should be a little bit easier to read.
I am going to go ahead and save this as a file that I can work with.
Uh, this is just all temporary.
So we'll throw it in my desktop and we'll call it like a playground
dot VBS or whatever now get object is going to actually basically return
object, but I kind of just want to know what the result of this whole string
is after it's concatenated and manipulated and done, whatever it does here.
So I'm going to go ahead and remove those silly parentheses
at the beginning and end of it.
And I'm going to see if I can use something like W script dot echo to
be able to just display this out.
W script dot echo is basically the console dot log.
Uh, it allows me to really just output this to the screen.
Uh, we can just print it out into standard output and you could use
something like message box to just, I don't know, display that out.
And I might have that syntax wrong.
I kind of need to remind myself here.
But W script dot echo allows you to run this with something like C script.
So if I open up the command prompt using commander here as part of flare, if I
zoom in, if I go ahead and get to my desktop, I should be able to run
C script on my playground.
Now, fingers crossed.
If I haven't screwed this up already.
Ooh, I've got this thing.
I've got the output here following, you know, the banner from Microsoft.
A E Z R T colon backslash backslash root C V B N C M V N N.
What is that?
How is that useful for me at all?
This looks like, you know, a potential like sim namespace or
something for WMI, I believe.
I might have that vernacular wrong, but that is something within windows.
So let's just swipe that and go put that into our script.
You're replacing what that originally would have been.
Uh, we'll put that back in quotes and we'll do this just as well for, you
know, our next variable B, B, B, B, B, B, B, B, B, I'm, I'm still a little
bit puzzled as to how this is coming together and actually returning a value
that this might be able to work with as an object, does that work?
Let me try to just run that on its own.
I have, did I miss some operations there?
I'm expecting this to be root sim management, which looks like
it's partially there, but not fully.
Are they doing some shenanigans?
Let me try and play with this.
I'm going to comment this line out with that single quote and
let me grab that syntax again.
If I paste this in, am I setting this AA object to be sim management?
How about I try and run this?
No, it whines.
What is the invalid syntax here?
Is that just me not doing this correctly?
Let's put this in a regular script on error.
Resume next set value.
Get objects should be just fine.
Maybe that's only something that W script can do.
Oh no.
That wait, wait.
The onerror resume next is probably not letting me do that.
I think that's going to error.
I think that is perfect purposefully failing.
So that won't happen.
Maybe let's go back to the code.
That onerror resume next is just going to let this thing fail.
Cause it's not going to get an actual object out of this.
This is garbage nonsense.
What does BBBBB going to do?
Let's go ahead and grab this to go ahead and deobfuscate it.
We'll grab that other portion here and see what they actually try to run.
What this exec query might come back with.
Pasting that in.
Let's use our W script dot echo one more time.
Go back to commander.
Try and run that.
No.
Wrong number of arguments to pass to CHRW.
That's fine though.
It only takes one.
Is there a comma in here anywhere?
Let me control F for a comma.
Oh, there is one, but that's in mid, which is another function.
None of these go to CHRW.
Maybe that needs to be wrapped in parentheses.
It just weird stuff in VB scripts.
There we go.
There's something.
This looks like it's trying to refer to process.
Looks like it's trying to pull win 32 process, but again, that's garbage.
That would fail.
Okay, let's go back.
I guess I can grab this code and it gets 48 as another argument to it.
Is that even a thing that you can do to exec query?
Or am I doing this all wrong?
Let me kind of get a quick reset.
Maybe just for a sanity check, I kind of want to try and run this with message box
and maybe in like W script.
Let me try and W script playground.
No, that still spits out the actual message here.
And even if I were to use a message box, it does the exact same thing.
So that's never going to return a result for me.
I have a hunch these would error.
Do they even use these variables?
No, this is the only location that even those variables are used.
However, this tries to loop through all the processes.
It defines a new variable with dim to denote ham, creating something new here.
And then we do a four each and all the results that would come through when 32
process class, and if that process name is equal to something here, then more
things happen, let's try and add some white space and see how we might be
able to make sense of this.
If statements in visual basic script will end via an end, if four loops will
continue to iterate through a next, and then we have another end, if that
matches the one above I'll get these tabs, correct here, and then we do some
other weird stuff, but let's see where this goes.
We're looping through every process that we retrieved from that win 32
SIM class, or, you know, WMI thing.
Uh, and then we check if the name is equal to this thing and then it will do
something, so let's go, go ahead and deobfuscate that we'll slap that right
back into visual basic script, the little editor here with W script echo.
Let's try and run that.
I'll use C script again.
Uh, and it does not like the fact that I have not wrapped that in parentheses.
So let me slap that again there.
And it's checking if the value is equal to W script.exe.
Interesting.
I was using C script to test that.
So it's not just detecting it based off of, it's literally the string
manipulation of checking.
Is this going to be W script.exe?
If it is, then we define D D D D D D D with all of this seemingly hex values,
just way, way far out to the right here.
And we go ahead and define that and then use E E E E presumably with a function
F F F F F F F F, which is defined down here.
Okay.
So that is code that we'll get to, but let me kind of keep cruising
and see where we go with this.
G G G G G G G is going to end up reading another object that we
could try and de-obfuscate here.
Slap that in and you know the drill here.
Super simple, super easy.
Slap it all together.
Run this.
That looks a little bit closer.
Win management Q colon root.
Uh, still not an actual thing though.
It's that little error.
That's so odd to me.
Well, okay.
That's what de-obfuscates to.
So let's check out this next variable.
H H H H H.
Another exec query where they're trying to again, do something
odd with a 48 argument there.
Let's use that.
Here we go.
Select from win 32 process.
Okay.
So that's probably the query that it's still trying to end up rolling.
Odd that it does that inside of another loop here.
I'm not getting this wrong.
Am I?
This is like plaguing me with anxiety and self-doubt.
We loop through each of those.
And for every process, yet again, we check this.
Okay.
If that matches a name, de-obfuscate that nice and easy.
Run that.
W script dot exe.
Yet again, what is happening?
If it is W script dot exe, then go ahead and execute what you
determined from F F F F F of D D D D D D.
Presumably this is going to be a payload.
Like this must be hex bytes for something.
I don't know what mid is going to end up.
I believe it's just getting some portion here.
We could just run that.
I don't know why that's just slapped in as an extra random command to run,
but let's see what that does.
Uh, does not like that.
Oh, parentheses are getting in the way.
What are you worried about, man?
Just use call the function.
How about that?
It does nothing.
Mid would only retrieve a length, right?
It, we just saw those arguments kind of given to us as we
hovered over it and VBS said it.
So that does not, it literally returns zero characters from this
and gives me an empty string.
Useless.
This one starts at nine.
However, this is 10 characters long.
So it gives me the letter E.
If E is equal to mid of this thing, character five as a starting
length going to eight, that does nothing.
This is all just a fraud.
Oh, hang on.
I grabbed the wrong thing.
Let me grab this.
Run that.
Please come back.
Run.
Act bogs.
Couldn't have said it better myself, except I did because I'm
the only one that said it.
And this is again, that's useless.
You, you don't even do anything with these values.
It's just garbage.
Okay.
F F F F F is the only thing that we ended up needing to work.
This is going to end up defining a return value because in visual basic script,
the name of the function after you set that to a variable is what that function
returns, this is clearly going to end up just cutting up and running and like
building out blocks or another layer of visual basic script to spit out an execute.
So if some way, somehow this were to succeed, if my interpretation of those
original obfuscated strings was wrong, F F F F F would deobfuscate and end up
executing running the next layer of D D D D D D D to follow.
Does that make sense?
Let me just slap this in.
Now we've got our function here working for us and let's go grab our good friend.
D D D D D D D.
What you got for me?
Paste this in here.
Oh, VBS said it just crash.
It did.
Okay.
I didn't, I didn't know we were going to give up so easy.
Let's go to the desktop.
Open up my playground again.
Do you not like a string that long?
You don't shoot.
I don't even have to use VBS at it.
You know what?
Like let's just use notepad plus plus we have notepad plus plus now D D D D D D
D is all defined and we don't need that temporary file.
We'll use F F F F F on D D D D D.
And let's go ahead and W script dot echo F F F F F F F of D D D D D D.
This video is going to suck.
You guys must hate listening to me.
I'm sorry.
All right.
W script dot exe on our playground dot VBS and theory.
Oh God.
I ran that in W script.
I should have used C script.
Playground on VBS.
That looks like something.
It really does.
Let me redirect that out to next dot VBS.
I guess I named the previous file next.
So that probably doesn't work all that well, but this has stuff to it.
Uh, despite the output of the previous thing, this looks like
something we can work with.
Let me bring this back into sublime tech.
So we have a little bit better display here.
We'll call that next dot VBS and it's this.
So this ends up yet again, executing it.
Oh, there's two functions here.
All right.
So let's clean this up.
We have another do loop and execute global is what's going to end up running,
but this is the thing that runs, which calls that based off of this.
Yeah.
And it cuts it up, does whatever de-obfuscation things that it wants to.
And then ultimately we'll end up running it while it's not a B-Lin.
So basically execute global is going to be the next malicious nefarious thing.
Um, so maybe rather than running execute global, we can go ahead and just
W script dot echo what that ends up being spat out to be so we can try and run this.
Granted there are non-printable characters up here and that worries me.
I feel like I've broken something.
There's no real way to be able to retrieve or get that easily.
Um, working in the text copies that I'm using here.
So let's, do you think it'll work?
Like would it work?
I don't know.
Let's do it in the flare VM so we can use execute global, but rather
than actually using it, let's use our W script echo.
So it will execute this next stage of the payload, but it'll unravel it for us.
Hopefully, theoretically, let's try to W script our next VBS.
Oh, it didn't like it.
How are we going to pull that data out?
We can't get in the way of execute global.
Can you redefine functions in visual basic script?
Like letting the first payload execute is no go.
That's no good, right?
We're just detonating this malware on ourself.
Let's make another playground.
Or yeah, let's just save this as an experiment dot VBS, please.
Hello?
Yeah, whatever.
I don't care.
Um, let's do a function.
Let's create our own function.
I believe you can end function just like that.
We'll call it execute global, but all we'll do is W script dot echo.
So I could do a little, please subscribe.
Right?
Now when I execute global W script dot echo, Oh, nested things.
Does that work?
You should never see this.
It's inside of a double quotes already.
So fingers crossed.
Let's try to see script this time.
Actually run the right thing on our experiment.
VBS.
Did you not save it?
You jerk.
I hate you.
Notepad plus plus.
That's why I never use you.
Can I just save it as all?
Yeah.
All types.
Let's go ahead and delete our experiment dot VB.
You're useless son of a S because it was missing the S.
C script experiment dot VBS, please.
Wrong number of arguments of invalid property execute global.
Oh, cause it knows that it takes no arguments.
Anything, but that does prove to us that we can overwrite that variable.
So now or overwrite the function, we could knowing what the next stage does
probably get around it, you think?
Because the second stage payload will end up running execute
global to actually detonate it.
But in the first stage where we're experimenting with this, we
could probably nerf that out.
As an experiment, let's just run.
Our mouth, our execute global with, with please subscribe rather
than actually showing us the payload.
Um, I'm going to disconnect this from internet in case I'm in case I'm horribly
wrong.
Okay.
So now we want to be running our playground.
C script playground.
Wait a second.
This is a first thing.
It just, it just echoed it.
It didn't, it didn't go ahead and execute it.
We need to still run execute.
Correct.
Cause it didn't even run.
Please subscribe because all we did was echo that out.
We didn't execute it.
We need to execute this.
Now to note that works for us because execute and execute
global are different functions.
But in the original sample, like if we go look at our server one, it just
calls execute on that return value.
So let's try that.
Cross our fingers.
Oh, what are you whining about?
Is it because it's just that no 19.
No, it is.
It is.
Let me just get, Hey, so I think we need dim stage two on the line above that.
How about that?
There we go.
So we W script that out.
Now we want to execute that.
Correct.
And hopefully my execute global previous nerve function will get in the way of it.
And all we'll see is please subscribe.
That's the hope.
Yeah.
Oh, that's so cool.
Oh, I know.
I haven't done that before.
I think that's kind of slick.
Okay.
So what this means is that we can have it naturally unravel with those weird
characters to just display the variable on the parameter that is passed in.
So rather than execute global to eval and run those next stage, now
we got this little workaround.
Do it.
Yeah.
Oh, that's so slick.
Okay.
Let me redirect that to third dot VBS.
Um, and let's go ahead and open up our third dot VBS.
Oh, you it's frigging Houdini rat crap.
We've seen this before.
I mean, I should have known it's like the WSH rat.
Oh, what a bummer.
What a, what a lame way to finally get to the end here where it's just
a, another sample that we've seen before.
Sure.
Cool.
We got new indicators of compromise, another domain, another port.
I should have expected this considering it is visual basic scripts.
This is a rat.
This is WSH rat.
We see it all the time.
You see it all the time.
We've, we've done this before in previous videos where we can dive into the code
as to what this is all doing and how it works, but it's just, it's just that.
The question is, would this even execute because of those original errors that we
were seeing at the start of this, trying to read when management's roots and B2 or
any, any of the other W WMIC and WMI classes and sin instances, like, I don't
think it would end up, I don't know if it would end up executing, maybe it was
tampered with, maybe it's multi, maybe it's manipulated in some cases, but this
is the only persistence that we, what we see on the machine, uh, ultimately.
Remote access Trojan is a rat WSH rat recoder.
Houdini is still doing his thing, but kind of a lame way to wrap up and end the
video, because this is something that we've seen before and it's lame, cheesy,
more visual basic script code should have known should have expected, but Hey, maybe
that nice little trick of clobbering the execute global function or any other
function that you might be able to need to have in some nested way that can still
be worthwhile.
And now we've at least diagnosed that this is what we're up against.
Um, doesn't tell us any of their hooks and claws, other than what might be in
temp.
So maybe on that host, we'd go ahead and clean out and scrub that temp, but
ultimately we're good.
And I think that's the end of the video.
Thanks so much for watching everybody.
Again, I always feel bad doing some of these when it's just a re-roll of
something that we've already seen before, but maybe there's still a little bit of
cool new learnings or you just have fun seeing me bang my head against the wall
against semantics and syntax and visual basic script, um, recommend folks.
Hey, bump around in REMnux bump around and flare.
You should kind of be tinkering in those.
And if you're, you know, experimenting and exploring some things, you're probably
more elite and more advanced than me cutting things together in like IDA and
actually disassembling actual binaries.
But I figured these sorts of videos, when it is at least semi human readable
language, it's something that other people.
For a larger audience can understand and interpret and can sort of make sense of
rather than just raw Intel assembly op codes, right?
Whatever.
I hope you enjoyed this video.
Thanks so much for watching.
If you did, please do all those YouTube algorithm things.
Um, I've got to decide if I even upload this, but maybe we'll see how we do.
Please do those YouTube algorithm things, like, comment, subscribe, blah, blah, blah.
End of video.
But goodbye, everyone.
See you later.
