I Smell Packets


“Add It All Together” Packet Challenge Reloaded
August 7, 2010, 1:29 am
Filed under: Packet Challenge

The file in the previous pcap that was posted got corrupted. Here is a new pcap and what you now need to do to win.

To win this challenge add the following numbers together:

  • The 8th byte of the IP header of the 1st packet
  • The value of the ACK flag in the 4th packet
  • The TTL of the 8th packet (in hex)
  • The number of bytes in the 8th ip datagram
  • The value of Last Octet of the Destination IP address of the 10th packet (in binary)
  • The value of the don’t frag bit in the 12th packet

The capture file can be downloaded from the I Smell Packets Google group located at the following URL:

http://groups.google.com/group/ismellpackets

The new filename is:

12b.pcap

Best explanation wins. Send you answers to chris (dot) christianson (at) gmail (dot) com.

Bookmark and Share



“Add It All Together” Packet Challenge
August 6, 2010, 2:17 pm
Filed under: Packet Challenge

After a long hiatus were back with another challenge. Take a look at the following packet capture and find “the phrase that pays.” Well, it doesn’t really pay but you know what I mean.

To win this challenge add the following numbers together:

  • The 8th byte of the IP header of the 1st packet
  • The value of the ACK flag in the 4th packet
  • The TTL of the 6th packet (in hex)
  • The number of bytes in the 6th ip datagram
  • The value of Last Octet of the Destination IP address of the 10th packet (in binary)
  • The value of the don’t frag bit in the 12th packet

The capture file can be downloaded from the I Smell Packets Google group located at the following URL:

http://groups.google.com/group/ismellpackets

The filename is:

12.pcap

Best explanation wins. Send you answers to chris (dot) christianson (at) gmail (dot) com.

Bookmark and Share



Winning Solution to “Name That Tune” – Packet Challenge
March 2, 2010, 3:12 pm
Filed under: 802.11, cowpatty, Wireshark, wpa

The winner of the “Name that Tune” – Packet Challenge is Jon Wolhberg (@jonw18 on Twitter) Here’s Jon’s solution:

Jon writes:

Here is my answer to the latest packet challenge and how I got to it.

The song is Never Gonna Give You Up by Rick Astley

The first thing I did was to open the pcap in wireshark and just look around to see if anything sticks out. What I noticed right away were all of the beacon frames which means we are dealing with some wireless traffic. Since the beacon frame has the name of the network, I decided to look at one of the packets and identify the SSID — in this case the name is “Linksys”.

I also noticed that the protocol being used is 802.11 which means there is some authentication to the network and probably some encryption surrounding the packets. I decided to look for the packets the provided the authentication in hopes of cracking the password. After some trial and error, in Wireshark, I filtered on eapol to see if eap over lan was the method for authentication. Low and behold I got 8 packets, that have the authentication handshake (these can be seen in packets 137,139-143,145,148).

Now that I have the SSID and I know I have a capture file with the authentication handshake, I need to crack the password. For this I used Backtrack4. After loading Backtrack I decided to use the program cowpatty. In order for this to work I need the capture file, the SSID, and a dictionary file, which cowpatty comes with (yes there are faster ways). The command I used was ./cowpatty -f dict -r 11.pcap -s Linksys (-f = dictionary file, -r = capture file, -s = SSID). After a few seconds the password had been cracked. The password is 12345678

Now that I have to the password, I need to decrypt the packets. I went back to wireshark with the packet capture opened and went to edit -> preferences > IEEE 802.11. You then need to enter the wpa password in Key 1 exactly as the following: wpa-pwd:12345678:Linksys
You also have to check the box that says “enable decryption”.

Once this is done the packets will become decrypted. I then saw an IP address I had not seen before (209.237.235.166). Not recognizing this address, I did a NSlookup to see what it resolved to, and it came back to lala.com, a music site. I also noticed that the site was sending a lot of traffic to the on port 1420 to the client machine. Wondering what that was, in wireshark I clicked on one of the packets and clicked follow tcp stream. It was there that I saw that this is a web request and in the header it revealed this: Content-Type: audio/x-mpeg. This was the song we need to identify. In the tcp stream I saved all traffic from the server to the client. I saved this as song.mp3

