ふるつき

v(*'='*)v かに

TAMUCTF 2019 Writeup

TAMU CTF had been held from 2019/2/23 09:00 to 2019/3/4 09:00(JST). Our team insecure (me, ptr-yudai and yoshiking) participated in the competition. We got 19162pts and reached 16th position. There were many valuable challenges in the CTF, thanks to all admins!

f:id:Furutsuki:20190304114512p:plain

Most of the challenges were solved by ptr-yudai (his writeup), but even I could solve some challenges too. I'm going to write the solutions to them.

[Reversing 100pts (solved by 1084 teams)] Cheesy

description:

Where will you find the flag?

We're given a 64bit Linux ELF file reversing1. First, I checked the output of strings reversing1 command. I found some base64-like strings in the binary.

 user@box:~/tamuctf/cheesy$ strings reversing1
 ...snip...
 QUFBQUFBQUFBQUFBQUFBQQ==
 Hello! I bet you are looking for the flag..
 I really like basic encoding.. can you tell what kind I used??
 RkxBR2ZsYWdGTEFHZmxhZ0ZMQUdmbGFn
 Q2FuIHlvdSByZWNvZ25pemUgYmFzZTY0Pz8=
 Z2lnZW17M2E1eV9SM3YzcjUxTjYhfQ==
 WW91IGp1c3QgbWlzc2VkIHRoZSBmbGFn
 ...snip...

I decoded them and got the flag gigem{3a5y_R3v3r51N6!}.

AAAAAAAAAAAAAAAA
FLAGflagFLAGflagFLAGflag
Can you recognize base64??
gigem{3a5y_R3v3r51N6!}
You just missed the flag

[Reversing 100pts (solved by 916 teams)]Snakes over cheese

description:

What kind of file is this?

The given file reversing2.pyc has python 2.7 byte-compiled format. The format is easy to decompile. I used https://github.com/zrax/pycdc to decompile it. The result is available here.

As we see the result, the source receives user input and compare it with an internal variable kUIl. The variables kUIl and Fqaa were cpied from XidT and Fqaa respectively. Let's see the value of kUIl and Fqaa.

>>> Fqaa = [102, 108, 97, 103, 123, 100, 101, 99, 111, 109, 112, 105, 108, 101, 125]
>>> XidT = [83, 117, 112, 101, 114, 83, 101, 99, 114, 101, 116, 75, 101, 121]
>>> "".join((chr(c) for c in Fqaa))
'flag{decompile}'
>>> "".join((chr(c) for c in XidT))
'SuperSecretKey'

So the key is SuperSecretKey and the flag is flag{decompile}.

[Reversing 384pts (solved by 405 teams)]042

description:

Cheers for actual assembly!

#medium

We were given the assembly code assembly3.s. I couldn't assemble it because it seemed to be generated on MacOS. So I edited the assembly to make it compatible with GCC on Linux.

  • rename section names: __TEXT,__text,....text, __TEXT,__cstring,...rodata
  • rename some standard functions: _printfprintf, ___strcpy_chkstrcpy
  • comment out some lines: .build_version..., .subsections_via_symbols, and some lines related with stack canary

Then it can be compiled with gcc reversing3_2.s and I was able to run it and got the flag: gigem{A553Mb1Y}.

user@box:~/tamuctf/042$ ./a.out 
The answer: 1
Maybe it's this:5
gigem{A553Mb1Y}
Illegal instruction (core dumped)

[Reversing 497pts (solved by 75 teams)]ReversingErirefvat

Erirefvfat is rot13 of Reversing.

description:

Harder..?

#medium

A given file (reversing4.s)https://gist.github.com/theoldmoon0602/d8bf5aebc0548cde47583f2aa07470ed is similar to reversing3.s. So same operation can be applied to make it compilable. It should be noted that we should link the libm by gcc -lm option because this assembly code uses round function.

Although the emitted ELF file runs correctly, no output can be seen. Tracing the execution of the main function by gdb, I found that the binary makes a string hip on the stack and converts it to uvc(in fact, this is rot13 of hip). Incredibly, the flag is gigem{uvc}.

