/var/log/Sawada.log

SAINO中毒患者の備忘録。

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.

f:id:takuzoo3868:20171210204226j:plain

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🤔 f:id:takuzoo3868:20171212003432p:plain

SECCON{N0SQL_1njection_for_Elasticsearch!}

SHA-1 is dead (Crypto 100pt)

  1. file1 != file2
  2. SHA1(file1) == SHA1(file2)
  3. SHA256(file1) <> SHA256(file2)
  4. 2017KiB < sizeof(file1) < 2018KiB
  5. 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.