Figuring this was a media file I ran the file command to verify. To my surprise I got the response: filetype ascii data. I then remembered that the http headers are also downloaded, so we need to remove them. I could have used a hex editor but found a good perl program at
http://blog.rootshell.be/2009/04/15/forensics-reconstructing-data-from-pcap-files/

The program strips out the http headers. I then ran the file command again and got this MPEG ADTS, layer III, v1, 128 kbps, 44.1 kHz, Stereo. Now that I have the file I just need to listen to it. After listening for a couple of seconds, I couldn’t remeber the song title. I open my iPhone and loaded the Shazam app that identifies songs…. and that is how I got my answer.

Chris continues:

Congrats Jon! Well done. Thanks to everyone who sent in entries. Honorable mentions go out to Travis Lee for his entry, he used Aircrack-ng to crack the WPA key. And Andy and Fab who used this Top 20 Password List to crack the key:

Imperva reveals top 20 passwords

Look for another challenge coming soon.


Bookmark and Share



“Name That Tune” – Packet Challenge
February 18, 2010, 3:40 pm
Filed under: Packet Challenge

Here is another little challenge for you. Take a look at the following packet capture and name that tune. The capture file can be downloaded from the I Smell Packets Google group located at the following URL:

http://groups.google.com/group/ismellpackets

The filename is:

11.pcap

Best explanation wins. Send your answers to chris (dot) christianson (at) gmail (dot) com.


Bookmark and Share



packetchallenge.com
January 21, 2010, 8:48 pm
Filed under: packetchallenge.com

I just wanted to take a moment to thank Ariany Mizrahi (@codemonkii) for giving me the packetchallenge.com domain name. He sent me a tweet last week and offered me the domain after he saw the site. Though it’s not worth a lot money or anything, people being willing to give anything away, without asking for anything in return, nowadays is rare. Thanks Ari!

Who knows? Maybe the new domain name will attract even more visitors to the site.

Speaking of packet challenges, I’ll try to post a new one next week.



A Script for sshbl.org
January 21, 2010, 8:46 pm
Filed under: DenyHosts, hosts.deny, sshbl.org, sshbl.sh

Here is a simple little shell script to download the blacklist from sshbl.org and to create a hosts.deny file with it. If your unfamiliar with sshbl.org, sshbl.org maintains a blacklist, that is constantly being updated, with the IP addresses of hosts which tried to bruteforce different hosts located around the world.

sshbl.sh

#!/bin/bash
rm /tmp/base.txt
wget http://www.sshbl.org/lists/base.txt
rm /tmp/base.tmp
cat /tmp/base.txt | grep '[0-9]*[0-9]*[0-9][.][0-9]*[0-9]*[0-9][.][0-9]*[0-9]*[0-9]' | sed 's/^/sshd: /' > /tmp/base.tmp
rm /etc/hosts.deny
cp /tmp/base.tmp /etc/hosts.deny

The above script first deletes any previously downloaded blacklist and then fetches a new one. Next, it removes any previously created temporary file. This temporary file is created by the next command which performs all of the following functions: displays the blacklist, searches it for IP addresses, inserts ‘sshd: ‘ to the beginning of each line, and directs the output to a temporary file. The reason for the inserting of the ‘sshd: ‘ is that this is what is expected in the hosts.deny file. Finally, any previously hosts.deny files are deleted and the new hosts.deny file is copied to the /etc directory.

All that’s left is to schedule this script to run using cron and the entire process will is automated.

This simple script takes just a few minutes to setup. If you’re interested in doing even more to automatically block brutefore attacks against your ssh server take a look at DenyHosts located here. It’s a python script that takes this to next level.



SANS SEC567: Power Packet Crafting with Scapy Debut at Sacramento!
October 22, 2009, 2:34 pm
Filed under: SANS, scapy

I have the opportunity to teach the brand new SANS SEC567: Power Packet Crafting with Scapy course!

If you’re not familiar with Scapy, Scapy is an unbelievably powerful tool that you can use to create all sorts of different packets. If you’ve ever needed to test an IDS/IPS rule, check weather or not a firewall will block something, or test some application to see how it reacts to certain traffic (like for a penetration test for example) Scapy can make your job easier.

