Sunday, February 9, 2020

Holiday Hack 2019 - Burp

This section will help with Objective 9 and the Holiday Hack Trail Terminal as well as other challenges.

Install Burp (only if it's not already installed.  I believe Community Edition is included in Kali Linux.)  Installation isn't that difficult.  You can find out how here:  https://portswigger.net/burp/releases/professional-community-2020-1?requestededition=community



I'm using a NetWars VM that I had on hand since it's already on there.  These directions are for some Linux builds.  It's much easier in Windows.

If you believe it's already installed, but don't know where it is, in a Linux terminal type

which burp

and that should find the executable as long as it's mapped to the path.  If it's not mapped to the path, try:

find / -iname burp 2>/dev/null

Linux will output paths like:

/root/.java/userPrefs/burp
/pentest/exploitation/burp


Navigate into the directory

cd /pentest/exploitation/burp


list the files in the directory so you can see if burp is in here.
 
ls

 
it will output the files in this directory.  Burp will be something like burp.sh

Run it

./burp.sh &

As long as Burp is allowed to execute.  The Burp GUI will load.  If it doesn't, check to be sure that Burp is allowed to execute.

ls -l | grep burp.sh

Look at the permissions on the left hand side, it should allow the user you're using to execute.  If not, try:

chmod u+x burp.sh

Try the following command again:

./burp.sh &

Now the Burp GUI should launch.  I remember the first time I launched Burp - it's a bit of a tabbed mess.  You'll get used to it.  Lolz  If I remember correctly, you'll get popups asking about starting a project - just start a new project - with Community Edition, it will not save the changes after you close Burp, so keep that in mind.



If this is your first time running Burp, ensure that your browser has Burp configured as the proxy on port 8080 (or whatever port floats your boat.  Point being that Burp and the browser have to know the port and that Burp is the proxy.  So the port has to match.)
Click the Proxy Tab.  Click the Options Tab. Under Proxy Listeners, by default it is set to 127.0.0.1 port 8080.  Make sure “Running" is checked.  If you’d like to change the port, click on the IP, click Edit, and change whatever settings you fancy.  Just know it isn't a good idea to change things without understanding what they do.



Now configure the browser to use Burp as a proxy.  This can be done multiple ways.  This can be done natively in the browser, which is a pain if you want use multiple proxies, or not use a proxy at all.  Or you can install an extension that can switch between proxies or not use them at all, but, either way works.  

For Firefox, to configure a proxy natively, click the 3 Lines on the top right hand side, select preferences, then Click on General on the left hand side.  In the right hand frame, scroll all the way down to the section labeled Network Settings.  Click on the Settings button on the bottom right hand side.



Check the Manual proxy configuration and configure each protocol that you'd like to use the proxy with the loopback (127.0.0.1) IP and port 8080.  note, your screen may look different than mine because I'm using a Proxy Switcher extension in Firefox.  Don't worry about the SOCKS host for now.  Leave it blank.  Click on OK.

 
Now test to be sure that Burp is getting the traffic.  Surf to google.com.  if you get an error, it may be because your browser doesn’t trust Burp's certificate.  So, you have to configure the browser to trust Burp.  Go to http://burp in the browser. 


The CA Certificate phrase on the right is a link to download Burp’s certificate.  Click on the link and download the certificate  If you get a popup asking what you’d like to do with the certificate file, Save it.  Keep note of where you put it.

In Firefox, it’s the 3 Lines on the top right hand side, preferences, then Click on Privacy and Security on the left hand side.  In the right hand frame, scroll all the way down to the section labeled Certificates  Click on the View Certificates button on the bottom right hand side.



You should now see a Certificate Manager screen.  Click the Authorities tab.  Click on the Import button at the bottom of this screen.  It should open a screen that is titled, “Select File containing CA certificate(s) to import”.  Navigate to where you saved the Burp certificate.  Click on the certificate.  Click Open.  You should get a notification that the certificate was successfully imported into Firefox.



Test to see if Burp can see the traffic.  Surf to www.google.com in the browser. Check Burp to see if you can see the traffic.  If you have issues, Burp has decent documentation for some issues.  https://support.portswigger.net/customer/portal/topics/718317-installing-and-configuring-burp/articles.  Burp is able to see the traffic.  You can tell because in the Target tab, Site Map tab, it's populated with web traffic, including www.google.com.  If Burp couldn't see the traffic, it would be empty.



This next part is important to avoid attacking unintended targets.  Click on the Target tab, Then Click on Scope tab.  Under Target Scope, Click the Add button.  You should see a popup titled “Add prefix for in-scope URLs”.  Type the url in the “Prefix" text box.  Click ok.  You should now see the url in the Target Scope.



SANS Holiday Hack 2019 - Objective 12: Filter Out Poisoned Sources of Weather Data

Objective 12:  Filter Out Poisoned Sources of Weather Data

Use the data supplied in the Zeek Json logs to identify the IP addresses of attackers poisoning Santa’s Flight Mapping Software.  The hints are given by Wunorse Openslae, who is in the Sleigh Room.  The link for the zeek logs is this:  https://downloads.elfu.org/http.log.gz.  The link for the Flight Mapping Software is:  https://srf.elfu.org/.  The links for the hints are:  https://pen-testing.sans.org/blog/2019/12/03/parsing-zeek-json-logs-with-jq-2 and https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion, https://www.owasp.org/index.php/Cross-site_Scripting_(XSS), https://en.wikipedia.org/wiki/Shellshock_(software_bug), and https://www.owasp.org/index.php/SQL_Injection.


I couldn’t get the syntax to work that was given in the SANS Pen Testing Blog, so I did this:  cat http.log | jq .[]| grep host.  It's not the prettiest, but it works.

To be honest, I didn't consult the links.  I've done these challenges for 5 years now.  Also, in my day job, I look at logs, so I see plenty of attacks.  At first, I did long tail analysis.  What that means is that I searched for the outliers in the hosts, uris, username, and user_agent fields. cat http.log | jq .[] | grep host | sort | uniq | sort -nr.  There was one misspelled host that looked suspicious that was related to some attacks.  ssrf.elfu.org.  There were many user agents that were misspelled or had other typos, but keep in mind that some of these were related to scans - like the kind used in Nessus scans, so they weren't necessarily bad traffic.  So, obviously, long tail analysis did not find all the bad traffic, but it was still helpful.  I had to look a little further than just the outliers.  I thought I'd found the 100 IPs that I needed.

After finding all the IPs I thought were malicious, I tried to login to srf.elu.org, but I didn't have the credentials.  Then I remembered the document that I decrypted in Objective 10- the credentials were mentioned in the Sleigh Router Finder document.  It said that the credentials were in the readme on the laboratory's git repository.  Also, Kent Tinseltooth said that it was running on default creds in the IP Tables Terminal.  Having read many a Gihub page, I remembered that there is usually a README.md file.  I also saw this in the traffic in the zeek logs with the attacker IPs.  So, I navigated to srf.elfu.org/README.md, got the creds, and used them to login.  Unfortunately, the 100 IPs that I'd gotten were not correct.  So, I tried a different tactic.

After finding ~62 known bad IPs because they were trying LFI, SQLi, XSS, and Shell Shock, I used those to pivot based on the user agent that they were using.  This was tricky.  Some of the user agents were the same as the attacker's user agents, but they weren’t bad IPs, so I had to distinguish the bad traffic from the good.  I found a pattern.  Most of the attacks only used 1-2 IPs per user agent.   Any more than that, and it was probably ok traffic. 

Then, I gave the firewall a comma-separated list of the bad IDs and got a RID.  I would've preferred to whitelist known good IPs instead of trying to blacklist the bad IPs, but the default 0.0.0.0/0.0.0.0 seems to always want to be Default Allow.  

The RID seems to be the dates that Real Genius and Mary Poppins were released.  

Really liked the end credits this year.  Everybody wants to rule the world. :)

