SECCON 2017 Online CTF Writeup
Introduction
SECCON online CTF qualifying was held on December 9 - 10. Since I did not belong to the team, it was individual participation. In addition, this time I covered with the interim report of enPiT in Hakodate, and less time to tackle the problem😫.
This article is Student Advent Calendar 2017 14th.
Writeup
Run me! (Programming 100pt)
The given source code is as follows.
import sys sys.setrecursionlimit(99999) def f(n): return n if n < 2 else f(n-2) + f(n-1) print "SECCON{" + str(f(11011))[:32] + "}"
Processing does not end due to recursion when program is started. However, since this source code merely obtains the term 11011 of the Fibonacci sequence, I used the online tool. Looking at the script though we only need the first 32 digits.
SECCON{65076140832331717667772761541872}
putchar music (Programming 100pt)
This one line of C program works on Linux Desktop.
What is this movie's title?
Please answer the flag as SECCON{MOVIES_TITLE}, replace all alphabets with capital letters, and spaces with underscores.
I looked at the List of highest-grossing films and entered it in the answer form. SECCON{AVATAR}
, SECCON{TITANIC}
, SECCON{STAR_WARS}
... What the heck. Flag is SECCON{STAR_WARS}
. However, I cloudn't accept it, so let's attack with corrective action.
main(t,i,j){unsigned char p[]="###<f_YM\204g_YM\204g_Y_H #<f_YM\204g_YM\204g_Y_H #+-?[WKAMYJ/7 #+-?[WKgH #+-?[WKAMYJ/7hk\206\203tk\\YJAfkkk";for(i=0;t=1;i=(i+1)%(sizeof(p)-1)){double x=pow(1.05946309435931,p[i]/6+13);for(j=1+p[i]%6;t++%(8192/j);)putchar(t>>5|(int)(t*x));}}
I attempted to compile, but since it did not work well with gcc version, I've formatted the source code.
#include<stdio.h> #include<stdlib.h> #include<math.h> int main(int t, int i, int j){ unsigned char p[]="###<f_YM\204g_YM\204g_Y_H #<f_YM\204g_YM\204g_Y_H #+-?[WKAMYJ/7 #+-?[WKgH #+-?[WKAMYJ/7hk\206\203tk\\YJAfkkk"; for(i=0;t=1;i=(i+1)%(sizeof(p)-1)){ double x=pow(1.05946309435931,p[i]/6+13); for(j=1+p[i]%6;t++%(8192/j);) putchar(t>>5|(int)(t*x)); } }
$ gcc music.c -lm $ ./a.out | aplay
After shaping, the compilation went well, so I piped it to Advanced Linux Sound Architecture, where the famous opening theme flowed. Great!
SECCON{STAR_WARS}
JPEG file (Binary 100pt)
JPEG file
Read this JPEG is broken.
It will be fixed if you change somewhere by 1 bit.
First of all, I analyzed it with famous tools.
$ file tktk-892009a0993d079214efa167cda2e7afc85e6b9cb38588cba9dab23eb6eb3d46 tktk-892009a0993d079214efa167cda2e7afc85e6b9cb38588cba9dab23eb6eb3d46: JPEG image data, JFIF standard 1.01, resolution (DPI), density 192x192, segment length 16, baseline, precision 8, 339x53, frames 3 $ exiftool tktk-892009a0993d079214efa167cda2e7afc85e6b9cb38588cba9dab23eb6eb3d46 ExifTool Version Number : 10.10 File Name : tktk-892009a0993d079214efa167cda2e7afc85e6b9cb38588cba9dab23eb6eb3d46 Directory : . File Size : 11 kB File Modification Date/Time : 2017:12:09 15:55:40+09:00 File Access Date/Time : 2017:12:10 06:04:08+09:00 File Inode Change Date/Time : 2017:12:10 06:04:08+09:00 File Permissions : rwxrwx--- File Type : JPEG File Type Extension : jpg MIME Type : image/jpeg JFIF Version : 1.01 Resolution Unit : inches X Resolution : 192 Y Resolution : 192 Image Width : 339 Image Height : 53 Encoding Process : Baseline DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) Image Size : 339x53 Megapixels : 0.018 $ binwalk tktk-892009a0993d079214efa167cda2e7afc85e6b9cb38588cba9dab23eb6eb3d46 DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 JPEG image data, JFIF standard 1.01
I should have used a binary editor to find out where it is broken, but since I found a useful restoration site I decided to use it as it is. Repair Your Damaged Pictures - Now! When I uploaded the file using the above site, I recovered the damaged JPEG file to some extent and got the flag.
SECCON{jp3g_study}
Vigenere3d (Crypto 100pt)
In the problem sentence, the source code "Vigenere3d.py" is given.
import sys def _l(idx, s): return s[idx:] + s[:idx] def main(p, k1, k2): s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}" t = [[_l((i+j) % len(s), s) for j in range(len(s))] for i in range(len(s))] i1 = 0 i2 = 0 c = "" for a in p: c += t[s.find(a)][s.find(k1[i1])][s.find(k2[i2])] i1 = (i1 + 1) % len(k1) i2 = (i2 + 1) % len(k2) return c print main(sys.argv[1], sys.argv[2], sys.argv[2][::-1])
Also, the log is as follows.
$ python Vigenere3d.py SECCON{**************************} ************** POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9
It is a three-dimensional Vigenere cipher as shown in the second line of the main function of the source code. What I knew was ...
- Key 1 is the inverse of key 2.
- The key length is 14 characters.
- As seven plain text
SECCON {
seven characters have already been found.
Therefore, I wrote a script to find keys in ciphertext.
import sys def drip_str(idx, s): return s[idx:] + s[:idx] def encrypt(p, k1, k2): s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}" t = [[drip_str((i + j) % len(s), s) for j in range(len(s))] for i in range(len(s))] i1 = 0 i2 = 0 c = "" for a in p: c += t[s.find(a)][s.find(k1[i1])][s.find(k2[i2])] i1 = (i1 + 1) % len(k1) i2 = (i2 + 1) % len(k2) return c # solver s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}" cipher = "POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9" head = "SECCON{" key = "AAAAAAAAAAAAAA" for i in range(len(head)): j = 1 while (encrypt(cipher, key, key[::-1])[i] != head[i]): key = key[:i] + s[j] + key[i + 1:] j += 1 tmp = key[::-1] key = key[:7] + tmp[:7] print 'flag: ' + encrypt(cipher, key, key[::-1])
SECCON{Welc0me_to_SECCON_CTF_2017}
Log search (Web 100pt)
Log search
Search the flag on Elasticsearch.
http://logsearch.pwn.seccon.jp/
I did not understand well, but when I repeatedly searched for "flag" and "response code 200", a flag text file was displayed🤔
SECCON{N0SQL_1njection_for_Elasticsearch!}
SHA-1 is dead (Crypto 100pt)
- file1 != file2
- SHA1(file1) == SHA1(file2)
- SHA256(file1) <> SHA256(file2)
- 2017KiB < sizeof(file1) < 2018KiB
- 2017KiB < sizeof(file2) < 2018KiB (1KiB = 1024 bytes)
Although it may be cowardly, I used pdf which google publishes. I added a file to fill the pdf file with the remaining size to make it fit the size.
$ wget https://shattered.io/static/shattered-1.pdf && cp shattered-1.pdf a $ wget https://shattered.io/static/shattered-2.pdf && cp shattered-2.pdf b $ dd if=/dev/zero of=tmp bs=1643000 count=1 $ cat tmp >> a $ cat tmp >> b $ sha1sum a b fa004512dad796e9e5f7958e497166c4df54eb7a a fa004512dad796e9e5f7958e497166c4df54eb7a b
A flag was displayed when uploading these.
SECCON {SHA-1_1995_2017?}
Conclusion
Total score is 600. Perhaps I should be able to aim higher. This is the problem that I challenged but was frustrated (It was a train traveling time !!! Nooooooo).
- Baby Stack (Pwn 100pt)
- Simon and Speck Block Ciphers (Crypto 100pt)
- Powerful_Shell (Binary 300pt)
Also, since I have not solved any problem of "Pwnable", I want to challenge again while watching others' writeup. At the end, I'm looking for a team. I want to get a good result by participating in a lot of CTF which will be made more advanced.