Javascrypt
I looked at the website with Mozilla Firefox, and right-clicked, and clicked on View Source. I read through it until I found a piece of javascript that appeared to generate the key. I copy and pasted it into a javascript editor that I had found via Google and added html code so that I could make it calculate and display the key for me in a nice manner. Here is my code:
<!DOCTYPE html>
<html>
<body>
<p>What is the key?</p>
<p_id="demo"></p>
<script>
function generateKey() {
var i =1;
var x = 208;
var n = 5493;
while (i <= 25) {
x = (x *i) % n;
i++;
}
key = "flag_" + Math.abs(x);
}
generateKey();
document.getElementById("demo").innerHTML = key;
</script>
</body>
</html>
My flag was flag_1596.
I looked at the website with Mozilla Firefox, and right-clicked, and clicked on View Source. I read through it until I found a piece of javascript that appeared to generate the key. I copy and pasted it into a javascript editor that I had found via Google and added html code so that I could make it calculate and display the key for me in a nice manner. Here is my code:
<!DOCTYPE html>
<html>
<body>
<p>What is the key?</p>
<p_id="demo"></p>
<script>
function generateKey() {
var i =1;
var x = 208;
var n = 5493;
while (i <= 25) {
x = (x *i) % n;
i++;
}
key = "flag_" + Math.abs(x);
}
generateKey();
document.getElementById("demo").innerHTML = key;
</script>
</body>
</html>
My flag was flag_1596.
Easy Overflow
In Java, the max value of a 32 bit signed integer is 2,147,483,647. In order to cause an overflow, all I had to do was to add the max number to the number that I was given. (I'm not exactly sure how that caused the number to become negative, because I haven't studied memory registers in great depth. I plan to do that soon.) I understand the idea of an overflow, in other words, memory registers only hold so big of values, and when one register can't hold a value, because it's too big, the rest of that value overflows into another part of memory, hence the term "overflow". I don't understand exactly how that works. I just vaguely remembered in java that we had to assign values according to size, and that each type could only hold so much. That's the reason that I knew the max value for a java 32 bit signed integer. My number was 4706106. Adding the max value that a Java integer could hold caused the number to be -2142777543. The flag was That_was_easssy!
Write-Right
I used the Linux tool called GnuDebugger: gdb -q and then typed p &secret to get the memory address of secret . I just looked for the memory address of secret and took note of it. The address was 804a03c. Then I ran the program and answered the question, "Where would you like to write in memory?" with the address of secret, and answered the question, "What would you like to write there?" with 1337beef. Then I was given the flag. The flag was arbitrary_write_is_always_right
Overflow 1
This challenge had a nice interactive feature to help one understand how the machine places values into memory. The server happens to use Little Endian format, which means that it stores the least significant byte in the smallest address. My objective was to overwrite the value of secret to hexidecimal c0deface. I looked at how someone solved a similar problem in picoctf2013 to get an idea of how to solve this one, and utilized that knowledge to solve this problem. Most Linux systems have a python interpreter installed, so I just used python. ./overflow1 $(python -c 'print "A"*16 + "\xce\xfa\xde\xc0"'). I got a shell. Then I just typed ls, to list what in the directory, and used cat flag.txt to get the flag: ooh_so_critical. If I'd overshot that narrow point in memory, which is allowed to be written in, then I would've gotten a segmentation fault for trying to write to an area in memory that is read only. I recently read a nice article about it called, "Smashing the Stack for Fun and Profit" by Aleph One. I didn't understand all of it because I'm not familiar with assembly, but I highly recommend it to read. It's an interesting view into memory.
Redacted
I just copied the page using the press-and hold on the screen of my iPad, and pasted the page into my Notes app. It saved the page. The background was black, and the text was white. There were no more black boxes on the page in my Notes app, so I could read the entire page.
Toaster Control
I looked at the source code of the page. In the javascript, I found the handlers for the other buttons, so I knew how to query the db for the action that I needed, which was Shutdown & Turn Off. The handler had to be url encoded. I looked up those encodings on Google. So the full address was web2014.picoctf.com/toaster-control-1040194/handler.php?action=Shutdown%20%26%20Turn%20Off.
ZOR**Update**
Thanks to Anonymous' comment "dog crap", :D, I noticed that I forgot to add the new "solution" method to the terminal command and a couple of typos. I added the original program and modified version to hopefully make the solution more clear. Thanks! If you all notice anymore typos/errors, let me know. I'll be happy to fix them. This blog is more like a journal. I reference it if I have trouble remembering something; so I'd like it to be as accurate as possible.
The hint states that the key is turned into a one byte binary key, which means that there are only 255 possible values that the key could be. The 00000000 byte doesn't count. All I had to do was to modify the ZOR.py program and add a solution method. Then I had to add a call to that method in the main funtion. All that the solution method does is to use the xor method already present in the program to test every possible key from 00000000-11111111. (I know, I said that the 0 byte didn't count. It was just plain easier to figure out the syntax.) It took me a while to figure out the syntax because I'm not familiar with python. I just copied the syntax of the other methods, and it worked just fine. I did have previous experience with Java, so I could understand the idea of what the program was doing. The main annoyance was the indenting. (If it doesn't work, play around with the indenting. I copied the syntax of the methods around it. Another item of note: sometimes some text editors can cause issues with the python program working properly, so be careful with which ones you use. For some reason, lately, I've also noticed that if you don't specify an encoding, python doesn't particularly care for that either.)
The solution method:
def solution(input_data):
decrypted = ""
for key in range (0,255):
decrypted += xor(input_data, key)
decrypted += " begin/end "
return decrypted
I used the "decrypted += " begin/end " line so that I could tell where each separate attempt began and ended. I guess that I could've used a newline character, to make it easier to read.
The calling method: I added it right under the decrypt elif statement.
elif sys.argv[1] == "solution":
result_data = solution(input_data)
I ran the program from the command line by typing, "python ZOR.py solution encrypted decrypedfile 25"
I added the 25 at the end to get past that annoying 5 char requirement at the beginning of the program. I could probably just remove that "if len (sys.argv) < 5: Usage()" line from the program, and not worry about that.
After running the file, I looked at the file by using "cat decryptedfile | less". When you print out the decrypted file, you'll see all sorts of junk because it is printing out every possible key value. If you look through the junk, you'll eventually see this:
This message is for Daedalus Corporation only. Our blueprints for the Cyborg are protected with a password. That password is 85bcdc9f283353a3e0ca9c4cc1c0dc
Here is the original program:
#!/usr/bin/python import sys """ Daedalus Corporation encryption script. """ def xor(input_data, key): result = "" for ch in input_data: result += chr(ord(ch) ^ key) return result def encrypt(input_data, password): key = 0 for ch in password: key ^= ((2 * ord(ch) + 3) & 0xff) return xor(input_data, key) def decrypt(input_data, password): return encrypt(input_data, password) def usage(): print("Usage: %s [encrypt/decrypt] [in_file] [out_file] [password]" % sys.argv[0]) exit() def main(): if len(sys.argv) < 5: usage() input_data = open(sys.argv[2], 'r').read() result_data = "" if sys.argv[1] == "encrypt": result_data = encrypt(input_data, sys.argv[4]) elif sys.argv[1] == "decrypt": result_data = decrypt(input_data, sys.argv[4]) else: usage() out_file = open(sys.argv[3], 'w') out_file.write(result_data) out_file.close() main()
Here is the modified program:
#!/usr/bin/python # -*- coding: utf-8 -*-
import sys """ Daedalus Corporation encryption script. """ def xor(input_data, key): result = "" for ch in input_data: result += chr(ord(ch) ^ key) return result def encrypt(input_data, password): key = 0 for ch in password: key ^= ((2 * ord(ch) + 3) & 0xff) return xor(input_data, key) def decrypt(input_data, password): return encrypt(input_data, password)
def solution(input_data): decrypted = "" for key in range (0, 255): decrypted += xor(input_data, key) decrypted += " begin/end " return decrypted def usage(): print("Usage: %s [encrypt/decrypt] [in_file] [out_file] [password]" % sys.argv[0]) exit() def main(): if len(sys.argv) < 5: usage() input_data = open(sys.argv[2], 'r').read() result_data = "" if sys.argv[1] == "encrypt": result_data = encrypt(input_data, sys.argv[4]) elif sys.argv[1] == "decrypt": result_data = decrypt(input_data, sys.argv[4])
elif sys.argv[1] == "solution": result_data = solution(input_data) else: usage() out_file = open(sys.argv[3], 'w') out_file.write(result_data) out_file.close() main()
Substitution
This one was easy. I found a nice website using google called cryptoclub.org. They have a nice Flash Substitution Decrypter. The hint in this challenge states to use frequency analysis to solve this puzzle. However, I decided to try to find the word authorization since I was fairly certain that that word was in the cipher, considering that I was looking for an authorization code. The only word that seemed long enough to be authorization was right at the beginning of the cipher, so I just replaced those encrypted letters with the decrypted letters for authorization. It turned out to be correct. Then I solved the words, "the", "code", and "is". After that, finding the substitutions for the other words weren't that difficult because there were recognizable words. The authorization code is "motherknowsbest". That was the flag for this challenge. The encrypted file ended up being a song from the movie Tangled, called "Mother Knows Best".
syhuwamrefcdvklbqxipjnzgto plaintext
abcdefghijklmnopqrstuvwxyz encrypted letters
Function Address
I used the Linux tool GnuDebbuger gdb -q. Then I just used p &find_string to find the find_string function, and took down the address of that function. The address was the flag for this challenge.
Basic ASM
I don't have any experience with assembly, however, the creators of picoctf had examples of some nice tutorials on the subject of AT&T assembly, so I was able to solve the problem by looking at the tutorials, and changing the assembly code to pseudo-code to help visualize the problem. I was supposed to find the value of %eax before the NOP in L3.
The original code was:
MOV $26693, %ebx
MOV $979, %eax
MOV $25717 %ecx
CMP %eax, %ebx
JL L1
JMP L2
L1:
IMUL %eax, %ebx
ADD %eax, %ebx
MOV %ebx, %eax
SUB %ecx, %eax
JMP L3
L2:
IMUL %eax, %ebx
SUB %eax, %ebx
MOV %ebx, %eax
ADD %ecx, %eax
JMP L3
L3:
NOP
My pseudocode. It helped to remember that the left side was the source, and the right side was the destination. Considering that in the assembly language, the value of %ebx is greater than the value of %eax, the L1 label computations were not done. So, the computations start in the L2 label.
ebx = 26693
eax = 997
ecx = 25717
If ebx < eax
goto L1
else
goto L2
L1:
ebx *= eax;
ebx += eax;
eax = ebx;
eax -= ecx;
goto L3:
L2:
ebx *= eax; //26693 *979, ebx = 26132447
ebx -= eax; //26132447- 979= 26131468, ebx = 26131468
eax = ebx; //eax = 26131468
eax += ecx; //26131468 + 25717, eax = 26157185
goto L3:
L3;
NOP
So the answer of "What is the value of %eax before the NOP operation?" is 26157185.
Spoof Proof
This one was really easy. I'm supposed to find the name of the person that doesn't belong in the network. I first looked at the ARP traffic for any ARP poisoning. I used Wireshark to analyze the traffic. (You can sort by protocol by clicking on the "Protocol" column.) Wireshark has a nice feature that tells when there are gratuitous ARP requests, (under Expert Information) and when it suspects that more than one machine is using the same IP Address. I found that the IP Address 192.168.50.4 had two MAC Addresses associated with it. I assumed that the MAC Address that was noted earlier in the traffic, before the potentially malicious activity, was the legitimate address, in other words, the address of the machine that is supposed to be on the network. I did a search for the other MAC Address and found that it was associated with the IP Address, 192.168.50.3, which is the IP Address of a user named John Johnson. John Johnson was spoofing an IP Address.
Delicious
In order to solve Delicious, I looked at the website. On the website, there was a session id. Websites use session cookies in order to keep track of sessions because http is a stateless protocol, in other words, it can't remember whether people had connected previously or not on its own. So, I installed an Add-On to my browser called Mozilla Firefox Cookie Editor. I changed the session_id of the cookie to 30. I was logged in as Dr. Florian Richards. The secret code was session_cookies_are_the_most_delicious.
dog crap
ReplyDeleteDon't know exactly what you're referring to, but thanks to your comment, I did notice that I left out "Solution" as argv[1], in "ZOR.py encrypted decrypedfile 25". It should be "ZOR.py Solution encrypted decrypedfile 25" Solution is the method that was added to decrypt the file-encrypted is the input, wich is the encrypted file-decryptedfile is the output, which is the decrypted file-25 is to get past the usage statement.
ReplyDeletewich = which-typos... 😜
DeleteShould probably add "python" before that command as well. Most people already know that, but I shouldn't assume. I'll fix it.
Delete