SANS Holiday Hack 2019 - Objective 11: Open the Sleigh House Door

Another 5/5 Difficulty.  I wouldn't say that this is difficult, just time consuming.  If you're familiar with Web Developer Tools, this should be a breeze for the most part.  This challenge is located in the Student Union.  Steam Tunnels, use them to get here.  If not those, start out at the train station, go north through the Quad, past the spinning gift, and to the Student Union.  Enter the right door.  Go to the right side of the room.  Shinny will be guarding the door.  Note:  He won't mention the crate until you’ve solved the first set of challenges.  Kent Tinseltooth, located in the same room gives hints.


Note:  Codes are different each running, so mine won't match yours. 

I'm using Firefox, because I prefer the Dev Tools in Firefox.  Other browsers would work, but may not match these directions.

Also note, These locks are kind of opposite of what you'd expect.  Green means locked.  Red means unlocked. 
Overall goal:  "I locked the crate with the villain's name inside.  Can you get it out?"
First Lock:  "You don't need a clever riddle to open the the console and scroll a little."


Click on 3 Lines at the top right hand side of the browser window, Click on "Web Developer”, Click on Web Console to display the Console at the bottom of the screen. 



Scroll to the top of the console window.  First code is given in a green box.


Lock 2:  Some codes are hard to spy, perhaps they will show up on pulp with dye. 


