Free YouTube Transcribe

Video transcript

Lua Infostealer Analysis ("My Hawaii Vacation" CTF)

John Hammond · 5,567 words · 26 min read

WhatsAppTelegramX

Want to search this transcript, jump the video from any line, or download it as TXT, SRT, or VTT?

Open in the transcript tool

Full transcript

0:00My personal favorite challenge that I created for the Huntress CTF, the capture the flag event that we ran for the entire month of October was a malware analysis challenge called my Hawaii vacation. Now that the CTF is over, I wanted to show you the challenge, maybe look at some of the write-ups and show you a little bit as

0:18to how it was created. So, the challenge prompt here says, "Oh jeez, I was on Booking.com trying to reserve my Hawaii vacation. Once I tried verifying my ID, suddenly I got all these emails saying that my password was changed for a ton of different websites. What's happening? I had a flag.ext on my desktop, but that's probably not important. Anyway, I

0:37still can't even finish booking my flight to Hawaii. Here's the site I was on. Can you get this thing to work? And this is the malware category. So, of course, it contains malware, but we have a virtual machine that we could spin up a dynamic instance that ends up getting its own IP address and ports exposed. So

0:53we could interact with something specific to this challenge. Now this is the coolest thing because this automatic deployment of a whole virtual machine does come thanks to core stack while the challenge VM is spinning up. You might recognize that interface from a lot of the other like just hacking training or JHT endeavors that I have on the side

1:11and it is the exact same platform powering the infrastructure not just for the ondemand courses on JHT but also hosting the CTF. It is extremely easy to get up and running because it's all just really markdown and then a virtual machine and a whole technical environment, a whole range whenever you want it. That also means we can have a

1:30whole virtual private network and spin up Windows virtual machines and even like an entire active directory network if we wanted to. It's pretty awesome. And the core stack team is fantastic because they've been willing to help and support everything that we've been up to. Like the VPN connectivity was something that I kind of asked for. And then the daily releases like

1:47automatically unlocking challenges or new lessons by a release date given time was some that we needed for the Hunter CTF and they were willing to build it in. So they're fantastic. They're phenomenal. If you want to develop your own courses or host your own CTF, would definitely recommend take a look at course stack link in the video

2:03description if you want to dive in. Anyway, our challenge instance has now started and let's go ahead and connect. Now we'll be presented with the fake booking.com like fishing lure that allegedly the end user also fell for when they entered their information like oh their name and this interface and form is all faked to look like potential

2:25malware but really if you were going through the steps if you were to start a verify your ID process it'll automatically force a download for a booking ID verification.exe file. This is the malware. The lure and lie of this fish is to oh run our secure ID verification utility to finish your

2:47booking and confirm your reservation. But don't forget this is all a CTF challenge. This is all kind of makebelieve for us to then analyze that malware and see what it's doing. So if we could track down the flag.ext. And hilariously my browser no longer wants to download this. It is detecting a virus because it is malware. So, I do

3:06actually want to show you how we could kind of work around that. Um, if I actually have the network tab or developer browser tools open with like F12 on my keyboard, if I were to fill this out, cruise through this form once again, when this starts a download, we can see it go to this download endpoint. And what I could do is just rightclick

3:27and then copy as curl. If you're using cmd.exe, exe like in the Windows world or in bash maybe on Linux. You choose whichever one that you're operating with. I will use bash and I'll get us to remnux. Say I want to work in the reverse engineering malware Linux distribution and let me go ahead and just paste in that kernel command. I hit

3:47control shiftv on my keyboard. I'll hit enter and you'll see that does want to output with a binary file. So we could just run the exact same command again though it is a whole lot of nonsense. At the very end of it, I'll use tac o to save at output. And then it was like booking IDverification.exe. Right? Once I hit enter, it will

4:08download. And now that will be here in my current working directory. Now, we could simply run the file command on this, but it's not going to tell us anything all that special. It's just a Windows executable PE32 portable executable. So, what I would like to do is then use a tool like detect it easy or die. With that, we could go ahead and

