 What's going on everybody? My name is John Hammond and this is a video showcasing one of the challenges from I Know CTF or INNO CTF. Admittedly I don't entirely know the best way to pronounce it. Let's go to their website and check it out. I know CTF.com. This was an international competition I believe out of Annopolis, Annopolis University team. So some cool people, some cool dudes, and they had one challenge that I really, really like and wanted to showcase to you. Might do a couple of videos on this, but Prism, one of the miscellaneous category challenges I think is worthwhile. I had a lot of fun with it, thought it was super cool, wanted to show it to you because maybe you might like this technique. So they give us this file. It says, do you have a prism to take a closer look? And we get this PNG that we can download. I have it already stored and created. Let me just open up a terminal here. I'll work in the INNO directory that I have and it's under prism complete. I have the files in here that I had used and I will create or showcase anyway this prism.png. So it's a QR code with different colors other than black and white, right? You can see kind of the full RGB values, maybe 255 for red, pure red, same with green and blue. And they even have some yellow and light blue and purple in there. So other colors that we would need to extract out and remove away, right? We can't just simply Zbar image, try and showcase, hey, what does this QR code scanned to actually evaluate because we have those oddball colors in there. So we need to create some renditions of the image where those are gone away. Problem is we have so many colors, how do we know which of these are considered black and which of these are considered white? So originally I thought, well, we'll probably just use RGB as regular full black and everything else will just be white. But that didn't work for me. So I thought, you know what, let's try this in a more dynamic way. And I will show that to you right now. Let's pump out some code to showcase that. I'm going to create a script. I'll call mine ap.py. I will make this a little bit larger so you can see it here. And I'll use my shebang line. I'm going to use Python 3 because the internet yells at me if I don't. And I want to use the Python image library. Let's get image out of here. And let's go and open that image up. Let's use open from that image module. Let's say that's prism.png. I'm gonna call that img just so I have it stored as an object. And let's get the size out of it. I'll say size equals width and height, which equals that pulled out. And I want to just see that image mode. So I know, hey, this is what it actually, these are the kinds of lists or tuples or arrays that I'm actually see when I look at the color values. So let's brought that down a little bit so you can see it. I will use Python 3 ap.py and it's just RGB. So we can expect when we're looking at this, we're actually just gonna have colors 255, 255, 255, etc. etc. Okay, so let's actually keep track of those that we know we have here. We have white, which will equal 255, 255, 255, full color and all RGB values. Black is the absence of all colors. So let's turn, whoa, change and turn. Let's turn those to all zeros. And let's go ahead and create a new image based off of this, because we need a place to store everything that we're gonna actually process everything that we're going to change all the colors that we're going to work with. So I will say new, I guess I'll call it new image. And we'll go ahead and say that can be image dot new. And we need to have that the same mode as the other one and the same size as the other. So make sure that runs looks like it's so good. Okay, I hope you were able to see that RGB value. I don't think my stupid faces in the way fingers crossed. Now let's actually work through all of the colors. Let's go ahead and actually get the data or the loaded values all of these images here, especially the one that we just actually opened the one that we want to see. So I'll use image dot load and I'll store that as data. And then I'll do four X in range width. Same thing for height. We use height here. So now I have X and Y iterating through all of the different pixel positions on that image, we can say color can equal data indexed at X and Y. And if you wanted to, you could just simply print out the color to see, okay, we're gonna end up prunching some numbers here and getting all these values out. I want to actually keep track of these color values, just as the first pass to kind of get an idea for what colors are actually in there. Because truth be told, I don't know. Hey, is this actually what what's the color value for that yellow or what's that red or what's that blue, etc. etc. It's probably 255 and then the subcomponents moved around. But just to be sure, I figured let's create a list of all of the scene colors or the colors that are present in the image. So let's do that. I'm gonna go ahead and create an array or a list. Sorry, Python. And let's say if color not in scene colors, we'll go ahead and append it there. scene colors dot append. And then just for our knowledge, we're using our code to further develop our code. Let's go ahead and print out those scene colors. So now if I bring this down a little bit, let's run our script. And those are the colors that we need to work with. So we have black in there. And we have white in there. And we have obviously a red, our blue, green, and some of those other mixed colors. So as we expected, it's 255 just moved around. That's totally fine. Let's go ahead and say scene colors can equal that. And we don't need to worry about finding those anymore. Now we need to be able to determine which of these are going to be considered white or black. Since we have white or black in this list, let's actually just go ahead and remove those because we don't have to worry about them. But we want to be able to determine, are we going to consider this color black? Are we going to consider it white? And we need to be able to account for all of those different possibilities, all the different combinations of whether or not we consider one of those black or white, right? So what I do here is I actually use iter tools because that has the handy dandy functions permutations and combinations. In this case, we want combinations. Sorry, that's a from iter tools import combinations. That's a syntax there. I'm sorry, I keep throwing my sublime text window around too. I know I'm giving you some like epilepsy. Also, just spit all over my computer. Don't look, don't watch this video guys. So now we can go ahead and determine what combinations of these colors do we want to work with. So let's do four potential in combinations. Actually, we actually need to determine how many of these colors we're going to consider good or not. So we actually need to keep track of how many of these same colors we actually have. I'm assuming 123456. We have six. So we actually need to stage out whether or not we want to take just this color and consider everything else black or white, or take two colors and consider everything else black and white. So we need to actually stage out the amount of combinations we're taking. I'm going to do that with a four i in range, len of scene colors now. And let's just comment that out for the time being so we can see how our logic is growing, right? So let's just print out i at the moment. So that's just going to be our numbers, right? That's just like one to five or zero, etc. So now we need to go ahead and create how many of these permutations that we want. We can call those potential. And I think I actually need to go all the way to six in that rather than just five. So let's do i plus one and we do that. Let's try it out. Let's see anyway. Let's use potentials of scene colors, combinations of scene colors with i. Let's print out all those potential combinations. I'll bring this down so you can see it a bit. And okay, we have all these intertool objects. Let's make that a list just so we can get an idea for how many of them there are and what they look like. Whoa! So a lot of stuff, right? Let's say first one. I don't know how well you can see this. Nothing. And then we have a couple combinations that's only one small size. And then we keep adding size to that, etc, etc. Because we're growing out our combinations. I should probably actually show you that looped through. So let me do for good in potential. Let's print out good. That might be a little bit easier to visualize because it's not a mess. There we go. So we start by taking only one subset of colors. So we'll be able to determine, okay, if we're in this good list or if we're in the subset of colors, we'll consider those pixels black. And we'll consider everything else to be white. And then we'll just determine it. That works just fine for us. And because we're staging out how many of these colors we're going to group, we always determine, okay, we're filtering through all of these potential colors. This way, actually, let's make sure we use that I plus one. Maybe that's what we actually need here to get all of these. Yep. Okay, cool. So we just might miss that last set of combinations. We actually probably don't need that because it's going to be a filter of one or the other. But hey, whatever. I'm getting stuck in my mind and I don't need to be. So for good in potential, now we have a list of colors we'll consider be black or white. So let's grab our loop that we've been using to actually monitor all these colors. And let's say if color is equal to black and color is equal to white, then we know we probably want to keep that color. So let's actually grab our new image data as well. So let's just call that new because that way new image is the image file and the new is the pixel object stuff that we can just say new image dot load. Good. So if it's color black and color white, then we probably want to keep it. So let's just say new can equal that color new index at that X and Y position is that color. Easy enough, right? Now what we could do is determine if our color is in our good list. Actually use that else statement in there because we don't want to deal with these black and white colors that we just handled. If color is in good, then we can say that new X Y can be set to black. Or if it's not in either of those, then we know that that's going to be white because we're using our good list as the filter for which of these colors we're going to consider to be black or white. We're permutating or taking all the combinations of these colors and determining which of these we actually want. And we'll have lots of different QR code images. So now let's go ahead and see what those look like. After we're done looping through that image, we can say new image dot save. Let's just create a lot of garbage PNG files. I'm going to go ahead and say import string and import random. So I can just create a stupid garbage file name of random dot choice. Whoa, if I can type choice out correctly, string dot ASCII lowercase for underscore in range five. So now I would just have a random string with a PAG extension on there. So now that image should be saved. If I actually create a little page here to monitor these, we can watch LS and I will run that script. So you should start to see lots of random new images being created, right? Lots of stupid PNG files. And we could look through all of those now that our script has ended. Let's view all these PNG files. And it looks like my black didn't make it in the original pass. lame. Let's verify that. If color is equal to black and color is equal to white, new XY should equal color. Or my bad. Now let's try and run that. Why didn't you tell me I could known? Actually, let's clear all of those old images. So I'll use LS.png and I'll use greptack v to remove the original image that prism.png and all those XRX RM. So now I have nothing else other than those let's use watch tack and zero. Hopefully you can see that. My face isn't in the way fingers crossed, right? So now I'm generating new images, blah, blah, blah. Hopefully I've kept all of those images in there, all those colors that we wanted. Okay, cool. So now we have potentially valid QR code images. Question is, we could use Z bar image to look through all of those. And there's a pretty gross bash way to do that. I'll show you how to do that just so we can see it. Z bar image all dot PNG, blah, blah, blah, blah. And if it actually had some results, we'd be able to see it there. So there's our flag, right? We immediately already found you know, CTF, and there's a middle portion, and the end of the flag. So we would not have been able to find all of those different iterations, all those different versions, if we didn't use this code, which is kind of cool and kind of neat, because I think that's a clever way to look through all of the potential color combinations. If you didn't want to use Z bar image and do that in bash, we can do it in Python. You need, let me show you pseudo pip three install pie Z bar. And that should let you go ahead and pull in a Z bar tool Z bar image for Python, right? So it has a we don't need string and random anymore, we can remove those because we're going to now try and decode this in Python. So we don't deal with creating all of those stupid QR code PNG image files on our folder. It just makes a mess, right? It's from pie Z bar dot pie Z bar import decode. And then we don't need to save this file anymore. But we have new image as the value or a Python image library image that we could pass to decode. So let's print out decode. Let's say, let's just print it out. Let's just say, okay, let's create a variable for it. Let's say decoded equals that. And let's print out decoded so we can see it. My phone's going off. Holy crap, my phone's going real off. I don't know if you probably can't hear that my bad. No one cares by dawn three eight. And we start to pump out potentially scan QR codes. One of them we get another one we get and we're getting our results as they come back. It's kind of neat. Notice this is actually a list. So if we want this data or this decoded data, we need to go ahead and index it and return this data little property here. So I'll say if decoded, let's print out the decoded index dot data. And that is a bytes object. So I'm just going to go ahead and decode that as Latin one. So now as we roll through this, let's actually clean out all of those image files. We don't have any of that crap. We can run our script. And it will slowly be able to detect here are the segments of the flag that we need. I think there's some random one, we got lucky or unlucky in generating all of our thorough QR codes. But that's how we could do it. You could piece together that this is the flag when you go ahead and take these middle pieces and ending pieces denoted by the flag start and end. But that's that that is how you solve that challenge or how at least I solved that challenge. I thought it was kind of neat. I thought it was kind of cool. I think this permutations going through multiple colors is a cool thing. You might be able to expand on this if you have a giant humongous set of colors. We got lucky because this one was so small. And that's why I was willing to try this idea. If we had more things other than just those 255 sub components, maybe it would have been a little bit tougher to generate. But thank you guys so much for watching. I hope you enjoyed this. Hope it was a lot of fun. Hope it was really cool. Hope you're playing I know CTF or a no CTF. We've been doing all right. We started the game began just like one in the morning my time. And we were leading the pack was going for like an hour or two hours or three hours and we were like number one. And it's all of us in the Discord server. The few of us that are willing to play really, really cool game really, really great. If you would like to be part of that, join the Discord server incredible family awesome community members that are way smarter than me. You should totally join the party. It's great. But hope you enjoyed this. I'll see you in the next video.