For this one, there is a div section that is marked as display: none.  Right click on the lock, Click Inspect Element, and look for divs that have display marked as none.



Lock 3:  The code is still unknown, it was fetched but never shown. 


Click on the Network Tab in Developer Tools.  There will be a listing of traffic.  Click on cause to sort according to type.  Look a the causes labeled fetch.  One will display an image with a code.

Lock 4:  Where might we keep the things we forage?  Yes, of course:  Local barrels!
  

Click on Storage Tab.  Expand Local Storage.  Look for barrels on the right and the code.


Lock 5:  Did you notice the code in the title?  It may very well prove vital. 


There are multiple ways to solve this one.  One way is to click on the Inspector tab, Scroll all the way to the top, Expand <head>, expand <title>, and the code will be there.

Lock 6:  In order for this hologram to be effective, it may be necessary to increase your perspective. 


Right click on the hologram, Inspect Element, Look for an attribute labeled perspective.  Increase it by a lot.


Lock 7:  The font you’re seeing is pretty slick, but his lock's code was my first pick.


This is another one where there  is more than one way to solve it.  One of the easy ways is to look in Inspector, scroll to the top, expand head, then expand style.  It will be in there.


Lock 8: In the event that the .eggs go bad, you must figure out who will be sad.  


Search for .eggs in the html, then click on the span class event button, then expand spoil.


Lock 9:  This next code will be unreacted, but only when all the chakras are active.  


Right click, inspect element, look for chakras and make sure that the pseudo classes are active for each one.  I‘m not sure why, but I could only activate one at a time.  I just did so and copied the code each piece at a time.   I don't know much about this.  7FO7AELY


Lock 10:  Oh, no!  This lock's out of commission!  Pop off the cover and locate what's missing.  As a side note - this is my favorite lock out of these. :D


Right Click>Inspect Element.  You will see a div class called cover.  Uncheck the background to "pop it open”  This is the first reason this is my fav lock.  There is a visible change.


The lock now appears as a circuit board.  See the code on the bottom right hand side?  That's the code we need.  Type in the code into the lock and try to click unlock.  Doesn't seem to do anything.  So, we need to find what's missing. 

Look at the Console, though.  You will see an error.  Macroni missing.  Another side note:  I solved this one by luck.  I happened to notice another button with macaroni.


Copy the macaroni from the other button and paste it under lock 11. The following is another reason this is my favorite lock.  If you look at the lock, you can see a visible change. :)  See the macaroni? Lolz

Try the code an unlock again.  It will say that it's missing a cotton swap in the console. 

Add another div class, except this time, make it component swab.  Try the code and button again.


Now it will say that it's missing a gnome in the console.  I'm not including the pic because it looks like the other two, except it says gnome instead of macaroni and swab.

Once again, add another div class, except this time, make it component gnome. 


The Objective Answer:  The villain is the Tooth Fairy.


From what I understand, there is a scoreboard.  If you write a script for this challenge and solve it in a very short period of time, it keeps track of it.  I imagine that this could help SANS and/or Counter Hack to determine a winner for the Holiday Hack Challenge more easily, but I'm not sure that they actually used this to determine who won.  I don't work for them, so I don't know what exactly goes into determining who wins.  I'm hoping that whichever team won shows what they did to solve this one in like 8 seconds or something.  It would be interesting to learn how to write a script like that.

Sunday, February 2, 2020

SANS Holiday Hack 2019 - Objective 10: Recover Cleartext Document

Objective 10:  Recover Cleartext Document

This objective asks us to decrypt an encrypted document.  Holly Evergreen gives the hint to solve this one.  Here is the link that she gives.  https://www.youtube.com/watch?v=obJdpKDpFBA&feature=youtu.be