The course was written by Judy Novak who used to work for Sourcefire. While at Sourcefire, Judy was responsible for testing IDS/IPS solutions and used Scapy extensively for doing so. She does an excellent job of explaining everything from basics to even the more advanced techniques. The course is jammed packed full of exercises. By the end of the day I can assure you that you will be able to craft some pretty awesome packets.

This course will be having it’s debut in Sacramento. Since this is a debut, you have the opportunity to take the course for half price! How’s that for a bargain? In return, all we ask is that you provide us with some feedback.

If you’d like more information or if you’d like to sign-up, please follow the link below:

SANS: SEC567 Power Packet Crafting with Scapy Debut at Sacramento – Power Packet Crafting with Scapy



Solution to ‘What’s wrong with Smelly Widgets?’
October 20, 2009, 2:39 pm
Filed under: Packet Challenge, SANS, SQL injection, Wireshark

The winner of the “What’s wrong with Smelly Widgets packet challenge?” is . . . Arvind Doraiswamy.

Here’s Arvind’s solution.

Arvind writes:

1. A blank form with a login and a password is first displayed. The webserver is running on 192.168.94.143 and an access attempt is made from 192.168.94.144.

2. Attempt at logging in with a blank username and password is then done(Packet 9). This is insuccessful as shown in Packet 12 where a user is not allowed to login with empty credentials.

3. Packet 14 sees the user try to login with the username chris and an empty password. This too is insuccessful as shown in Packet 17 , a user must have something in the password field.

4. Packet 19 sees a third attempt at trying to login with the username chris and the password “password” . The attacker is trying out various common password combinations. This too is insuccessful as shown in Packet 22 and returns an error message of “Invalid credentials” . This means that you must enter something in both fields. So the attacker must now either find a valid combination or must try and bypass the login somehow. Well, he doesn’t have a valid combination so he decides on the latter.

5. At this point though there is another request for the home page on 192.168.94.143 from 192.168.94.1. He tries to login with the username of chris and a password of smellywidgets. This results in a successful login and displays order history. This is crucial…

6. On packet 37 we now see chris making another attempt to unsuccessfully login with username chris and password ismellpackets from the IP 192.168.94.144. This again is unsuccessful.

7. The attacker on 192.168.94.144 is now fed up and decides to try and get in without a valid username and password. On packet 42 he sends a request with username and password as follows:
username: ‘ OR 1=1–
passsword: password

This login is a success!! What happened here? Lets take a look at how a normal successful login would happen in the first place.

EXPLANATION:

A website is hosted on a webserver. A login page is part of the website. When a user enters his username and password on the website, it is accepted as input by the website form and handed over to the code for further processing. The application code now must compare what the user entered with what is already stored in the database. If it didn’t do this — well , there wouldn’t be a need for a login form at all and everyone could see everyone’s data. Now how does the application actually do this?

The application needs to ask the database whether it has entries for the input that the user gave at the login page. So if we take the example of a successful login made by chris from the IP 192.168.94.1 the application will ask the DB – “Do you have an entry for someone called chris , he’s entered a password called smellywidgets. Is this correct?” . The DB checks in its entries and says “yes that’s fine.. Chris indeed exists – allow him in”. Now the language that the application talks to the DB is called SQL – and when it asks a question – its said to be “querying” the database. So effectively the application queries the database in a language called SQL.

Now obviously there needs to be some structure to this SQL query. So while checking authentication is sends a query as follows:
SELECT username from users where ‘username’=’chris’ and ‘password’=’smellywidgets’ . SQL surrounds its userinput by single quotes, that’s part of the syntax.

The DB check the validity of the user chris , checks if his password is smellywidgets and then if it finds an entry like that, returns the username to the application. The application checks if the number of entries returned are not 0 (meaning there was a match) and then allows the user access. Great..now we know how a normal login happens. Now what happened when we typed ‘ OR 1=1– instead of chris? Again an SQL query is formed , but this time the query is as follows:
SELECT username from users where ‘username’=” OR 1=1– and ‘password’=’password’

Pay careful attention to the ” OR 1=1– . It effectively translates to .. “Please check is there is a user called ” (BLANK) OR check if 1=1 “. Huh? Now obviously there is no user called ” or BLANK in the DB but the second part 1=1 .. well that’s always going to be true ..right? 1 is always 1 and 2 is always 2 so that part will alwys be true. This means that the first part of checking the username has evaluated to TRUE and a successful message will be returned if the password is correct as well. Er..but I don’t know the password. No problem .. that’s where the — comes along.