4:28browse to that booking ID verification.exe. I'll hit enter to open that up. And you might be able to see there is an overlay here that contains Lua bite code. So, this is a Lua executable or code program malware written in Lua and it seemed to contain some of the artifacts, some of

4:48the leftover Lua bite code present. Now, with the advanced tab toggled, like this checkbox here, to toggle on and off the advanced display, we could use the extractor utility and then just carve out or extract any kind of portion or part of this binary that we want. But we know the overlay should have some Lua

5:08code in here. So, let's try and extract this. I'll use the dump button. And then we could just save that as Lua byte code with a T. Okay, let me hit save. Now back in the terminal inside of this directory, I do have that Lua byteode.bin. And if I were to run file on that, that tells me, look, that is

5:29Lua byte code with the Lua version 5.1. Now, I had a lot of fun with this because this was kind of the first time that I got to play with Lua. I wanted to create a CTF challenge that was some malware written in Lua and it was pretty sweet. So if we have luabyte code, even trying to like open this in a text

5:46editor, it's still going to be all hex. We can't really make sense of that. If I use something like xxd or maybe hexedit. Do I have that? Just to see the rob I don't have that. Okay, let's use xxd and then pipe it to the head command so we can see the very top. Uh but take a

6:03look. The beginning header or like the special marker of a Lua byte code file signature is hex 1B not a printable character so you don't see on the ASI section on the far right but then the full word Lua capital L so you could see that but with this Lua bite code since that is okay artifacts remnants pieces

6:24and parts of what the original Lua source code was could we kind of walk this back could we recover the original source code from what this program.exe exe really was since the Lua bite code just happened to be included. Not always the case, but we do have something to work with for the CTF challenge. And since we know this is Lua byte code,

6:43maybe a better file extension is Lua C for that compiled rendition. And since we know that this is Lua version 5.1 that was used to develop this and we're trying to maybe decompile the bite code, we could probably look for Lua 5.1 decompiler out online. And there are a lot of resources for this. That version

7:05specifically Lua 5.1 looks to be pretty commonly accessible for decompilation. There are some GitHub utilities that you might be able to track down. I've seen Lua deck work very well. Looks like there's a Rust package. a lot of options here, but honestly, I have seen this Lua decompiler website work pretty well and be pretty convenient for us because it

7:26is online. Looks like the URL here for that is luadec.maworm.site. And it looks like we could just drop or drag in the bite code lac right here and then it could spit out the source code. So, I'm going to try and open up our file explorer so that I could use the lua byte.lac Louis C and then just drag

7:47that in here for a quick and easy way to get the source code behind here. Again, totally welcome to use whatever tools you use, but I think this one did work well. And we get to see what this thing is trying to do. Granted, it is extremely well obfuscated, right? This doesn't make a lot of sense and there is

8:08a lot of code. Take a look at the scroll bar to the right. Uh, and there are a lot of emojis. That was the obuscation that I, as the challenge author, wanted to pour in here, especially with it being, oh, he he hhaha, my Hawaii vacation. So, they're all a little bit tropical. They're all waves and coconuts

8:27and palm trees, stuff like that. But with this, we have at least uh beginnings of the source code, though we can't make much sense of it. We can see some functions here like os.execute. So, it's probably running different shell commands, but they're all obuscated thanks to these emojis here. Let me copy all of this so that we have a way for us

8:47to work out it locally. And let's just call like Lua source.lua. I can paste in all of this payload. But how do our emojis look? Uh, looks like they didn't get retained. That may very well just be Sublime Text. Our text editor not willing to display the emojis. So from our command line, we

9:08could try and cat that out. And there are just the unic code representations or whatever bytes make up those emojis. To make that a little bit easier on us, we could use one of the other utilities like unluy. That one is written in Java. So we could pull that down. Let me clone that down. Inside of that directory,

9:28there is a build script. So I can run that again. I know strange things that we downloaded. just run from the internet. But I'm inside of a virtual machine, so I think we're okay. Now, inside of a bin directory, we do have unluac.jar. So I could run java tac jar on our bin