I think this is terrible as CTF challenge :( There are so many unnecessary pieces in the source code such as round function and mostly unused abcdefghijklmnopqrstuvxyz string (w is missing). I believe all elements in the challenge should have a reason for its existence, not for misleading from the essence of the challenge.

[Misc 340pts (solved by 476 teams)]Hello World

description:

My first program!

Difficulty: medium

We're given a file: hello_world.cpp. At first glance, I found that it is also a whitespace program. When I executed it by an online whitespace interpreter like this, it printed out the message Well sweet golly gee, that sure is a lot of whitespace! and the flag gigem{0h_my_wh4t_sp4c1ng_y0u_h4v3} remained on the stack.

[Android 376pts (solved by 420 teams)]Secrets

description:

Can you find my secrets?

We're given an android apk file: howdyapp.apk. It was a very simple application which has only a count-up function. By the way, because it was android apk file, let's decompile it to source code by below steps.

$ unzip howdyapp.apk
$ dex2jar classes.dex
$ jar xf classes-dex2jar.jar

Then, there were some java class files at the com/tamu/ctf/howdyapp directory. I decompiled them using cfr and found flag variable in the R$string.class file. The variable had a resource id, so I extracted resources. I'm using apktool for extracting the resource directories from the apk file. After apktool d howdyapp.apk, correctly extracted res directory appeared under the howdyapp directory. Let's grep the directory by the keyword flag.

$ grep -R "flag"
values/strings.xml:    <string name="flag">Z2lnZW17aW5maW5pdGVfZ2lnZW1zfQ==</string>
values/attrs.xml:        <flag name="bottom" value="0x00000050" />
(...snip...)
values/attrs.xml:        <flag name="none" value="0x00000000" />
values/public.xml:    <public type="string" name="flag" id="0x7f0b0020" />

We could find a base64-encoded string Z2lnZW17aW5maW5pdGVfZ2lnZW1zfQ== whose name was flag. Decode this to get the flag: gigem{infinite_gigems}.

[Android 460pts (solved by 240 teams)]Local News

description:

Be sure to check your local news broadcast for the latest updates!

Difficulty: medium-hard

app.apk is provided. I extracted it as I explain in the previous challenge. There were three .dex files classes.dex, classes2.dex and classes3.dex. First, I dove into the classes.dex. I decompiled the MainActivity.class to MainActivity.java. Here I pick up the following part from the source code.

        BroadcastReceiver broadcastReceiver = new BroadcastReceiver(){

            public void onReceive(Context context, Intent intent) {
                Log.d((String)MainActivity.this.getString(2131427360), (String)Deobfuscator.app.Debug.getString((int)0));
            }
        };

I wondered what is the value of (String)Deobfuscator.app.Debug.getString((int)0). It seemed to be using third-party obfuscation library. Therefore, I dove into the classes2.dex this time. The decompiled and reworked(= fix variable types, delete package informations, add main function) source code is Hoge.java. By compiling and executing Hoge.java we can get the flag: gigem{hidden_81aeb013bea}

[Crypto 354pts (solved by 455 teams)]RSAaaay

description:

Hey, you're a hacker, right? I think I am too, look at what I made!

(2531257, 43)

My super secret message: 906851 991083 1780304 2380434 438490 356019 921472 822283 817856 556932 2102538 2501908 2211404 991083 1562919 38268

Problem is, I don't remember how to decrypt it... could you help me out?

Difficulty: easy

ptr-yudai tried to decrypt this as RSA where n=2531257, e=43, c0=906851, c1=991083, ... and found the fact that first pair (n, e, c0) could be decrypted to g, but others could not. Here are decrypted numbers.

103 105103 101109 12383 97118 97103 10195 83105 12095 70108 121105 110103 9584 105103 101114 115125 

I noticed that each successor numbers can be split into two ascii numbers. I wrote the following script and got the flag: gigem{Savage_Six_Flying_Tigers}. It... it is boring guessing I think.

import sys
from Crypto.Util.number import *

n, e = (2531257, 43)
p, q = 509, 4973
d = modinv(e, (p-1)*(q-1))

cs=[906851, 991083, 1780304, 2380434, 438490, 356019, 921472, 822283, 817856, 556932, 2102538, 2501908, 2211404, 991083, 1562919, 38268]
for c in cs:
     x = str(pow(c, d, n))
     while len(x) > 0:
         if int(x[0]) < 5:
             sys.stdout.write(chr(int(x[0:3])))
             x = x[3:]
         else:
             sys.stdout.write(chr(int(x[:2])))
             x = x[2:]
sys.stdout.write("\n")         

[Web 100pts (solved by 776 teams)]Robots Rule

description:

http://web5.tamuctf.com

Difficulty: easy

Guessing from the challenge name, I visited /robots.txt on the server, then I saw the following message. It ordered us to make a request as a google-bot.

User-agent: *

WHAT IS UP, MY FELLOW HUMAN!
HAVE YOU RECEIVED SECRET INFORMATION ON THE DASTARDLY GOOGLE ROBOTS?!
YOU CAN TELL ME, A FELLOW NOT-A-ROBOT!

Requesting as a bogus google-bot by this command: curl -A "Googlebot" http://web5.tamuctf.com/robots.txt, we could get the flag: gigem{be3p-bOop_rob0tz_4-lyfe}.

[Web 325pts (solved by 498 teams)]Science!

description:

http://web3.tamuctf.com

Difficulty: medium

f:id:Furutsuki:20190303154837p:plain f:id:Furutsuki:20190303154856p:plain

From the words words Flask as a Service, I tried Server Side Template Injection(SSTI) using Jinja2. As the test input {{ '7'*7 }} showed 7777777, it works. From this page I copied and pasted exploit code: ''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('os').popen('ls').read(), then the page listed some files including flag.txt. In the same way, I executed cat flag.text and got the flag: gigem{5h3_bl1nd3d_m3_w17h_5c13nc3}.

[Web 362pts (solved by 443 team)]Buckets

Checkout my s3 bucket website! http://tamuctf.s3-website-us-west-2.amazonaws.com/

Difficulty: easy

Guessing that this bucket has a permission problem, I digged the bucket using aws-cli like below.

$ aws s3 ls s3://tamuctf             
                            PRE Animals/
                            PRE Cats/
                            PRE Dogs/
 2019-02-20 02:06:49     124222 doggos3.jpg
 2019-02-20 02:06:49        632 index.html
 
$  aws s3 ls s3://tamuctf/Dogs/
                            PRE CC2B70BD238F48BE29D8F0D42B170127/
 2019-02-20 02:06:49       8120 beaglepup.jpeg
 2019-02-20 02:06:49        919 pup.html
 2019-02-20 02:06:49       6305 puphalloween.jpeg
 2019-02-20 02:06:49       7666 pupnerd.jpeg
 2019-02-20 02:06:49      17666 pupnerd2.webp
 2019-02-20 02:06:49     165653 pups.jpg

I met a very suspicious directiory name CC2B70BD238F48BE29D8F0D42B170127, so I digged deeper and reached to the flag.txt. To get the flag I visited to http://tamuctf.s3-website-us-west-2.amazonaws.com/Dogs/CC2B70BD238F48BE29D8F0D42B170127/CBD2DD691D3DB1EBF96B283BDC8FD9A1/flag.txt from the browser. The flag was flag{W0W_S3_BAD_PERMISSIONS}.

$ aws s3 ls s3://tamuctf/Dogs/CC2B70BD238F48BE29D8F0D42B170127/CBD2DD691D3DB1EBF96B283BDC8FD9A1/
 2019-02-20 02:06:51         28 flag.txt

[Web 478pts (solved by 177 team)]Bird Box Challenge

description:

http://web2.tamuctf.com

We've got Aggies, Trucks, and Eggs!

Difficulty: hard

There was a simple search page, however, it returned Our search isn't THAT good... message against to our query. ptr-yudai discovered the word union was repelled. But as I surveyed, I found /*!0000union*/ was not repelled. For example, we got test by the query http://web2.tamuctf.com/Search.php?Search=test' /*!00000union*/ select 'test. I revealed some curious behavious as I tried some queries.

  • There was only one user-defined table whose name is Search
  • There was only one column in Search, whose name is items
  • There were three rows in items: Aggies, Trucks and Eggs

These pieces of information didn't make me close to the flag. In fact, the flag was hidden in the user name, therefore the query http://web2.tamuctf.com/Search.php?Search=test' /*!00000union*/ select user() from Search where 'x'='x showed us the flag: gigem{w3_4r3_th3_4ggi3s}