At first, this one seems like it would be extremely difficult because it has a five tree out of five tree difficulty rating.  I think that that mostly comes from our heads though.  We think something will be difficult, so it is difficult.  If you watch Ron Bowes’ talk, Reverse Engineering, The Easy Way, you see hints in there that makes it not so bad.  It's just a way of thinking that most people aren't accustomed to.  First step, download the software and use it like a person normally would - encrypt and decrypt a file.  Get a feel for how it works.  A notable feature is that this encryption software sends a key to a 3rd party that stores the key (AKA key escrow).  Then the user is given a guid in which they can use to retrieve the key.  One thing that sticks out is that it has an option that is not recommended, which is to send the traffic over HTTP with the insecure option.  So, one could use something like Wireshark or tcpdump  to record the traffic and see it.  This is good for a reverse engineer or someone troubleshooting an issue because they can better understand how it works.  This is not good for every day use because it can show the key being sent as well as give clues about how to retrieve or reverse engineer keys without sniffing traffic.  https://en.wikipedia.org/wiki/Key_escrow



Notice, in the following image, that when the insecure flag is used that the key is sent in clear text, and the GUID is sent back to the user in cleartext as well, making this insecure flag dangerous.  Not only does this give attackers this one key, but it gives clues to the inner working of the application as well.



Already we learn a little bit about the application.  The key is 16 hexadecimal characters long.  1 hexadecimal character is 4 bits (AKA a nibble).  2 hexadecimal characters is 4 + 4 = 8 bits.  A byte is 8 bits. 16 hexadecimal digits/2 hexadecimal digits per byte = 8 bytes.  So, the key is 8 bytes long.  Usually DES has an 8 byte key.  So, we can hypothesize that the encryption is DES.  Also, look at the seed.  It looks like a UNIX timestamp.  Interesting that in the question, they mention a timeframe that they believe it was encrypted.

After normal functionality has been observed, including watching the insecure version in Wireshark, use a program like IDA to examine the elfscrow.exe binary.  It's fairly easy to use.  Just open it, Click on New, Choose your executable, click open.  Usually the default information is ok.  In the challenge description, we are given debugging symbols that may be helpful.  If you have IDA, the elfscrow binary, and the debugging symbols in the same directory, and you try to load the executable into IDA Pro, it will ask you if you want to load the debugging symbols with it as well.  Click on yes.





This program, like basically any other program has a main function.  I don't have an extensive knowledge of all the terminology involved in programming, however I do remember a couple of things.  The main function can call other functions.  Code execution isn't necessary linear. when you’re reading assembly or other code.  The application will start in main, go to the first line, and go in sequential order in main, however, it may have to jump to other functions.  So you can't always read the code top to bottom.  When it calls another function, you'll see something like call 0x1234.  That means you need to find the function at address 0x1234 to see what that does.  When it's done with 0x1234, it'll jump back to the main function after the call statement and follow in sequential order until it comes across another function, jump, or loop.  Keep in mind, the other functions can call other functions, have jumps, or loops as well.  But it's the same idea.  It goes in sequential order unless it sees something like a jump or a loop…  Thankfully, we don’t have to be assembly gurus to solve this challenge.  Ron says it's the easy way.  Note, even if we don't understand all of it, we can still see the insecure flag I mentioned earlier.  So we can read some of it.  That's enough to make educated guesses about what is going on.  If that fails, then we can Google anything we don't know.




On the left hand side, you should be able to see a listing for the functions.  If you don’t, it might be because the View is set to a different setting than normal.  Go to View, Open Subviews, then choose Functions to see them.  Notice the interesting functions?  “super_secure_srand” which is expecting to get an integer  (probably the seed), then “super_secure_random"(which expects nothing), “generate_key", and “time".  Also, note the store key are retrieve key which are the web functions that we saw earlier when we ran the application.  Double Clicking on any of those functions “jumps" to that function in the Disassembly View  Again, if you don’t see the Disassembly, you probably need to adjust the View.  Same directions as getting the Functions, except, choosing the Disassembly view option instead.  Below, the super secure function is shown.



The most interesting thing to note is how the key is generated, so we'll look at that first.  The most important thing to note here is that the time function is called to get the current time.  Then it's pushed onto the stack and is used as the seed.  The seed is then sent to super_secure_srand.  See how that function needs an integer (int)?  The integer given to it is the seed.


