NTFSM
I'm not here to tell you how to do your job or anything, given that you are a top notch computer scientist who has solved four challenges already, but NTFS is in the filename. Maybe, I don't know, run it in windows on an NTFS file system?
Overview
We are provided with a PE file ntfs.exe. Analyzing the binary in IDA reveals that the binary has been stripped and obfuscated with excessive jump instructions. IDA's auto analysis won't be of much help here, so we can terminate it with Analysis(0) in IDC.
Luckily, the strings in the binary are not obfuscated. We find an xref to the string "correct!" in the function 0x014000C0B0, which I'll rename main. Unfortunately, this function is too big to decompile, so we will have to analyze the disassembly.

The main function first calls sub_140002725 with various strings. This is probably some sort of initialization function, but at this point we're not too sure what exactly it does. We'll use dynamic analysis to dig deeper later.
The string values also suggest that the program is implementing a Finite State Machine (FSM), which is also hinted at by the name of the challenge.

After a few obfuscated function calls, we observe a pair of comparisons between stack variables and the value 0x10. If both variables equal 16, then the correct! message will be printed. We can thus guess that 16 might be the number of characters in the input, or perhaps the number of stages we need to pass.

This is further confirmed by the string input 16 characters, along with a strlen result that's compared with 16.

So let's input a 16 character password and see what happens!
Dynamic analysis
After starting up procmon and running .\ntfsm.exe 0123456789ABCDEF, we observe that the binary seems to be creating new files to store the FSM state and other parameters:

However, these files are nowhere to be found, at least in File Explorer:

That's because ntfsm.exe:input is not a file, but an Alternate Data Stream of the ntfsm.exe file. Luckily, we can use notepad++ with the hexdump plugin to read the contents of these streams:

From the procmon logs, we also observe that the ntfsm.exe process executes itself 16 times, while also executing a command to display a message box:

This implies that the input is probably processed character by character, and there are no early returns if an input character fails the check.
Unfortunately, there's not much else we can glean from dynamic analysis right now.
A huge jumptable
Scrolling further down the main function, things start to get interesting:

First, a global variable, interesting_var is read and compared to 90780.
It is then used to determine which branch of a 65535 case jumptable is executed.
Since interesting_var is initialized to zero, let's start from the first branch in the jumptable:

The first part of this code section isn't very interesting. The rdtsc instruction simply reads the timestamp counter. The program measures the time taken to execute a few simple instructions, then checks that the elapsed time is less than 313333337. This is probably some kind of antidebugging or anti-sandbox mechanism, and isn't part of the password checker.
Next comes something more interesting:

Using a debugger, we can observe that [rsp+0x30] holds the first byte of our input. This value is then compared against various characters. Control then flows into different branches depending on which character is matched. Luckily for us, this section is completely unobfuscated and it's pretty easy to see what's going on.
Each of the branches are nearly identical, differing only in the value stored into [rsp+58D30h]. This is probably the value of interesting_var for the next run. The value of [rsp+58AB8h] is then incremented, thus functioning as a counter/index into the input string.
To confirm this, we can change the first character of our input to J, then observe the contents of the alternate data streams just before the second ntfsm.exe is spawned:

As expected, the position has been incremented to 1, and the state (interesting_var) is set to 2.
Recall that we want interesting_var to equal 90780.
Thus, we will need to find a mov qword ptr [rsp+58D30h], 90780 instruction. Since the binary is quite large, I decided to search for the byte encoding of the instruction instead:
from pwn import *
data = open(r".\ntfsm.exe", "rb").read()
target = b'H\xc7\x84$0\x8d\x05\x00' + p32(90780)
print(hex(data.find(target)+0x140000c00))
# Result: 0x14018ca38This brings us to branch 57775, which indeed sets interesting_var to 90780.

Note that the only valid input character in branch 57775 is Q. Thus, we know that the correct password must end with Q.
We can now repeat this process to find which branch will bring us to 57775, and what the corresponding input character should be. After repeating this 14 more times, we should be able to find the right password:
password = "iqg0nSeCHnOMPm2Q"
path = [0, 1, 5, 11, 25, 53, 114, 234, 468, 930, 1824, 3621, 7221, 14397, 28807, 57775, 90780]Running the program with the correct password reveals the flag:

It is not known if there is a meaning behind the password, or if it is just random alphanumeric text.