A — in SQL means a comment , which means everything after the — is ignored by the DB engine thus resulting in the query which runs as :
SELECT username from users where ‘username’=” OR 1=1–

It didn’t matter what password I entered, the DB just checked if 1=1 which is always TRUE, returned a message to the app saying.. hey this is TRUE. Go ahead and grant access, and the application duly did so. This technique is called SQL Injection where you modify a backend SQL query using your own input and retrieve data accordingly. Now back to the challenge!!

—–

8. Packet 51 depicts a login successful message to the SQL injection request made on packet 42. Packet 53 shows each and every widget order that was placed by every user, this is clear because multiple credit card numbers are shown in the HTTP response. This has happened because the DB has returned the first entry which it found matched the user’s request – and this was the first user , who in this case was probably an admin user who could see all entries.

9.On packet 68 the user clicks the logout button and decides to logout of the application. Confirmation of his successful logout is shown in Packet 77 and 79.

10. The attacker starts another login process in Packet 81. The body of the HTTP POST request is split across so many packets because of the size of the __VIEWSTATE parameter which ASPX applications use to remember previous entries made by users in forms. This isn’t that relevant here though as of now. The request is so huge that you see the actual userinput only in packet 86 this time. This time the entry he has made is %27%3B+UPDATE+Orders+Set+Amount%3D0.01– . What does this mean now? Time for a little bit of background on what those funny characters are:
—-

EXPLANATION:
When you type a special character which isn’t alphanumeric the browser performs something called URL Encoding on it before sending it to the server. It effectively means – When you send data over the Internet , it doesn’t need to be encoded if its ASCII.. coz ASCII is an example of “WYSIWYG” (What you see is what you get). However that isn’t true of other characters like ‘ % and others – hence they are URL encoded before sending it out. A single space is encoded as %20 by the browser – hence if there’s a space in your data you must send it as a + instead. Now back to the challenge, what does this input say?
—-

11. %27%3B+UPDATE+Orders+Set+Amount%3D0.01– translates to ‘; UPDATE Orders Set Amount=0.01– . Hmm ..things are getting interesting now. If you recall how we discussed SQL before – the backend query for this translates to: SELECT username from users where ‘username’=”; UPDATE Orders Set Amount=0.01– and ‘password’=’password’ . This tells the DB to check if the username is blank and the update all entries in the Amount column in the Orders table to 0.01. Now note …this isn’t going to successfully log you in to the DB – we don’t have a 1=1 like before but the SQL query will still work. Why? Because we know that the username field is vulnerable to SQL Injection I can not only log in by bypassing authentication — I can tell the application to send any query I want executed on the remote DB. In this case its an update query — I separate the original SELECT query and the UPDATE query with a ; — The UPDATE query won’t run unless you put the ; — That’s a separator incase you want to run multiple queries (batched queries they are called in SQL). Potentially I could run more queries by just putting in a ; between each of them. Phew ..lets move on.

12. Packet 98 – shows a failed login attempt for the UPDATE query..but that’s perfectly fine. You do not need to be “logged in” to do damage with a SQL injection. All you need is an entry point. That’s why its so dangerous. Going on then..

13. Now he tries to login with the ‘ OR 1=1– input which we discussed earlier..possibly to check whether what he did with the UPDATE succeeded or not. The complete Request body is in Packet 105.

14. Perfect!! Look at Packet 121 now.. You need to look directly at 121 because Wirshark has this feature called Reassembled TCP where it basically joins all the data split across packets into 1 long bit. if you don’t want to read inside Wireshark , you can right click paket 121 in Wireshark and do a Copy — Bytes Printable text only to a text editor. You can also copy from a FollowTCPStream. Here you can clearly see that the amounts of each and every widget is now 0.01 , meaning that the UPDATE query succeeded.. even without a successful login.

15. Packet 129 sees the attacker logout again..now that he’s confirmed that the SQL Injection has worked and Packet 140 shows him the login page again.