Logically the next place to look would be super_secure_srand.  The srand function is used to set the starting point for producing a series of pseudo-random integers.  If the application didn’t call this, it would be as it started at one, so that may may it predictable.  So, the application is starting it at whatever the current time is.  https://www.geeksforgeeks.org/rand-and-srand-in-ccpp/  Not really much of a reason to look at the assembly on srand, because we now know what it does.  Only thing interesting about this one is that it calls super_secure_random.  This is where things get interesting.  Note that the values below are in hex, however, they can be converted to decimal by right clicking on them and selecting the base10 option.  It is the icon on the menu with a number 10 in it.  There is an H next to the number to show it's currently in HEX.  The image of the right is converted to base10. Those are the constants that Ron mentions in his video that we need to lookup.



If you Google those constants, you find that it's the constants for the Linear Congruential Generator that creates the random numbers for the key.  Considering that Ron has a solution skeleton outlining a potential way to decrypt files that only needs an encryption algorithm and the random number generator that is written in Ruby in the github page that he released with the video, https://tinyurl.com/kringlecon-crypto, it might be wise to grab the ruby version of this Linear Congruential Generator from here:  https://rosettacode.org/wiki/Linear_congruential_generator.


Below is Ron's solution skeleton.  Notice that it says exactly what to put where.  Here is the link:  https://github.com/CounterHack/reversing-crypto-talk-public/blob/master/demoes/demo7%20-%20putting%20it%20all%20together/demo7%20-%20solution%20skeleton.rb  The code is continued on the next page. I added comments to hopefully make it more clear.

require 'openssl'

#key length?  We know it's 8 bytes from executing the program and looking at the key length.
KEY_LENGTH = 8

#A function that generates the key (pseudo random number) if it's given a seed as a starting point.
def generate_key(seed)
key = “"
#the following is a loop that creates each character of the key.  So basically it says, from character one, all the way up to the ending character (the 8th character),
#generate a random number.

1.upto(KEY_LENGTH) do
#Below we have to generate the random number with the PRNG - this is where we add the code with the constants we Googled.
key += (seed & 0x0FF).chr
end

#Return the full 8 byte key to the calling function
return key
end

#This function decrypts the data using the key.
def decrypt(data, key)
#What cipher is it?  We already know.  DES.
c = OpenSSL::Cipher::ALG.new(ALG_DETAILS)
c.decrypt
c.key = key
#He mentioned in his talk about the pattern of the blocks of each cipher.  One hint people may miss is that padding may be necessary.  It should go here.
#Return the decrypted data.  Note, he’s returning a string, not a file.  We'll have to figure out how to decrypt a file.

return (c.update(data) + c.final())
end
#This function shows how to use this ruby script.  Give it data, and a seed and it'll decrypt the data into a string.
if(!ARGV[1])
puts("Usage: ruby ./solution.rb <hex data> <seed>")
exit
end

#Tells ruby to expect HEX Data
data = [ARGV[0]].pack('H*')

#Tells ruby to convert the string that the user types to an integer.  The key function is expecting an integer.
seed = ARGV[1].to_i

#Call the generate_key function, give it the seed, so it will generate a key and return it.

key = generate_key(seed)

#Display the key to the screen
puts("Generated key: #{key.unpack(‘H*’)}")

#Display the decrypted data as a string.
puts "Decrypted -> " + decrypt(data, key)