9:49unluac.jar. And we'll need to provide the file that it would work with. So let me go ahead and provide inside the parent directory our lua source. Oh, well now we want the byte code, correct? Lua C. And that spits it all out onto the terminal here for us. This is at least using kind of a backslash notation for all of the

10:09different potential emoji obfuscation that we're seeing. So, let me redirect that out to our Lua parent directory. Lua source.la. And now that's a little bit more sane. Sort of, not really. Now we just have the numbers rather than the emojis in Sublime Text. But we could see what's going on. It looks like whenever it's trying to deobuscate whatever was a

10:31big long string of emojis, they use this underscore D function with a underscore_k variable. So underscore d. We could go find try to go see how that's implemented. Realistically, it's going to be a function, right? So searching for just it isn't going to be that helpful. But let's look for function,

10:51the name of that so we could see how it is being declared. Well, there's not a lot of actual code executing here. Like, oh, calling different functions or manipulating things in the file system is what I mean. Obviously, it's running code, but it's all just manipulating maybe the variables that are passed in. This is the obfuscation routine using

11:13another argument which we might have seen at the very top here. The K value and that was presumably defined as underscore K. Is that going to be equal to something? Yeah. Okay. So there's a giant string here with let me turn word wrap on for a quick second. Yeah, that must be the key to decrypt or decode or

11:36de obfuscate whatever ends up being passed to any of those emojiified different sections of code. But since this is Lua, right, since this now we're working with the script, the raw source code, could we just sort of unravel this or let it unravel different pieces and parts of the script to deobuscate it

11:58automatically so we understand what were the real raw plain text values that are now hidden and tucked away from what was emojis. Let's try and take where we're defining this big local k value and let's try and create our own little script. We can just call this like playground.lua, right? And then let's go grab the

12:19underscore_d function that's defined as well that we could collapse in sublime text really easily. So I could then just copy that entire thing and then let's paste that into our playground script. Right? Does this need anything else? Or could we just kind of proof a concept test this if we were to run that with Lua? I don't

12:39have Lua installed right away, but we could just install that version, Lua 5.1, and then we could run our script. So, let's try to run. Let me get back to my home directory here. Lua, our playground. There should be no output. Cool. But there are no errors. So now that we've found and been able to recreate that capability, could we just

13:00find and see what any of these actually evaluate out to be? Like here is a potential error message. Maybe let's just try that and let's bring that to our playground script over here. And let me just print out what would be it calling this decrypt routine with the key. Can I now run our script? Attempt

13:23to call global_t. Okay, we don't have that, but looks like it would need it. So, we could grab that piece from the actual payload. What is our underscore t? Oh, looks like kind of a table, right? Local function and just returning these out. So, do we need that functionality? Nothing malicious in that

13:44payload. And we could try and trust running that. Now, let's get back to our terminal. Run it again. Now, we need underscore_U8. Okay, so we're just peacemealing the parts and pieces that we need here and then giving our own little playground harness availability to be able to run that. Looked like it tried to run it, but I don't know what if that worked.

14:05Does that have everything that we need? Let's try to get some of the other chunks. If this is all the very beginning of the script, maybe this is just the developing harness for how we could deobuscate different parts of the code. Let me try and print now. That will run. Okay, cool. We might have been missing some of the other variables

14:26that were defined up here like a space equ whatever blah blah blah. So that gave us a plain text readable string and that technique could kind of be used to deobuscate or decrypt each and every one of these inside of the payload file. But that could get a little bit tedious. doing that manually, though we know that

14:47is really the objective right now to try and make sense of what this script could be doing. So, this, I'll admit, might be the best time to get some AI or artificial intelligence involved because we know how we could decode, deoffuscate, decrypt, whatever you want to say for that underscore_D function that seems to be unraveling the

15:08pertinent parts and pieces of code here that maybe we could just have chat gpt crap out a decoder script. I have this Lua code and I'll paste in the entire payload here. It looks like all of the original plain text strings end up being deobuscated, decoded, or decrypted with

