jtwp470’s blog

日記とかプヨグヤミングとか

Juniors CTF Writeup

Hi. I am jtwp470, a member of ctf team, g0tiu5a. The final score of our team was 65th, 3000 pts.

f:id:jtwp470:20161128005713p:plain

I have never written CTF writeup to use English. It is difficult for me to explain techniques to use English. I try to write CTF writeup using English because I am studying English.

Web

Black Suprematic Square

There are NOT a web link which connects to the problem. I searched a picture first, and I got a picture name. When I use the Chrome developer tools at the scoreboard, I found the hidden link.

Wow. Is it flag? This CTF has no flag format. :-1: So, I guess this is the flag!! I want to get a a character string but I don't install OCR software. (Because huge)

Do you know Google Cloud Vision API? This is free for trial only. I used this.

[
  {
    "locale": "it",
    "description": "a ima i wah si dupa\ni eru\nquei vahphiekah7u\ncee tai r9ai Gae1eS\nsaedoo4becooShoh\nhu8ei fahXi7EJoh2\ngaephechei 5chi P9\n",
    "boundingPoly": {
...

It is very fantastic! I fixed it by hand and I got a correct flag.

Flag: aima0AiwahsidupaiToehoong1PhieruqueivahphieKah7uceetair9aiGae1eSsaedoo4becooShohhu8eifahXi7EJoh2gaephechei5chiP9

Thank you Google!

Six Strange Tales

I felt this problem is really Web at first time. This problem was solved to use Chrome Developer tools like above the problem. I found a javascript code in the scoreboard.

 <!--
window.addEventListener('load', function () {
var b = document.getElementById('img');
var a = b.getContext('2d');
var d = new Image();
d.src = "http://i.imgur.com/GIYH3fA.png";
d.addEventListener('load', function () {
a.drawImage(this, 0, 0);
k = 174;
l = 345;
m = 12; 
n = 89; 
o = 671;
p = 18;
q = 222;
r = q-1;
c="rgba(0,0,0,0)"; 
if (navigator.userAgent == "Gravity Falls") 
c=c.replace(/(0)(\))/,"$1.5$2");
a.fillStyle = c;         
a.fillRect(q%m-6, k-3, n+r-q-2, 5-(p-q));
a.fillRect(2*(q+1), p+1, n+r-q+2, l+16);
a.fillRect(l+r-30, o%p-5, 2*l-600, q+5-p);
a.fillRect(q%n+42, o%p-5, o-600+p+1, 2*(p+1));
a.fillRect(176, o%p-5, 2*l-600, q/2*3+47);
a.fillRect(2*k+p-100, q%m-6, o-600+p+1, n+r-m/2);
a.fillRect(o%p-5, q%m-6, 2*l-604, k-p-4);
a.fillRect(2*k+p-100, q/2*3-10, 3*m+p*3, (p+1)*3);
a.fillRect(2*k+p-m+2, q%m-6,2*l-600, q+n+m-190);
a.fillRect(2*k+p-10, k-p-m/3, o-600+p+1, r+m*2/3+p);
a.fillRect(n-3, q-k+9, 2*(l-300), q+n+m);
a.fillRect(l+q-31, q+m/2,2*l-600, k-p-m/3);
a.fillRect(o-2*p-p/2, q%m-6, 2*l-600, q/2*3+47);
},false);},false);
// -->

Because of this script, I changed the user-agent to "Gravity Falls". (Note: You don't use curl because curl is not able to eval javascript code.)

Wow. A piece of flag came out!! I red the problem to get flag.

Gruncle, but how should we read the secret? From left to right or right to left? Or maybe upside down? It depends on whether you are a Christian, a Muslim or a Taoist...

I tried to read from upside down, left to right and right to left.

The "left to right" is generated a correct flag.

Flag AhWae2OhIs4feeh3ud2juD9aaej8eeThMaiy2au0dawu0Aeb

Trivial

LosT Code

I don't want to reverse the go binary. But we need not to do at this problem.

$ ./LosT.x32
This is a safe bruteforcer Lost. Try to guess (32*[0-9a-f]:
Success -- 1; Fail --0
Options
-b, start bruteforce
-h, show this help
Example: ./LosT -b 0123456789abcdef0123456789abcdef

$ ./LosT.x32 -b 0123456789abcdef0123456789abcdef
01000000100000000000000001000000

It is very easy to get a flag. I wrote a solver using Ruby.

#!/usr/bin/env ruby

pos = 0
flag = "0" * 14 + "1" + "0" * 17

while pos < 32
  "0123456789abcdef".chars {|c|
    flag[pos] = c
    val = `./LosT.x32 -b #{flag}`
    if val.rindex("1") == pos
      pos += 1
      puts flag
    end
  }
end
$ ruby LosT_solver.rb
60000000000000100000000000000000
61000000000000100000000000000000
61600000000000100000000000000000
616d0000000000100000000000000000
616dc000000000100000000000000000
616dc300000000100000000000000000
616dc380000000100000000000000000
616dc388000000100000000000000000
616dc388800000100000000000000000
616dc3888a0000100000000000000000
616dc3888a9000100000000000000000
616dc3888a9900100000000000000000
616dc3888a9910100000000000000000
616dc3888a9917100000000000000000
616dc3888a9917000000000000000000
616dc3888a99170c0000000000000000
616dc3888a99170c5000000000000000
616dc3888a99170c5b00000000000000
616dc3888a99170c5b80000000000000
616dc3888a99170c5b8a000000000000
616dc3888a99170c5b8aa00000000000
616dc3888a99170c5b8aa70000000000
616dc3888a99170c5b8aa72000000000
616dc3888a99170c5b8aa72100000000
616dc3888a99170c5b8aa721d0000000
616dc3888a99170c5b8aa721d9000000
616dc3888a99170c5b8aa721d9200000
616dc3888a99170c5b8aa721d9250000
616dc3888a99170c5b8aa721d925a000
616dc3888a99170c5b8aa721d925ac00
616dc3888a99170c5b8aa721d925ac60
616dc3888a99170c5b8aa721d925ac68

It took about 2 - 3 secs. It is very rapidly.

Flag: 616dc3888a99170c5b8aa721d925ac68

(I think this problem category is not "trivial brute force", is PPC.)

Reversing

Reverse Fever

First, I thought I need to use angr because I don't want to analyze much binary manually.

BUT, I can solve this problem using BUG. 😁

$ nc ctf.org.ru 8269
What's you name? a
Hello a! Only -3 challenges remain
For solve it you need a decode base64 data and reverse engineer crackme
…
…
...
…
Flag: a
Unfortunately :C Game over.
Flag is DEAL_WITH_IT

Wow! Why do I get flag? I don't know. I can solve this problem using one-liner.

$ echo "a\n" | nc ctf.org.ru 8269

Fxxk. PLEASE TEST THIS PROBLEM. & I am sorry that I cannot solve this in the correct way.

Flag: DEAL_WITH_IT

Forensics

I love forensics categories. 😍

Clone Attack

I think that the way I solved it is not the regular way. However, there was no direct idea. I apologize to the CTF management member. m(__)m

I extracted a given file, there are a lot of JPEG file. When I ran exiftool, I found the flag was md5sum of any file. No hint. So, I decided to submit using brute force.

#!/bin/bash

SUBMIT_URL="https://scoreboard.ctf.org.ru/flag?id=10"
SESSION="session=<sensored>"

for f in $(find ./CloneAttack -name '*.jpg')
do
    md5=`md5sum $f | cut -d' ' -f1`
    echo $md5
    curl  -d "flag=${md5}" -b ${SESSION} ${SUBMIT_URL}
    sleep 1
done

I don't know a picture is correct flag. But I can solve it. (Sorry, I didn't check the response. :))

Admin

ROFL

I found the url in the ifrace: https://docs.google.com/viewer?url=http://ctf.pnzgu.ru/text.pdf&embedded=true&a=bi&pagenumber=1&w=800&h=1100

I downloaded it and convert to text. It looks like base64 encoding. I ran the command like this:

$ cat text.txt | base64 -d | base64 -d | .....  base64 -d 
6Mn2yc7hX971xMXz

What? Is it flag? I submitted it, but it is NOT flag. I saw a telegram and I found a hint. This is KOI8-R. I used iconv to convert this.

$ echo "6Mn2yc7hX971xMXz" | base64 -d | iconv -f KOI8-R -t UTF-8

Flag: ХиЖинА_чУдеС

Restricted Area

There is an ACL list. At EXT format, they have ACL.

First, I mounted it to attach acl flag.

$ sudo mount -o remount,acl /vagrant/image.bin /media/test

Next, I wrote the code which set ACL.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# setfacl -m u:<user>:r <file>
import subprocess
import shlex
import os


cmd = lambda c: subprocess.call(shlex.split(c))
command = "setfacl -m u:{user}:r /media/test/{file}"
users = ("dipper", "mabel", "soos", "wendy", "stan")
acl = {
    "lazy_black_cat": [1, 0, 1, 0, 1],
    "lazy_black_dog": [0, 1, 0, 1, 1],
    "lazy_black_pig": [0, 1, 1, 1, 0],
    "lazy_red_cat"  : [1, 0, 1, 0, 1],
    "lazy_red_dog":   [1, 1, 0, 1, 0],
    "lazy_red_pig":   [0, 0, 1, 1, 1],
    "lazy_white_cat": [0, 1, 0, 1, 1],
    "lazy_white_dog": [1, 0, 1, 0, 1],
    "lazy_white_pig": [0, 1, 1, 0, 1],
    "silly_black_cat": [0, 1, 0, 0, 1],
    "silly_black_dog": [0, 0, 1, 1, 0],
    "silly_black_pig": [0, 1, 0, 0, 1],
    "silly_red_cat":  [1, 0, 1, 0, 0],
    "silly_red_dog": [0, 0, 1, 0, 1],
    "silly_red_pig": [1, 1, 0, 0, 0],
    "silly_white_cat": [1, 0, 0, 0, 1],
    "silly_white_dog": [0, 1, 0, 0, 1],
    "silly_white_pig": [1, 0, 0, 1, 0],
    "sly_black_cat": [1, 0, 0, 0, 0],
    "sly_black_dog": [0, 1, 0, 1, 0],
    "sly_black_pig": [1, 0, 1, 1, 0],
    "sly_red_cat": [1, 0, 0, 0, 1],
    "sly_red_dog": [0, 1, 1, 1, 0],
    "sly_red_pig": [1, 0, 0, 1, 0],
    "sly_white_cat": [0, 1, 1, 0, 0],
    "sly_white_dog": [0, 1, 1, 1, 0],
    "sly_white_pig": [1, 0, 0, 1, 0],
}


def get_user(acl_list):
    return [users[i] for i, k in enumerate(acl_list) if k == 1]


for a in acl.items():
    fname, acl_list = a
    for user in get_user(acl_list):
        c = command.format(user=user, file=fname)
        print(c)
        cmd(c)

I can get a flag.

$ sudo ./check_32
...
        sly_white_pig
UID 1008 read:
        lazy_black_cat
        lazy_black_dog
        lazy_red_cat
        lazy_red_pig
        lazy_white_cat
        lazy_white_dog
        lazy_white_pig
        silly_black_cat
        silly_black_pig
        silly_red_dog
        silly_white_cat
        silly_white_dog
        sly_red_cat
FLAG: 09D240FD60442F6CD3F45E47704D9DCBF0344B0D

Flag: 09D240FD60442F6CD3F45E47704D9DCBF0344B0D

Oh shSSH!!!

I saw a dump pcap file to use Wireshark. I found the fact:

  • SSH connection between 10.1.0.41 and 10.0.23.37. Port number is 38574.
  • 10.0.23.37 is alive via VPN.
  • Download .ssh/id_rsa ;)
  • See passwd: I think this is /etc/passwd. and found a user: hirsch.

So, I guess I need to connect 10.0.23.37 to use SSH and .ssh/id_rsa

$ ssh -i ./id_rsa -p 38574 hirsch@10.0.23.37
The_third_season_was_sold_to_the_aliens
Connection to 10.0.23.37 closed.

Gotcha. I got a flag.

Flag: The_third_season_was_sold_to_the_aliens

Summary

This CTF is so nice but I suggest that they should decide the flag format and they must use English not Russian. It is very confusing me because of nothing flag format and I cannot understand Russian, I gave up to solve some recon problems.

The CTF organizers must NOT use a cloud file service (like Google Drive, Yandex, OneDrive and more...) because they have download limit and we want to download problems via command line (like curl or wget).