This is how I solved it.  Note, I re-purposed some of Ron's code.  I didn't know Ruby, well, here's one way to do it:  Reusing code and Googling.  I found how to decrypt DES in Ruby in these articles.  https://stackoverflow.com/questions/26493253/des-decryption-in-ruby  https://stackoverflow.com/questions/56741153/how-do-i-decrypt-files-that-are-encrypted-using-des-command-in-ruby  I narrowed the time period down by looking at the creation date of the (elfscrow) encryption executable.  Obviously you can't encrypt the file before the encryption software was made.  So, that narrowed it down to between 8:20:50 PM UTC and 9:00 PM UTC.  Secondly, I generated the seeds using  Powershell and pulled them in at the top of this code into an array.  I used a loop to try each seed and create a file that is potentially decrypted.  There are more efficient ways.  There were quite a few files to sift through.  Thankfully file -i /path/to/files/* | grep “application/pdf” will bring up the decrypted file.

require 'openssl'

#Read the file that I created containing the seeds into an array
arr = []
file_lines = File.readlines(“~/Desktop/narrowseeds.txt")
file_lines.each do |line|
    arr << line.strip
end

#Key Length is 8 - it's DES - Figured this out from key length.
KEY_LENGTH = 8

#Generate the Key with the Linear Congruential Generator code, because that's how the program does it.
def generate_key(seed)
  key = ""
  1.upto(KEY_LENGTH) do
    key += ((((seed = 214013 * seed + 2531011) >> 16) & 0x7fff) &0x0FF).chr
  end
  return key
end

def decrypt(key,number)
  #Algorithm is just plain DES.
  c = OpenSSL::Cipher::DES.new()
  c.decrypt
  c.key = key
  #to figure out that the padding was needed, I Googled an error I was getting.  Ron explains it in the video, but I missed it the first time watching the video.
  c.padding = 0
      #Found this decryption routine by Googling how to decrypt files encrypted with DES in ruby
      file=File.open("/root/Desktop/decrypt_attempts/#{key.unpack('H*')}.pdf",’wb') do |outf|
          decrypted = c.update(File.read(‘ElfUResearchLabsSuperSledOMaticQuickStartGuideV1.2.pdf.enc')) + c.final
          outf.write(decrypted)
      end
end
#show how to use this ruby program
if(!ARGV[1])
  puts("Usage: ruby ./solution.rb <hex data> <seed>")
  exit
end

#initialize counter
number = 0
#For each seed in the array, do the following
for seed in arr do
    #Add one to the counter
    number = number + 1
    #display the seed being tested
    puts(seed)
    #generate the key from this seed
    key = generate_key(seed.to_i)
    #display the potential key
    puts("Generated key: #{key.unpack(‘H*')}")
   #I was going to use number to create different filenames with each key, but decided to use the hex instead, so I knew what the key was.  Unfortunately the method I used printed  
    out [“"] as well for the file name.  Linux didn’t care though, still saved them to disk.

    decrypt(key,number)
end

Here’s how I generated the seeds in Powershell.  Note, I'm changing my local time to UTC.

#initialize the variable.
$unixTime = $null
#if there's an error, keep going without bugging me about it. (Some errors will still show up, but they are less likely.)
$ErrorActionPreference = “SilentlyContinue"
#initialize the seeds array
$seeds = @()
#Nested loops to create timestamps for all the minutes and seconds.  Didn't need an hour one because we narrowed it down to less than an hour.  Could have been narrowed down more, but this is good enough.
    for($m=0; $m -lt 60; $m++){
        for($s=0; $s -lt 60; $s++){
            #This is taking into account if the numbers are less than 10 for both seconds and minutes.
            if($s -lt 10 -and $m -lt 10){
                #Get my local time, change it to UTC, then format it in unixTime format.  Inner parentheses are resolved, first, then the next one out, and then the last.
                $unixTime = [long] (Get-Date -Date ((Get-Date "12/6/2019 14:0$m:0$s").ToUniversalTime()) -UFormat %s)
            }
           #This is taking into account if the numbers are less than 10 for seconds and greater than 9 for minutes.
            if($s -lt 10 -and $m -gt 9){
                $unixTime = [long] (Get-Date -Date ((Get-Date "12/6/2019 14:$m:0$s").ToUniversalTime()) -UFormat %s)
            }
          #This is taking into account if the numbers are less than 10 for minutes and greater than 9 for seconds.
            if($s -gt 9 -and $m -lt 10){
                $unixTime = [long] (Get-Date -Date ((Get-Date "12/6/2019 14:0$m`:$s").ToUniversalTime()) -UFormat %s)
            }
            else{
                #if minutes and seconds are both greater than 10, do the following.
                $unixTime = [long] (Get-Date -Date ((Get-Date "12/6/2019 14`:$m`:$s").ToUniversalTime()) -UFormat %s)
            }
          #Add each timestamp to the array.
            $seeds += $unixTime
        }
    }
#Create a file containing all the seeds.  Make it ASCII because Linux barfs on Unicode at times.
$seeds | Out-File -Encoding ASCII narrowseeds.txt

Looks like the decrypted file contains some proprietary information  The answer to this objective is Machine Learning Sleigh Route Finder.