16. Things are now getting worse on Packet 147. By following the same methodology above you can see that the payload the attacker uses this time is:
INSERT INTO Users VALUES (100,’hacker’,’sniffthis’)– . He’s creating a new user with an ID of 100 a username of hackers and a password sniffthis. Again..the SQL will succeed..but he won’t be able to login. This shows that the ‘ OR 1=1– was primarily just a test to find out whether the field was vulnerable or not, the real juicy stuff is here. The hacker should now try and login with this new account..lets see if this happens. Packet 159 BTW predictably rejects the login attempt.

17. Yes, predictable the hacker now logs in with the username of hacker and the password of sniffthis in Packet 166 and Packet 170 shows a successful response. After the test login he logs out again on Packet 172.

18. Now he starts SQL injecting again this time using a batched SQL query (remember queries split by a ; ? ) to log in successfully with a ‘ OR 1=1– as well as add a new entry with the query :
‘ OR 1=1; INSERT INTO Orders (OrderId, Item, CreditCard) SELECT UserId,Username,Password FROM users–

Now there should be a new entry in the Orders table with the values 100,hacker,sniffthis .. right at the bottom. We’ve basically retrieved the hacker’s details from the users table and Inserted them into the orders table for some reasson. Lets see why..lets look at the response.

19. Yes , just like we thought. Have a look right at the bottom of Packet 206. We see a row 100 hacker sniffthis ; meaning that the attacker managed to successfully INSERT and VIEW his results. He then successfully logs out as can be seen in Packet 236. Now what?

20. He’s placed an entry into Orders , meaning he bought stuff without paying a cent, he’s changed all order prices , now he destroys the entire users table by SQL injecting again — ‘; drop table users– . This is on Packet 248. The by now familiar Invalid Credentials message comes in on packet 266… but he’s not bothered any more. His job is done.

21. Now there’s a connection again from the other IP 192.168.94.1 . Remember the guy here successfully logged in once? Lets see what happens now. Yes, he tries again on Packet 276 with the same username and password with which he succeeded last time – Username: chris and Password: smellywidgets.

22. Disaster.. The Users table is not found…of course it won’t be – The ‘hacker’ user dropped it after he inserted a successful order. The response in packet 279 shows this error message clearly – ERROR: Failed to execute SQL command: Invalid object name ‘Users’

Maybe there will be guys who use clever scripting techniques to pull out all the data – but since the dump was just 280 packets I didn’t really spend too much time thinking on how I’d do that and stuck to good old Wireshark instead. Thnx for a nice challenge anyway though 🙂

Chris continues:

About the only thing I’d like to add to Arvind’s solution is that it’s sometimes nice to know what type of systems you’re dealing with. In this particular case, you can do this by following the TCP Stream and looking at Host Headers. Notice bold text in the following output:

GET / HTTP/1.1
Host: http://www.smellywidgets.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/8.10 (intrepid) Firefox/3.0.11
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Mon, 05 Oct 2009 17:51:57 GMT
Content-Length: 1922

Examining the above, we can see that this server appears to be running IIS 7 and ASP.NET. We can probably safely assume that this is a Windows 2008 server. Now, just because this is a new Windows 2008 server doesn’t mean that it’s immune to SQL injection. User input always needs to be sanitized. Filtering out characters like single quotes, double quotes, and semi-colons would have prevented this attack.

Just case you’re interested, this challenge was created using a Windows 2008 virtual machine, IIS, ASP.NET, Visual Web Developer 2008 Express, and SQL Server Express 2008.

Thanks to everyone for sending in all the write-ups. You all did a great job. It was really hard to choose a winner. Special shot out to Louw Smith for being the only one to mention the Beatles reference. It was also nice to have a couple of my former Sec 401:SANS Security Essentials students submit answers. You guys rock!

Speaking of Sec 401: SANS Security Essentials, I’ll be teaching it again in Sacramento, CA. January 28-30 and February 1-3. If you’re interested in attending please feel free to contact me. There are also some links on the left with more information.

That’s it for now. Again, congratulations to Arvind and thanks to everyone who sent in answers.

The following are some links to more information about this week’s challenge:

SecuriTeam – SQL Injection Walkthrough
SQL Injection Cheat Sheet
Cheat Sheets – pentestmonkey.net



‘What’s wrong with Smelly Widgets?’ – Packet Challenge
October 6, 2009, 4:07 pm
Filed under: Packet Challenge

smellywidgetslogo.jpg

Help! Something is wrong with the Smelly Widgets website. Can you find out what it is?
The capture file can be downloaded from the I Smell Packets Google group located at the following URL:

http://groups.google.com/group/ismellpackets

The filename is:

10.pcap

Best explanation wins. Send your answers to chris (dot) christianson (at) gmail (dot) com.



Winner of the Crypto Kitchen Packet Challenge
August 13, 2009, 2:25 pm
Filed under: Packet Challenge, Vigenere

The winner of the Crypto Kitchen packet challenge was David Langlands (@zerodave on twitter). The following is his write-up:

David writes:

Chris,

Please keep posting these, they’re a lot of fun. Both the easy and hard questions have the same answer “Merchandise7X” which I’d love to say I didn’t need to Google… but alas, the gods of trivia skill failed me at a critical moment. Mother Google says that it’s the secret ingredient in Coca-Cola.

The packet stream is an SMTP transaction. Reassembling the message by following the TCP stream we see that the hard message is as follows:

Message-ID: <4A65E533.8090903@i.eat.packets>
Date: Tue, 21 Jul 2009 16:56:35 +0100
From: Foody McFood <really.hungry@i.eat.packets*gt;
User-Agent: Thunderbird 2.0.0.22 (Windows/20090605)
MIME-Version: 1.0
To: newrecipe@recipes.on.line
Subject: Great new recipe
Content-Type: multipart/mixed;
boundary=”————030809040302070301000205″
This is a multi-part message in MIME format.
————–030809040302070301000205
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

Here’s that great salad dressing recipe I was talking about:

Ingredients

* 45 ml Olive Oil
* 1 Garlic Clove crushed
* 30 ml Balsamic vigenere
* 15 ml Basil shredded
* The Secret Ingredient!

Method

1. Mix together all ingredients in a jar
2. Shake well.
3. Pour over the salad.

Don’t tell anyone about the secret ingredient – discretion is the key!

Enjoy,

Foody McFood

A few things of note here, the easy file is the same message, with a different Message-ID: header. The easy message-id header stands out a bit, since most MTAs have a header that looks more closely like the hard version’s header. File that for future reference:

EASY -> Message-ID: <Pmjeyeglwfh7F@i.eat.packets>
HARD -> Message-ID: <4A65E533.8090903@i.eat.packets>

The hard pcap file also has a JPEG file which is base64 encoded. One method to decode the base64 content is:

1. Use “Follow TCP Stream” to reassemble the SMTP conversation
2. Cut and paste just the base64 text into a text file (I called mine chal9.txt), it begins with “/9j”
3. Use openssl to decode the base64 text:

openssl base64 -d -in chal9.txt -out isDecoded.jpg

4. Opened the file only to find a message “The secret ingredient is: “ and a very obfuscated swirl:

image002.jpg

5. Dead end… must be Stegonography, a really bad captcha, or somehow have some text embedded in it.

Here, I’d love to say I went right for the simpler “embedded text”, but I ran this through a battery of stego tools, and even tried a few captcha decoders first.

6. Performing a ‘strings’ on the decoded jpg reveals a familiar string near the beginning of the file:

Pmjeyeglwfh7F

7. Further analysis revealed this string to be embedded in the JPEG EXIF header slot for Document Name
8. Re-reading the message we have two hints, the first one is “vigenere” instead of vinegar. Wikipedia informs us that Vigenere was a cryptographer, and although he didn’t invent the cipher that bears his name, I’d say it’s a pretty solid indication that we need to run the message through a vigenere decoder.
9. The SMTP message ends with “Don’t tell anyone the secret ingredient – discretion is the key”
10. The fine folks at sharkysoft have an online Vigenere cipher encoder/decoder at: http://sharkysoft.com/misc/vigenere/
11. Putting the whole text of the easy message into Sharky’s tool, the only recognizable words appear:

Merchandise7X

12. Obviously, you don’t need to plug the whole message into the decoder, just the ‘Pmjeyeglwf7F’ string.
13. Merchandise7X is known to KO insiders as “Pig’s Blood”, or the secret ingredient in Coke (thanks again, Google!)

Very fun. Thanks again to you and Alec R Waters for making it a fun challenge!

Best,

Dave

Chris writes:

David, you rock! You were the only one who came up with the correct answer to this challenge. And thanks for the kudos too, but Alec gets all the credit for this one. Until next time everyone.