15:29this routine. Could you please create a Lua script that will take in an input file as an argument, look for these function calls, and then replace them with the actual inplain text string that should have been there. Fingers crossed. We'll see how that does. I threw a lot

15:50of code at it, so I don't know if that'll fit in the context window. [laughter] Okay, here's a self-contained Lua de obviscator that reads a Lua file, finds the calls, and then tries to decode them. Oh, it detected the emoji alphabet. [laughter] Okay, cool. This should be nice and handy if it works. Fingers crossed. But looks like it's re-implementing the same

16:10functions that we provided. So, this might come together for us. Let me be honest with you. Developing the CTF challenge was a lot of AI slop because I know I need the idea. Okay, have this functionality of a malicious payload, but can we tweak it, tune it, make it harder for humans to make sense of obviously the emoji obuscation, but

16:33having the ideas and still having AI be able to put this together so the code runs is still pretty handy. Okay, so let's try it. Let me go ahead and copy this code. Let's get back to our text editor with maybe a decoder.lua. Let's paste this in. Try and run this from the command line. Okay, that's actually

16:52looking pretty good. Let's redirect that out to the actually I think we can use tact in place it created for us. Oh, no extra hyphen. So in place. Sweet. So now we should have the original source code with all of those strings deobuscated other than the deobuscation stuff at the top for the actual functions that did

17:14it. But now you can see the plain text strings here and none of those emoji unicode whatever symbols here. And there is a lot of anti-debugging stuff set up at the very top here. Fun fact, when I was developing this challenge, I did not want you to end up just throwing it into an online sandbox and then being able to

17:32uncover what this program really did. But I think some folks were still able to just throw it into any run, uh, any run and then be able to uncover it, which was a little bit of a bummer. I wanted to drag you down that static analysis route, but hey, whatever. A flag is a flag. There's a lot of these

17:49extra functionality for anti-debugging stuff. When we eventually get to the very bottom here after all this anti-debug, while there is a ton of them, the actual code kind of kicks off with this UF function where it's working with curl, the command line utility that we've already been using in this video to be able to interact and work with

18:08online sites. Well, we could upload a file. Looks like they are using this tac f with a file that might be provided. So they actually end up building out functions where they could check if a directory exists, make it if it didn't, using curl to potentially download. I'm going to assume this DL function here. But they go ahead and try to get a

18:29temporary directory made use 7zip downloading it literally so that they could end up creating a allegedly fakemp file that's actually going to end up bundling up everything inside of a users's directory. So let me turn word rap on so you can see some of these strings a little bit better because

18:50there is a PowerShell payload in here where we get a user account like a Windows user. We get their location like their user profile, home folder, directory including their desktop, their documents, their downloads, all the things and their SID or their security identifier, security identity descriptor, whatever that acronym is

19:10supposed to be. And they bundle this all up and extract out the SID to be executed and uploaded to the endpoint that we actually already started for this challenge. It's like hearkening back to itself, bundling up the end user and the victim's entire directory with all of their files like essentially an

19:31info stealer. Infoststealer payload written in Lua using sevenzip. Super simple. But they upload this with a specific endpoint big long name here with some arguments Prometheus and a random string. So let's try and get to this URL. Let's go see if we could actually access that back over here. And

19:51it prompts for a username and password which we can see because that's presumably included for this UF functionality here. USPS as the arguments that would take. Do we see that actually used? Yeah. Okay. Username and password right with that TAC U for the authentication header or authorization to access this. So we have

20:12a username Prometheus and the password here. Another fun fact developing this challenge I was thinking of using the Prometheus obfuscator. never actually did. I ended up making this custom thing with the emojis, but I wanted that to be kind of the trick. So, now let's enter Prometheus as the username. Paste in that password and see if it will let me

20:32in. Looks like it does. Okay, so there were uploaded files as if they were already exfiltrated out from the victim, right? That's the premise of this challenge. he or whatever end user was walking through Booking.com fake fishing URL and was infected by this info stealer malware. So we have the zip archive of everything that might have

