 Hello everyone, my name is John Hammond and welcome back to some more Natus over the wire web application security Some Python scripting and programming to hack some websites. It's pretty cool stuff I've been away from this for a while because this challenge level 28 is a little difficult and kind of hard So this is going to be a long video. Please do bear with me. I hope it's pretty cool though I hope you learn a few things so let's dive right in I have the web page visible right here because I want to Showcase the functionality of this application before I start to look at it in code so we have this computer joke database where we could search for a query and It will supposedly return information back out to us Normally, we're able to view the source code of some of these applications just so we can learn and understand a little bit More going through the war games here, but unfortunately this level does not provide the source code So if I don't enter anything into the search, it will go ahead and return some results for us In fact, it gives us just a couple here No shortcuts in life. Let's see if I click and find one blah blah blah It gives us like computer jokes if we were to put in stuff like Anything or please sub it would return queries that have that string in it and unfortunately nothing has please sub in it That's weird. If I tried to search for the letter a obviously it will get a couple more results If we wanted to just go for sequel injection, we particularly could but obviously that's not going to return anything Because that text is not in that query or whatever it's trying to run in the database However, if I just went for like a single quote or a double quote or just a quote It will be able to return things that have this in here So that lets me interpret that okay, it's probably escaping in these single quotes and double quotes It's not just gonna make the database crap out on us So what I'm sure you're noticing is when we actually look at some of these Returns all these things that actually return out to us that give us some information. We are getting a interesting change in the URL It throws us to search dot PHP It gives us this query variable that that is the HTTP variable that we're working with and it looks like a bunch of garbage a lot of encoded data a Lot of this URL encoding is likely for trying to hide some special characters And that looks like it may turn out to be base 64 when we actually take a look at it So let's go ahead and do that Let's get to our Python script where we have the code over on the left here And then the output of the the return and what what the web page gives us on the right-hand side So I just made a simple get request to do that. Let's actually set this to Close that other one there and set this HTML for syntax highlighting that looks neat Okay, good, and let's go ahead and try and make a request now where we actually submit a query So we're gonna end up posting to that URL with data going through here I'll put this on a new line. So it looks a little bit nicer Let's say query can equal Just a letter a and then that should be everything we need right. I'm hoping we get anything yep, okay cool we get some responses and And Now we want to be able to look at the URL. So we can do this. We can actually just check out response dot url and At the very very top here you see okay, it gives us the entire URL and This front part the whole actual web address and the search.php query That's all going to be a static length So if I wanted to scrape out the very very end here We can probably just take how many characters is this you can see at the bottom left 60 60 characters selected So let's go 60 characters from The end and we'll just get okay that portion that is the encoded information. Oh, I Put that on text not the URL Okay, cool. So now let's go ahead and encode this We probably won't need URL. I'll do this through the requests I just actually learned this request actually has a utils like submodule that allows you to quote or unquote I think it's unquote. Let me check. I'm hoping Fingers crossed. Yeah, okay, cool Now that is certainly base 64 and if we wanted to with that base 64 module included we could base 64 dot B64 decode and We'll get some raw bytes out of this that sublime text won't be able to show for us So let's actually check out the representation or REPR to display those raw bytes and Okay, looks like we're getting a lot of interesting things there So as I'm exploring this actually before I go ahead and show the representation I want to look at some experiments when we test with the Okay, we'll just base 64 decode. Let's again not do that just yet I want to save these lines though because we will probably keep track of them pretty soon I will just want to see that base 64 string for a few of these and I want to gather these I want to be able to see are there any interesting changes when I change my query So just ls random inputs I'll steal a few more of these and put them down here so I can examine them Let's say just what and Get a few more Okay So if you check out this text here, you should notice that the First portion of this encrypted or encoded or whatever this data is Is actually staying the same for the first part right here. It looks like it will get up to 42 characters in and the base 64 encoded values to give us Constant and the same values However, everything that follows looks like it will change So that leads me to think of the conclusion that we are having some static text or some non changing Regular text or data that's being propended or put at the very very start of our input or what goes through And then that's being encrypted and then eventually encoded and it seems that That's it's it's not particularly changing the segments that are being displayed here Are being encrypted kind of piece by piece or chunk by chunk Or block by block And that's telling us that okay, uh, they're being encrypted the exact same way That Points me in direction the direction. Did I say did I say another word? I may have said another word. Okay. I didn't want the england cricket team That's not what I wanted. I wanted uh ECB encryption. This is a block cipher that is electronic code book Electronic code book ECB it is a form of encryption Where the message is divided into blocks and each block is encrypted separately But going through the exact same operation kind of using the same key. It's it's not chaining these blocks or these chunks together. So You'll be able to see uh, or at least you'll you'll be able to determine portions of the encryption scheme As you tinker with and as you play with it, you'll see some examples here On this Wikipedia page the image of tux the Linux mascot when it's encrypted using ECB You're still able to kind of make out what that image actually is so We can probably do something interesting here But let's keep in mind that it is using this ECB electronic code book block cipher To encrypt our input. So the next kind of point of attack is to determine the block size or how big Or what are what are the what what's the dimensions of these chunks or these blocks that our message is being cut up into So let's take a look. Let's see how we can figure that out What I want to do first is actually determine Let's see here What query will we have? Oh, I just deleted those things that I told myself I wanted Classic Let's try and see what the length of the actually Decoded or like the raw data is after we Send it a different and varying lengths of information. So let's do four i in range and let's go about a like How many characters do we want to go for? Uh, well, how long is this to begin with how long is our decoded one to begin with before we actually check out the I put an extra string there. Okay. It is 80 characters long. So So What could we potentially be working with here? Let's go for i in range 30 maybe 30 characters long 50 180 I don't know. Let's try it. Let's just do Response equals all this. Let's determine the length Um, we don't have to view it out. Let's just view the Length i or query length and then Response length will be just like that. So let's now change this query to like the letter a multiplied by i so Let's try and run this see how long it takes for us. Uh, I forgot a comma here Okay, so query length zero response length 80 This will keep returning and returning and returning for us until okay. We see something change here We've got a difference in the response length being 80 and the response length now going to 96 So that's changing the encryption. Uh, that that it's actually outputting here for us Um, it looks like we're getting more of these changes as we change our query length Just as we would expect we're going to hit 100 pretty soon Let's zoom in on this a little bit And okay, okay, we went 80 sweet so This starts at 80 and goes until 80 ends here and that takes about Or is it 13 lines? Yep but We got 96 over here This length of the response is only 96 for 16 lines and then as we check out 112 We have 112 again 16 times you can see at the very bottom I've selected 16 lines Same thing for 128 if we check that out. We have 16 lines so what we can Assume and understand here is that this very very first block that we're looking at is obviously taken up by some of The original data or the original string or text that is being propended on or putting in at the very start of our input so That can't be that trustworthy, but maybe these other 16 length blocks We certainly can trust so that's how we can determine the block size Okay, so now let's try and figure out where our data actually is Or or kind of what how much room or what buffer do we have to work with within these blocks? So let's check out. Let's say our block size can equal 16 now that we've kind of figured that out Now we can determine what blocks we want to actually check out. Let's do Do Another for loop for each of these let's do a print just to get a nice visualizer Let's get about 50 characters of a line there and let's do four block in range How many blocks we want to check out? Well, the original thing was 80 and we want to go to We don't want to go. We don't want to make a request anymore. We saw that change happen about With character length of 16 a query length of 16 So let's change that to again 16 or 15 or whatever you want. I'm not I'm not choosing 16 because it's a block size I'm choosing it because that's where we saw a change in the response length and it gives us a couple in and out So we can explore some of those Now let's check out the actual blocks of the data that we're seeing in the response. Let's check out about How about five or let's say 80 the original length was 80 and then we divide that by the block size So let's check out the response that we're getting just like We've seen before except now we don't want the length. We want The original thing decoded from blocks The current block that we're looking at times block size. So this will originally start at zero and then up until block plus one times Block size So that'll go 16 Bites at a time 16 first block and then 16 to 32 the second block and then 32 to 48 the third block Etc. So if we wanted to check that out, let's wrapper that to get the raw representation again And let's print out block block data just like that And we still want to have our query length visible up at the top here So now let's check out what this does uh response What's not what's going wrong here? Oh, I would actually need that after the After I go ahead and query the the site Okay, so query length zero response length 80 and this is happening over and over again until we get to about 16 requests 15 requests just fine so You can see again I'm looking at the raw representation of the bytes your elaborate representation of the data So it's not base 64 encoded to separate into different chunks those different blocks So the first block or I guess block zero and we can actually Change this to block plus one. So it makes a little bit more sensor has as to how we are reading it Okay, check this out. So blocks one and two seem to be the same for every query length That we send it. So that tells us that That must be the amount that is filled up by The original propended text that's at the very very that's the static text that we don't have control over It's just being added in at the very start of our input And that's what's it's encrypting. You can see that that doesn't change blocks one and two don't change However block three is changing with our input. So where do we find a threshold where we fill up one block? We fill up block three and then we start to move into what would be block four Because apparently there's data being added after our input So we could potentially figure out what that is Because it's ecb because it's a lot electronic codebook cipher. So I see in query length 10 In query length 11 block three actually Stays the same value so And it looks like that same way onward from 12 13 etc etc So that means the threshold for filling all of block three That where that location in the message where we are where our input is going we have filled the block between 10 and 9 So nine means that there is just one more character that would eventually fill the block Because once it hits it hits 10 and 11 it's going to stay the same over and over and that means we fill the block with our our a letters so if we have one last character available in The block if we set it a query of length nine we could potentially figure out what that data is Following our input because it's being encrypted if we actually figured out. Okay. What is this block? What does that block look like if we fill it with one more character and we could keep iterating through that character to try and determine What character is it in the real data that they're appending that we don't know yet? We could probably leak it out. So that may seem weird. That may sound weird Let's let's do it. Let me show you how we how we can make this happen Let's go ahead and say the correct string Is just this representation again, we'll put that in repper So that is what they would as we would assume from that and we could import string Have all of the potential characters here. There's Printable characters for c in string dot printable Then we'll make a request where we say a Nine times because we know that that is where we're going to have one last character to fill this block And we'll put in the character that we're looking at So then we can go ahead and get What block we're looking at block three in this case? We'll take that original line that we had and just set block to two because it is zero based When we know we're looking at block three, but since it counts zero one two that will be the third block Our answer Will be this again with the third block that we're looking at so we can test if answer is equal to the correct string then we know We found the character That would be following that that uh Input the we supply so let's include that c right there. We can print Trying c And let's run this trying zero one two three four, etc. Etc. And this will loop through the characters here I hope this makes sense. I'm going to try and visualize it here with some block stuff. I'll try and Make these blocks just like this So if we were filling up our blocks up until the last segment here So first and second blocks are filled and then The third block we know we just oh, okay cool. I found a percent sign here Hopefully that will close in We are filling up until we just leak into Uh, whatever the fourth mall fourth block may end up being so one two three We fill the third block up until the Character that would eventually be starting the next block starting the fourth block so Since the original data is at the very very end here following our input We can supply everything up to that last block and since it will be encrypted one way or the other We can keep checking to see what is that character going to be Is it going to equal what it would have been had it been actually encrypted following That that's very very hard to discuss and I'm sorry if I suck at explaining that. Hopefully you see it visually okay, so Since we are since we found the character percent sign We have an interesting hunch here now because knowing the application and knowing the functionality of what this program does It's probably running a query something like select text from jokes Where the text is like and this is sequel right here where it's using that percent sign as a wild card where text is like our input With the percent sign following because that's the wild card. It'll match anything that has uh that notion in it so This is doing an interesting thing because normally using this technique now that we found that character We could potentially shrink our test block and just add the character that we found at the very very end So it will encrypt and gcrypt the same way we would expect it because now that we figured out what character was next We can try that attack again Shrinking down our padding or our space that we're filling in and so we can leak out more of the message that follows or the text that follows our input but This is kind of an issue in this case right here because we actually are probably wrapped inside of a string We at least in the sequel code that's probably running in the back We wouldn't be able to actually test this because our input is again As we saw from our testing in the beginning being escaped Like we we tried to enter a quote or a single quote But we know that that's probably not being processed as real Uh sequel commands, so they're going to be escaped with a backslash So unfortunately since that will take up more than one character And that's going to leak over into the fourth block and we won't be able to test it We won't be able to track it down since we are testing in just the very very edge of the third block Okay, but now we have a hunch now. We know that maybe this is running sequel injection Maybe this has some opportunity for sequel injection except We can't use those single quotes or double quotes Just as I was saying because they're going to be escaped. We can't just do that sequel Like union select whatever we want blah blah blah password from users We can't do that just in the search query because it will be escaped out of it So now we have to take advantage of what we know with this electronic code book and with this encryption scheme We could potentially try and figure out What uh, what what could we enter what encrypted information could we get that would actually look like we had entered that information Since we can encrypt the same way But if we handle that escape Sequence properly because we know that we're going to end up having it eventually Um following Let's actually keep that that query here If we got this single quote to be included in the third block and not no longer really necessary for the fourth block That way we could be home free where we could do our own injection following it So now we just have to figure out how we can encrypt and get the data for that input This probably sounds weird again. I'm going to show it to you Let's write this code here. Let's say our injection is A space character or letter a whatever padding we want to use times nine So we fill up the third block because that's that's our buffer here And I'm only going to use nine characters. So just as we saw that select text from jokes where thing Like blah blah blah that single quote at the very very end will actually go ahead and be interpreted just fine We won't have an escape going through We'll actually just have That single quote at the very very end rather than the percent sign. So nine will be that threshold If I use that injection and then I add on our single quote Union select. Let's just do password from users because that's kind of what we've seen in the previous levels And we'll just do a comment here to note the very very end of the sequel injection Or the sequel query now we have that string that we want to figure out how we can encrypt how we could actually get that to be Something that the back end application will handle So let's do that Let's determine first of all, how many blocks is this going to take and the way that we can do that is we can just say Blocks equals length of injection And we got a minus 10 here because we have this padding the a's or the spaces that we're filling it up with in the single quote Let's do minus 10 And then let's divide that by the block size Now that will get only up until we have a remainder So we have to say if we have a remainder we're going to need another block The way that we can do that is we can just test if The length of injection minus 10 modulus block size is not equal zero So if it's not it's if it's not a straight factor if we do have a remainder Then we can just say blocks plus equals one. So we add a an extra block in there Let's see how much how much this is going to take up. It's going to take up three blocks. Okay, that's fine Now what we can do is we'll go ahead and encrypt this the way we can do that is by checking this response And getting the url just as we've done before and said rather the query we're working with we'll say our injection And then let's check out The block that's returned for us the full thing We don't need the representation We just want the raw bytes and we don't need it cut at any specific block. We want the full thing Do I have a number of parentheses there? Okay, cool. We're good. So let's just say raw inject And if you wanted to see this you could if we want to check out the representation you could That's just fine So that is going to be the encrypted scheme that has our injection it now How are we going to be able to properly put this into a request? Without actually making the request and having the program encrypted. We have to encrypt it for the program Let's trick it. Let's try and give it original Good data like the spaces that we use to or the a characters that we use to fill the third block Then let's get the very very end Like after we have Actually filled the third block just so we know the very data at the at the very end of of the original query And then fake it with that first part of the the safe good string and then let's put our injection in between it So that probably sounds strange But again, I'll show you in code So let's get a response with just The a character or our padding 10 times to fill the third block Let's get that Good base And let's actually say that our query Will be or the URL that we're end up going to the query that we're going to be using is Good base up to the third block size So the third block block size times three because we know that that's the third block that we want now that we've filled it We can go ahead and add our injection in there. So injection We'll get the third block size filled and let's take Block size Plus three plus Blocks because that is the amount of blocks that are necessary for our injection times a block size So that's a full value here Now we should be able to add on the very very end that we had from our good base again taking from Three blocks in to the very end So it's it's faking the query and essentially just puts our injection in it and crips it the way that it would have expected it Again making sure the blocks are all in a line I've said a blocks. I've said that a lot Throughout this whole thing. So let's check out our query right now Probably something that we can't see. That's fine. Let's go ahead and Base 64 encode it. Oh, I'm sorry. I made a mistake here. Let's go from zero to the third block at the start and then other way around so from 48 in or the third block in that's my bad Now we have a proper looking injection string. Okay. Now we want to go ahead and quote this so it is properly url encoded and This was a sticking point for me It looks like that function does not actually url encode forward slashes and that Made all the difference when I actually tried this challenge So we're going to have to go ahead and replace those Let's change those forward slashes should be percent 2f in hex So that does make all the difference in this challenge We will need to make sure that those forward slashes are url encoded. This has to be fully url encoded For it to work. Okay So this can be our query now And let's keep in mind that when we actually retrieved this data It was in the form of The url With search.php at the end it brought us to search.php as a page And then it had query as the actual http variable that we're working with So now that we've constructed that variable on our own Let's go ahead and add that in So we don't post a request. We just get a request with our given query Now if I run this Display out the text that we're getting from that response Nothing So something is wrong. Let's explore Oh, I think I see the first problem and that I was using just the string injection as The the blocks that I was trying to reach out rather than just raw inject. So now let's try and run this Okay. All right. That was it sweet. So that is the the password. That's the flag that we're looking for but I hope this made sense. I hope this I know this is a crazy long video But I hope you were able to visualize everything that I was doing because electronic code book cipher is very very strange And the way that it encrypts block by block and each block is just a segment of the original message Um, but we can detect it. We can determine what it actually is So let's get uh re and scrape out this flag here. I think it's re dot find all Get a raw string from li Something in there anything to end li with our response dot text Zero and we don't need the number of blocks to be displayed anymore. That's just fine Okay, there is the flag just like that. So that is natus level 28 I hope that you guys enjoyed it. Um, kind of a long process doing some peculiar interesting things I hope it was easy to see the code. I hope it was easy to understand. We're doing some interesting things, but I was honestly just very amazed and impressed and pleased with this. I thought it was very cool And honestly a really big learning experience for me. Um, I will have to jot down this process I had this like the the procedure that I went through here to actually Okay, determine the block size and then determine where the block Actually has our input going in and then determining how we could take advantage of the fact that that escape sequence or that that string Delimiter the double quote or single quote would actually be handy for us when we're trying to do our sequel injection So very very cool. Very very interesting. Uh, hope you guys enjoy this Hey, shout out to the people that support me on patreon. Thank you guys so much. You're fantastic I love you. I don't know why no pixel has an o in front of this name. You're the best, man One dollar a month on patreon. I'll give you a special shout out just like this I think in every video five dollars or more and patreon will give you early access to everything They release on youtube before it goes live if you want the content right when it's hot right when it's work ready That's the best way to do that. Please do join our discord server link in the description It is an awesome community full of ctf players programmers and hackers You can hang out with me and other cool people will be tackling ic tf Um Knock ctf and other competitions that are coming up this week. Hey, I have a link in the description for a humble bundle Uh book package that will really help me out. It's affiliate link full disclaimer. I'm a sellout. I'm sorry. I suck But uh, it helps me put food in the table and you guys and your support really just enables that for me So thank you. Thank you. I'd love to see you on patreon Please do like this video comment this video subscribe if you're into that stuff. I don't know Uh, I'd love to see you on patreon. I'd love to see you in the next video. Get out of here, man