 Ladies and gentlemen, welcome back to another John Hammond YouTube video. In this video, we're going to take a look at a weird file. This is something that we had stumbled across. It is kind of peculiar and I think it's kind of a fun story, so we'll dive in together. So we'll hop over to my terminal here where all the good stuff is happening. And I've created this directory VBE, and in this directory I have a file, something.vbe. So running our regular usual file reconnaissance on this thing, we'll try to figure out what the heck it is. We'll run the file command on this file. And the output of that is just simply data, which doesn't exactly help me all that much. Usually the go-to is like, alright, well let's just kind of run strings on that easy peasy lemon squeezy, see if there's anything interesting in that. No, absolutely not. It is just a boatload of garbage and nonsense. So I'm like, WTF. What is this thing? Obviously, of course, the next best thing is to go ask our good friend and uncle Google here. So we'll fire that up in a web browser and I'll look for a VBE extension just to see what the crap this thing is. FileInfo.com as the first result gives me some good, good knowledge here. This says a VBE file extension is a script written in visual basic script. A programming language that is a reduced version of visual basic stores the source code in an encoded format so that it's not recognizable, run natively in Windows by the Windows script host, wscript.exe or cscript.exe. Okay, a VBE file can contain a virus. So do not open a VBE file if it is an unknown email attachment. You can decode a VBE file to verify the legitimacy of its source code by dragging and dropping file contents onto the decode VBS script. What? There is a decode VBS script. You can also drag and drop VBS files onto the encode VBS script to encode. Is there a thing? What? What decode, oh, oh, oh, encode and decode VBS scripts and these are just straight up things. Oh, Microsoft has them in like their gallery. This page says that our goal is to help you understand what a file with a VBE suffix is and how to open it. VBE script encoded script file type. Ah, okay. So that explains why we couldn't really read anything out of this good noise because it is visual basic script as is normally in plain text and human readable is as it is a scripting language, but it is encoded to that. So we could try and decode it. I am however running on Windows right now so I don't think I could particularly run a VBS script to decode it. I wonder if there are any other file things that might do it. Any other utilities or tools that can do it. But it is apparently a VBE script encoded a script file. So it's probably already weird and wonky if it is a VBE script VBE decode. Is that a thing? I am now using dark theme. Okay, thanks Firefox, Google. Oh, there's a Python script for it. From Didier Stevens. I might be mispronouncing your name. I'm sorry, my friend. Also 2016. Okay. Let's do it. Let's try it. Oh, there's a reference here. Maybe I can read that to kind of understand a little bit more of what this thing is. Thanks. Why do you keep doing that? Take me. Microsoft is the one that put me in dark mode. They were like, no, no, no, no, you should save your eyeballs, dude. So let's save this thing. I'll put it in this current directory. I'll just W get that down here. Okay. And now I have a decode VBE.python file. This is 2016. Is this Python 2 or Python 3? Oh, it's just doing weird mappings seemingly. Then replace this stuff. Okay. I guess we'll just do it. It doesn't look like there's anything horrendous and malicious there. So let's Python 3 decode VBE.py. That is doing nothing. Straight nothing. Okay. Is it really going to make me use Python 2? Does it like read from centered input or something? Oh, yeah. I guess I should have read that error message. I'm a dumb dumb. Python 3, tackage. Can I just give it a file? Yeah. Okay. Tackage will show this help message. You can just pass it a file. All right. Let's do a Python 3 decode VBE on or something dot VBE. And that spits up and dies. Cool. That's probably Python 3 things. All right. Search cannot use a string pattern on a bytes like object. Yeah, that's totally a Python 3 nuisance. Will it work in Python 2? Pretty please. Python 2 decode VBE something. What? It's just an empty space? There's no way. There's no way. How big is this file? No way. Look at that scroll bar. There is no way this just translates to like an empty white space. I don't buy that. What is this script doing? What is this decode VBE doing? Manual. Yep. Encoded VBE script. That's what we want. Provided file can also be a password protected zip file with password infected. It does it. Oh, it checks for Python 3? What? Whatever. I just wasn't getting it to work, I guess. Fixed pipe. File to string hash. Standard out write chunk data. Oh, nice. Okay. It just sort of chunkifies it. So it doesn't have to do it all at once. And this mapping thing with decode, I guess, figures out some of the bytes. What is the thing that like actually does it? Like if we go to the main function, right, which is ran by main when we run the script, checks the manual, it checks if we actually are looking for help, or if we supply arguments, we will decode VBE, either based off of standard input or the file we specify. So decode VBE is the function that we want to check out here. Fixes the pipe, checks for Win32, does some peculiar things. I'm on Linux right now. Otherwise, it does an omatch, or creates this variable omatch to search with regular expressions for some thing. And then gets the content. And then if it matches, or if it doesn't match, it tells me hey, it can't find an encoded script. Otherwise, it decodes the groups. Oh, it only indexes the first match. So it's only going to get like one thing no matter what. What is in the script? Yeah, it's a... Okay, so that first thing that it finds is what's straight nothing, and it looks like it's just using that marker for a hashtag at sign tilde caret, ha! Literally says ha with the equal sign little prefix there. So that's got to be something. But it only does it for the first one. We should totally patch that and fix that, so it does it for all of them. Because I want to see what all those other things are. This script is just weird in that it has some oddities. Let's do a regex.findall. So that way we can use the same arguments for the regular expression pattern to look for in the contents of the file, and then we'll have a match, which we did earlier. But rather than just displaying one, let's comment that out and let's do like a for match in omatch, because that'll return a list. We'll give us a list of all that. And so we'll send it out, write chunk decode omatch groups 0, but rather than just getting the first index, let's try and do that inside of the loop running it on all of the matches, right? So if I save that and go back to our terminal, does that look any better for us? Now let's try that Python 2 decode VBE on something.VBE. Ooh, that got something else. Oh, and it got a lot else. This also still looks like jank weird. Oh, but I can see like actually human readable source code stuff in here. Sort of. Okay, that's something. Oh, and there's a lot of output. So we totally went through the whole thing. Let me tee that to like, what should we call this? Decoded dot VBS. Yeah. And it spits it out because I use tee. Okay, so now I have this decoded VBS can decoded decoded dot VBS. Oh, it needs a D ASCII text. Good. Okay, actually somewhat readable. There we go. Okay, so this is this is genuine. This is actual visual basic script now with a lot of weirdness. But let's, for the sake of our sanity, try and get some syntax highlighting and sublime text. I'm pretty sure there is a visual basic script, like package thing that sublime text can just use. So yeah, I hit control shift P on my keyboard to invoke sublime text, like control line command panel. And I just entered install package so I could get into package control. See this one just typing in VBS for visual basic script. So while whack enter on that looks like it successfully installed. Let me close all this out now and see if it displays it better. Yes, with syntax highlighting. Okay, perfect. Let's see what the heck this thing is and does because there are a lot of completely random variable names in here. I also think this is hilarious. These W script dot sleep zeros. That literally does nothing. That line does absolutely nothing. It's just going to sleep for zero seconds as in don't sleep. Don't wait. So how many of those are there? Because I see them like repeated over and over and over again. Sublime text tells me there are 231 occurrences of W script dot sleep. So let's nerf that thing out of here. Find and replace all that with an empty string. So they all go away. I hit control H to do finding replace in sublime text. And once you're specifying what you want to find and what you want to replace, I use these backslashes here to escape the parentheses because I am in regular expressions mode. And then you hit control alt enter on your keyboard. It will do the finding replace for every single occurrence. So that works. I don't know what this comment is. Is this base 64? Let's pipe that into base 64 decode. My face is in the way. Nothing useful. Okie dokie. But it's a comment. So like that's kind of weird. It's not doing anything. And I saw that W script dot sleep line was probably just morphed into it because of the standard outright chunk thing that that script was doing to decode this. We should probably in all honesty, and I think I want to tackle this as soon as I'm done recording this video is like sort of clean the script up or make it so that it does do it on every single occurrence of these encoded markers that it finds rather than just doing the first one. Because what if a file like this like runs comes along again. So we can Python three of five this and maybe make it better do some odd parts do some other more interesting things. You can find out on my GitHub real real soon now. Let's see what else we got here. A dim is the marker in visual basic script to create a new variable or kind of declare Hey, I'm going to end up using this. And this thing is apparently set to 544 for some reason. So I'm going to rename that variable. And this is kind of like my process whenever I see some variable names that don't make sense. I'll try and read through the code and understand what they do or what they're being used for and rename them so I can make sense of it as I read and see all the occurrences later down later on in the code. So this is just going to be 544. There we go. Again, find replace all of those. And then we have this thing that takes a tangent function like weird trigonometry functions. We'll call that like tangent funk results, I guess. And then we have this thing. Oh, that was that big giant blob of straight nonsense we saw earlier. Yeah, this thing goes on forever. This is my horizontal scroll bar. What? All right. So we'll call that big blob of nonsense. I think that's the appropriate name for it here. Big blob of nonsense. There we go. And then we make more variables. 142 for some reason, doing another tangent function. Why are these things happening? 142. I see I'm being weird here. I didn't use underscores in those previous variable names and now I'm using underscores. This is classic programmer inconsistencies, not that I'm programming anything right now. Another tangent function. I don't think that actually does anything. Are these variables literally ever used again? No. No, they're not. That is completely useless. Thank you. Weird visual basic script. How about this thing? Oh, that one's set to an at sign to limiter. That's weird. Seemingly. All those five at signs. We'll call that five at signs. What about this stinking another tangent nonsense? That doesn't do literally anything. It just takes a tangent value for no reason. Okay. Big blob of nonsense. We've got five at signs. We do another tangent function call. Oh, and then we take the big blob of nonsense and we split it with the five at signs. Oh, because those are all separated by numbers here. We'll call maybe characters, maybe like ASCII characters. We'll keep using more tangent functions. Great. That is set to zero. I'm just going to set that doesn't look like it's being used in a random tangent function. But this however is so we'll kill that. And more tangent function, complete waste of time. What is that used for? Oh, that's working with the big blob of nonsense down there. What is you bound supposed to be? Is that a function VB script you bound? You bound VB script you bound function. Oh, I'm back out of dark mode again. Sorry for your eyeballs, everybody. Turns the largest subscript for the indicated dimension of an array. What does that mean? What? Oh, so they use L bound. To see the total number of things here. You bound is going to kind of get the count. Is that right for a single dimension array? That was a not very helpful explanation. W3 schools, maybe it was, maybe I'm just stupid. Tutorials point tells me literally the exact same thing. Largest subscript value. I'm pretty sure that is just taking the length. I'm pretty sure that's just getting the length of the script of that array. Yeah. So let's call that, and they subtract one from it. So we'll just call that like length of nonsense. And keep in mind that nonsense has now just been split by these at signs. So we are literally getting a list, essentially, or like an array of all of these numbers. So, okay, moving on, more tangent functions die for E equals zero to the length of nonsense. Oh, this is a for loop here. Is there an end for anywhere? Where the heck is this not? Oh, there's a next. Okay. We should probably remove some of these serious amount of new lines that I just put in here because of the W script garbage. Let's clean that up. These can all go away. Five at signs. We split the big blob of nonsense. The length of the nonsense is now being used. And another just following that as a useless tangent function. Then we do another useless tangent function inside of the for loop. I should indent this for loop, by the way, just so we can kind of understand our logic flow. I'm just cleaning right now. There's a lot of stupid stuff in this tab that so we can see the for loop there. This is yet another uses tangent function. This is also yet another uses tangent function. Okay, so the whole W script dot sleep zero thing and all these uses tangent functions is just making the code do random things or not. Like have strange functionality. So like behavioral analysis will just die or it's like, oh, no, this thing seems fine. It's just doing trigonometry over here. Oh, but we do actually, we do actually do stuff with our big blob of nonsense. That looks like it's being indexed with E being our iterator. Right. So E is our iterator. I don't want to control H that E because E will be present in a lot of other random things like actual variables. Actual variables that I want to use. So let's call that index of nonsense. Slap that in. Oh, and then we take the character of that. Okay. So, oh, sorry, I need to replace that specifically with character of nonsense. No nonsense. I can type another stupid useless tangent procedure and another useless stupid tangent procedure. But eventually we're building up a new string seemingly of all characters joined together. Yeah, yeah. Another useless tangent function. Oh, and then we actually sleep for real. And we execute global. All characters joined together. So we're building out, we're looping through that list and carving out data out of it. What is this execute global thing doing? VBScript execute global. The execute global statement execute one or more specified statements in the global namespace of a script. Oh crap. Okay. And then we have the eval. It's basically execute like within the current context. More random tangent functions. So we should probably figure out what that all characters joined together thing is, but we have, oh God, a lot more to do in this script. Holy crap. Wait a second. These all look like the exact same thing. These all look identical. WTF. I mean, not identical, right, but they're, they're literally do this goes on for 25,000 lines and more than that because we cleaned half the thing. Another random comment with not actual base 64. That doesn't make sense. So what else we got? What else we got? Let's scroll back to where we were and let's kind of figure out what these things are doing. So this is a function and we define some variable with completely random strings. Let's call that random string. Let's call that another random string because that's being defined to that thing just following it. It tests if the random string is not equal to the other random string, then it ends them together or no, they concatenate them. That's, that's the, that's the operator to concatenate in visual basic script, I think. So it concatenates them together. We'll call that like concatenated. And then we do a for loop for one to three where we set the return value of this function to that. It just adds in the concatenated thing. Is this function ever called? Oh, it's redefined. What the heck? How many times do they redefine this function? 165? What? It literally is the exact same code. It's just, it had the exact same variable numbers, but it's just doing nothing. Is this function ever called though? Let me go back to the like the last call or the last match. No, it's literally just, it's just defining and declaring these functions. It does straight up nothing. If I search for every single function and carve these out, what else is left in this code? Do they ever actually use these functions? Let's use regular expressions and try to get new line characters up to a new line, new line. Or let's search for an end function and space function. I think I need that to be greedy. Is that right? Crap. How do I do this? I want multi-line pattern matching. End, gosh, end function. I want this entire thing, please. How are you not matching that? I don't know what new line things I need to deal with. Control H for function, which we do. Match everything and then match new lines. Anything as many times as you can up to a new line multiple times. Multiple times. What the heck? This will be the death of me. Seriously, what the heck guys? I know I've done this before. Function, anything matching it with a new line character. Anything matching it. Let's get multiple of these up to end function. Up to end function. Oh my gosh. I'm crying. I mean, what's a good way to do this? I'm going to stifle. I'm going to stumble at this wall for a couple of minutes. So if you get bored, skip ahead. I know I've done this before. Function, anything, get me to a new line. Get me anything on the following line and match that as many times as you can. Match this thing. Oh, new line plus that as many times as you can. No. How about anything plus a new line as many times as you can? No, no. This is me like choking at regular expressions, everybody. We're going to burn five minutes on this video just because I'm literally trying random things. But I'm seeing Sublime Text match the first line. Do I need like a in the selection? No, reverse case, no case and sensitive whole word. Should that do it? End function. Okay, this is a stupid loss cause. Let's move on. All these other strings though, because we know this thing is repeatedly defined, but it is never actually called. So are any of these functions called this thing? Wait, this is the exact same setup. Like looking at RKSNXBL, obviously, it just loops for a random number concatenating on the strings that it concatenated that have no real purpose. But then if you search for this thing, it's never actually called. What? What are you doing? It just defines more random variables outside of the scope of these functions. So it is the same variables over and over again. Okay, this is useless. That portion probably doesn't do literally anything. Let's just go back to our stinking big blob of nonsense, our only friend here, and let's try and carve out what this thing is doing. So we'll slap it in to its own Sublime Text window so you can kind of get the context as to what we're working with here. Let's turn off WordWrap so you can see just this insanity. And now let's get into Python and let's just split this in our own way, you know? Let's do Python 3 and take this entire blob and store it as blob, right? And I'll paste that in. Great. Now I have a blob. And that's the whole thing. So let's do a blob.split on those, what was it, five? Five characters of at signs? And now we have all these ASCII numbers. And it took the character of these. So we will do the exact same thing and some nice neat list comprehension. We'll do character array of C for C in that blob. And that needs to be an integer. So we'll cast those to an integer first and then we'll take the character array of it. Oh, and there's an empty line at the very, very end. So we'll do another check if that C value exists, if it's not an empty string. If it is an empty string, we'll totally ignore it, but that gives us some stuff. If I join all of those together, well, we have like an actual readable string here. Yep. Oh, and that is totally more visual basic script. Okay. Let's save this as content. And now let's write that to a file. Let's open second stage dot VBS. Right. And let's just write to it with our content. Okay. Open up another terminal down here. Now we have second stage dot VBS. So let's take a gander at that thing. Ooh. Recoder Houdini Skype Houdini FX. Now we're getting to the real malware boys. Ladies and gentlemen, this has a host name for duck DNS on port 81 installing directory for a windows environment variable of temp using an LNK folder and LNK file. I said those out of order. Public variables for the W script objects that we pull in. So W script dot shell file system object. And let's take a gander through this code. Let's see what it does, boys. Can we clean this up? Can we clean this? Maybe, uh, maybe is there a, maybe a visual basic script beautifier? VB code and denter. I trust you indent. Thank you. Code beautify. See about you. Did you like do it automatically? What the heck? What the heck? All right. That isn't working either. VBS beautifier format code. Holy cow. I am, I am falling down a rabbit hole here. Just trying to find a, let's just like a code beautifier. It doesn't need to be visual basic script guys. I just need to online JavaScript beautifier code beautifier. We already did. VBS script. Slap that in. Nope. It still isn't doing it. Is there. VBS script in this. At all. I swear I've done this before. You defy. Visual basic script. Online. Online VBA code formatter. That looks promising. Let's do that. Yeah, yeah, yeah. All right. So let's call this cleaned second stage. So we actually have. Decent naming of things. Private variables install name is going to be this script. It grabs the startup directory. And it gets the. Install directory. If. It does not have an existing folder than it. Puts it in temp. Okay. Sleeps for. Some time. Creates other variables usb spreading. And then we do the thing. On error resume next. So we totally ignore things we do a little while true while loop. Install must be. Another function that's defined. Oh, and then we get. Responses. Are we posting to something? Is that a function? Is that another function? Exkecut. And then we just kind of understand. What the response is from. I'm assuming command and control server. See to. On install send. Okay, so we can download things. Upload things. The numerate drivers new made processes. Yeah, so how this thing installs apparently. Is ready. If we have free space. This is very. This is very thorough checking it. Hey, if we have space, if we have a rightable drive, the drive is ready for us to use, then go ahead and put it all here. Some you bound again. Okay. Getting the, getting the name and then adding a dot LNK file. Creating a shortcut. Yep. That's the LNK file using com spec, which will evaluate to CMD.exe. CMD.exe slash. See to run just one command echo randomness and start. To this script. Adding in quotes with CHR W34. Echo random start and then the file name. For this script and then exit. Ah, and then. Oh, it's getting an icon from the registry. That's kind of neat. Classes and just a regular LNK default icon. Then we save it. Do the same thing with more randomization of start in here. So. Okay. We invoke it with Explorer. Seemingly. Yeah. For every single folder that it has, if it looks for it, it finds it. It saves it. That's kind of neat. Spooky scary. Uninstall. Looks like it deletes some registry keys. Okay. And it tries to persist or hide in like the run registry keys. Classic. Good old auto runs. Nerves itself by deleting the LNK file. And post looks like. It does make an HTTP object and post. Like a web request to our host on that port. With the command that we want to get. So that has to be our. That that has to be specifically the C2. And the information. Is including in the user agent. Oh, it includes in the user agent header information about the computer, which we can see is on a function here. And that grabs some WMI information. Windows management instrumentation. Grab. All the information from the wind 32 operating system class. Spooky scary upstart. That's got to be okay. Writing to. Yeah, yeah, yeah. This is writing to the registry key. The default run. And then use W script.exe to invoke this spooky dookie thing. With our install directory and install name. So this file. It just persists in the registry. Those bad guys. Hardware ID. Get more information. Security. Oh, is it like looking for the firewall? Is it like looking? Yeah, yeah, yeah. Looking for antivirus products. You sneaky mom. Oh, that's awesome. It just checks to see, hey, what's going to stop me? What are the security products that you have on your phone that might slow me down? We might have to nerf all those antivirus things. If we want to be a real bad guy. USB spreading. Oh, whoa. We're almost done. We're almost done. I swear. HTML HTTP. Okay. Downloads a file. So we can like. Excellent trade things in and out, right? Yep, we post with is sending or get to be able to retrieve things. So the C2 server can work in and out. We're exfiltrating data, exfiltrating files with download and upload. Of course, all using the ADO DB stream. Storing that file with the file system object. Saving these things. Very slick. Enumerate drivers. Enumerate FAF, which I don't have to top my head. No, enumerate processes. Yep. Just using again, WMI. Selecting from win 32 process exit process. So it's going to kill itself. How do we? Oh, oh, oh, it just kills a process. You can pass in a pit and just shoot the thing. Okay. And run command and control, right? Get a little CMD shell. Just run comm spec, which is going to again be cmd.exe with slash C. And that is it. Oh, so that is some C2. That is some command and control, ladies and gentlemen. Written in visual basic script persisting in the registry. Checking out these host names or that host name. And I've seen variants of this. If you Google around, you can look at this code and you can see other renditions of it. And maybe we can do that in a later video, but they'll change the host name. They'll change the install directory. They'll change the port. What, what is this thing kind of called? I am going to need to jump into a meeting. So I have to go soon, but yeah, yeah, yeah. Here's a gist for this thing four years ago. Same sort of thing. Different hosts, different install directory and different port. So this thing has been around. Looks like this is Dunihe. Hworm by Houdini. Oh, and FireEye has some good stuff on this. And it's old. It's old. Like this is 2013, 2015, but it was kind of cool to dive into this and poke around with it. So, yeah, yeah, yeah, yeah. Literally the exact same code. Just about Dunihe, I guess is the name of that remote access toolkit, remote access, you know, Trojan Rat, visual basics trip. So that was cool. That was fun. I had a good time with that. Maybe this is a new rendition. Maybe Houdini and Duhini is back in action. But I mean, this is, this is kind of recent. So maybe the code might be a little bit different. Maybe the version number of the malware that it might be. But I hope you enjoyed this little deep dive into some strange odd encoded visual basic script file, decoding that, changing around some of those variables and following it through in the visual basic script. But this was very fun to record. I had a lot of fun doing this. And I hope you had fun watching it. Maybe you learned a few tricks or two. Maybe you like that methodology of kind of going through and understanding the source code. You can read it, right? When it's a human readable and plain text being a scripting language. But that is that. If you haven't already, maybe this could be some indicators of compromise you can throw into your library or any of that stuff. But I think that's it. I think that's all I wanted to do in this video. This was fun. I had fun. Let's wrap this thing up, everybody. Thank you so much for watching. I really, really hope you enjoyed this video. If you did like this video and you want to do more stuff like this, I have a good time with this and I think it's kind of cool to put a real life use case and practical application to some of this nerd cyber stuff that we do. But I just hope you enjoyed it. If you did, please do all those YouTube algorithm things. Please hit that subscribe button if you haven't already. Leave a comment. I'm super helpful. That is super helpful. And I am grateful for that kind of expanding the YouTube algorithm and like the video and stuff. All right, dude, I'm fading out. I'm at the end of my rope here. So I got to shut this video up. Thank you so much, everybody. I love you and I hope you like this video and I'll see you in the next one. Goodbye, everybody. Take care.