20:53been in their directories folders, right? The flag.ext that was on their desktop and a log file. What is this log file? We could download that as well. I've got those downloaded. So let me go look at that log file. And it looks like just a bunch of numbers. But looking back in the code, that's actually

21:13created the log extension here based off of their SID or that unique identifier for that user, redirecting it to this f variable with that.log extension. So that presumably is the end user SID, maybe just not in the format that we're used to. And they actually use that the

21:34raw value it looks like as an argument that gets passed to that BD function. Can I find that function bd? And that is probably a password. Yep, that's the password that's used with sevenzip to bundle that up. So I need to convert this to I guess the regular syntax for a SID, right? And if you aren't familiar,

21:54okay, that is a security identifier. Just trying to go take a quick look. Taking a look at the Windows or Microsoft documentation. Do they have an example here of what that should look like? Yeah, normally this sort of style and structure, but we just have the raw bytes that we need to try to put back in place. So, with this log file that is

22:13allegedly a SID, could we convert this into the proper format, what I want to do is actually replace all of the new line characters with a comma and that way we could use this as some syntax. Let me get back to Windows real quick because we could try to create these as bytes. Like maybe we define that as a

22:33variable and then we define the type of bytes and that should be a list of them, right? And we could slap all of those in. Oh, sorry. I think that type is just byte and then as an actual array. So, let me remove the s plural here. How about that? Okay, now we have all of the bytes as they were originally kind of

22:53perceived and parsed within PowerShell. Now we could carve out the SID with a new object system security principle security identifier I think and then we would pass in the bytes and does that take a oh shoot sorry needs another argument for zero to know that it comes

23:14from there. Okay, cool. So now we have a SID that's created. Uh, and let me actually store that as a variable. We can just say that is the letter S. And then the letter S, let me get the actual value out of that. Okay, now we should have a SID. And that should be the password. So if it is the password to

23:32our sevenzip archive of all of the files that were for this victim, it will take a password. Let me drag that in. I can paste in the SID that we have uncovered. Fingers crossed it extracted. AO. Okay, so inside of here we have all of the files that were on that victim computer, right? Desktop, documents, downloads,

23:53and they noted that the flag.ext was present in their desktop. And there it is. We have solved that challenge. That is my Hawaii vacation. That was the malware analysis challenge. It was personally my favorite both in creating and both letting you all hopefully get a chance to play with for the Huntress

24:14CTF. Bringing that back to the game board, we would go ahead and submit the flag and that was correct. So, for just a little bit, I think it would be fun to go peruse through some of the writeups as to how people solve this as well. Here's one from is the Dev. Um, let's see. They had my Hawaii vacation. They

24:32do. All right. Challenge began with a web form that would download a heavily offiscated executable. They use strings to do some analysis to start off seeing the anti-VM checks. Then they could see the luabyte code in there and they extract it with cyerschef. Neat. Okay. And they used unluy to decompile and pull out the source code and they could

24:52track down the decoding function. They had a Lua decoder script similar to what we did with a lot of the necessary boilerplate to get that to work. I don't know if that's AI generated or not, but hey, again, flags a flag at the end of the day. They uncovered the username and password to get to the endpoint URL.

25:12Kind of like the back end of that malware. Found it uncovered and got the SID. Easy peasy. Here's another from Alta Cyber. Let me go look for my Hawaii vacation. Cool. They got it, too. Yeah. Okay. So, they were tracking someone using any.run run to get just the username and password, but that was less fun. I think the static analysis is

25:34again the road that I wanted to lead you all down. Oh, and they actually found the Lua offset and then used DD to carve it out when we just used detected easy. Cool. Another UNLA C. A lot of the emojis. Excellent. Oh, and then they uh used AI. Cool. Nothing wrong with that. Again, I think that is I mean a part of

25:54not only now developing CTF challenges and solving CTF challenges. You still kind of have the wherewithal and the understanding of what's going where and yet they could see this curl command would end up being executed with the username and password. They could recover it and then they converted it the same way that we did in PowerShell. Excellent work. That's uh Steven Folk.

26:14Thanks so much. Big shout out. And Rasvie Overflow, thank you so much. shared a whole YouTube video on walking through all of the different malware challenges from the game. So, this is awesome. And they are all even timestamped so you could jump to any of the specific ones to kind of see it in action. But looks like my Hawaii

26:33vacation when we get to here, he does walk through it and then just slaps it into any run, which is totally cool, totally fine. Uh, but yeah, I'm like, dang, they were able to uncover the Prometheus string and just the username and password that would end up being used. So, now for maybe some of the fun behind the scenes, I'm hopping over to

26:53my Kelly Linux VM and let me get into the challenges directory for my Hawaii vacation and I can show you how this was kind of all put together. There's a lot here because it's a lot of junk. It's a lot of nonsense. The original raw Lua script was just this pulling down from sevenzip to get the executable. I

27:14originally was going to try and have some libraries used to pull that down, but I ended up just opting for curl because that way it's a built-in and then I didn't have to try to compile in other like socket http ltn2 and other libraries and things for the standalone executable that I wanted to end up giving you as the player. basic

27:32authorization header and then being able to check whether or not we'll execute scripts or files. And then this is what I ended up just tightening up changing the different variable names to be much shorter. Obuscating a little bit of the code and of course pouring in the anti-debug capability. Then I had a whole script that would straight up

27:51obfuscate with the emojis and translate to a lot of the nonsense so that any of the strings that were present in the original payload would get encoded, encrypted, whatever, obfuscated with that function and just look like emojis and be a little bit overwhelming. Again, a lot of that is AI crap, but it's for the fun of the CTF challenge. To compile

28:14this, I would actually end up having srl lua.exe exe and glue kind of bundling these together. And I would make sure I would have Louis C actually keep the bite code inside of the file because I wanted that to be your real breadcrumbs to be able to make that a little bit easier. I didn't want you inside of

28:31Gedra or IDA or Biner Ninja to be cutting up a Lua executable. I still wanted you to be able to uncover the source. Then behind the scenes, the actual application is just a raw Flask app. I'm sure you can smell a lot of the AI slop here, but that is just keeping track of all of these. And then it's

28:48hosted on a Windows host so that it could compile and like dynamically put in the actual URL for this running instance. So it would know its own URL and address and port so that the callback or the quote unquote C2 like the backend of this malware is going to funnel back to the host that you

29:09dynamically spun up. That way it would actually write specific to this instance what the malware ends up being and then displaying this out for the other endpoint and making the booking.com fish page. So I hope that was pretty cool. Again, we had like almost 12,000 folks that had registered and played the Hunter CTF and almost 7,000 teams in the

29:30scoreboard, which is absolutely bonkers and bananas. Kind of the new record. Uh greatest thing that we've ever been able to pull off. And looking at My Hawaii vacation that had about 153 solves, uh, First Blood came in about almost a half hour into the game start. I think we had a significant kind of falloff of people not playing through the whole rest of

29:49the month, which makes sense. You know, life gets in the way. That's why we had hosted the game for so long. But we would not be able to do all of that without the huge support from Core Stack. They made this landing page. They made, of course, the infrastructure. And I did want to make sure that they were

30:03in the limelight for a little bit because seriously would not be able to put on a game at this size and scale with a VPN, with Windows boxes, with all this uh without their help. So, big shout out to them. You can check them out in the link below. Thanks so much for watching. Hope you enjoyed this

30:15video. Please do all those YouTube algorithm things. Like, comment, subscribe. Let me know if you like this new uh display uh maybe long vertical for me and then the actual full screen without my face getting in the way for any part of it. Let me know in the comments. Thanks so much. See you in the next video. Goodbye.

More from John Hammond

All 86 transcripts from John Hammond

Recently added transcripts

Browse the whole transcript library Browse all English transcripts

This transcript was generated from the captions YouTube publishes for this video. Get the transcript of any YouTube video atfreeyoutubetranscribe.com, free, unlimited, no sign-up.