20250323 ‐ VSFTPD Logs - rundas-r00t/blog GitHub Wiki
video walkthrough here: https://rumble.com/v6r2zb2-rundas-gets-r00t-sunday-ctfs.html
first let's make a new directory, cd to it, and download the log file:
mkdir vsftpd; cd vsftpd then r-click-->save as on the link and choose the directory.
let's start with some quick prelim investigation
file vsftpd.log
exiftool vsftpd.log

nothing super surprising here. let's continue with head
head vsftpd.log

Question 1: what is the IP address that 'ftpuser' use to first log-in from?
let's head and grep and see if we can easily answer this question:
SPOILER
head vsftpd.log | grep 'ftpuser'

so there we go! nice.
Question 2 is "what is the first directory that ftpuser created? well, we can clearly see that in the above screenshot on line 5, so Question 2 is trivial.
Question 3 is What is the Last directory that ftpuser created? let's try tail and see what the bottom entry is:
SPOILER
tail -n50 | grep -i 'mkdir' vsftpd.log

easy peasy.
Question 4: what file extension was the most used by ftpuser? so basically we're needing to isolate file extensions from the log, and then count the entries to see which extension appears most often. we'll need to use some awk and drop these into a new file to parse further. let's do that now.
SPOILER
counting the space delimitizations, let's try to isolate columns 12 and 13 to start
awk '{print $12,$13}' vsftpd.log

ok looks like 13 is the column we need, so let's do this again and drop it into a file:
awk '{print $13}' vsftpd.log > files.txt; head files.txt

we see alot of blanks due to the formatting of the log, since some lines don't have a 13th column. i'm sure there's a handy way to clean this up quickly from the command line, but i just ended up going through the file via gedit and manually removed the empty lines, until i realized i could use Excel and filter on blanks and easily remove the blank rows & then copy/paste back into a new txt file. since i have LibreOffice, i don't have a 'filter on blanks' feature, so i ended up sorting the lines (which is not best practice since we're changing the order) and copy/pasting back into the txt file. I got lucky on this that we're just using the file for a count and not needing it for anything else. this is partially why i copy/pasted into a new txt file cleanfiles.txt, in case i need to reference the original order later. (and then 5 minutes later i changed my mind about this and overwrote the original files.txt file anyway lol oh boy...)
now that we have column 13 cleaned up, let's double-check our work:
head cleanfiles.txt

looks good. now let's work on getting some totals on these file extensions.
SPOILER
grep '\.' cleanfiles.txt > files.txt; rm cleanfiles.txt; head files.txt (overwriting files.txt since it doesn't appear that we need the original anymore)

now we need to awk this with a delimiter of / so we can remove the folder path and isolate the actual file name and extension:
awk -F'/' '{print $5}' files.txt | head

ok now that we're happy with the results, let's drop this into a file to delimit further to isolate the file extensions.
SPOILER
awk -F'/' '{print $5}' files.txt > cleanfiles.txt | head cleanfiles.txt

now we can delimit again on '.' and drop all of these into an extensions.txt file:
awk -F'.' '{print $2}' cleanfiles.txt > extensions.txt; head extensions.txt

now we just need to cat extensions and sort -u to get a list of the totals. but we don't want just the numbers, we want the output to be something like:
JPG: 16
xml: 100
etc..
so let's use some pipes, echo and and a bash loop to see if we can make the output look nice:
SPOILER
first, let's get a unique list of extensions for which we can iterate on with the bash loop:
cat extensions.txt | sort -u > uniques.txt and open up this file in gedit or mousepad and manually remove the new-line characters and make them space delimited.


final result:

i'm sure there's a way to do all this in a single command, but for now, we have the end result we need, so let's continue with creating our loop. copying the space-delimited file extensions to our clip board, let's make the bash loop:
SPOILER
`for ext in bak0 chm css DE exe JPG pdf php png txt xml; do echo -n "$ext"; grep "$ext" extensions.txt | wc -l; done'

now let's drop it into a file:
for ext in bak0 chm css DE exe JPG pdf php png txt xml; do echo -n "$ext"; grep "$ext" extensions.txt | wc -l; done > extcounts.txt; cat extcounts.txt

so now we can easily answer Question 4.
Question 5 asks to find another user in the log. in the video, i originally just tried grepping the file to see if we could see any other users in the /home/user/ file directory list on column 13. this is very messy and you'll be scrolling for days.. so let's go back to the original file and see if we can awk and sort -u on column 8, which has syntax of [username] :
SPOILER
awk '{print $8}' vsftpd.log | sort -u
in the video, i used a more complex command, but the above will work and is shorter, so it's better than what i originally used.

Question 5 is good to go!
On to Question 6: what IP address did this other user log-in from? i bet we can answer this with grep:
SPOILER
cat vsftpd.log | grep 'jimmy' | grep -i 'login'

in the video, i used cat vsftpd.log| grep 'jimmy' | awk '{print $8,$9,$10,$11,$12}'|sort -u :

i arrived at the proper answer, but grepping twice ends up being much cleaner than what i did originally.
Questions 7: how many total bytes did the other user upload?
SPOILER
we know the other user is jimmy and we're looking for keyword upload so we'll likely need to grep on these two and then awk to find the column of bytes. let's do it.
cat vsftpd.log | grep 'jimmy' | grep -i 'upload' | grep 'bytes' | awk -F',' '{print $3}' | awk '{print $1}' > byteslist.txt
NOTE: in the video, i did cat vsfptd.log | grep 'jimmy' | grep 'bytes' | awk -F',' '{print $3}', which will give us the total bytes of UPLOAD and DOWNLOAD, (and then subsequently isolated DOWNLOAD by mistake) which is not what we need. you can see how i problem-solve through these mistakes from timestamp 44:00 - 51:00.
now that we have a list of bytes, we can utilize ChatGPT to give us a bash command to sum each line and give us a grand total:

yoooo this is awesome! awk can sum! lets do it:
awk '{sum+=$1} END {print sum}' byteslist.txt > uploadedbytesbyjimmy.txt; cat uploadedbytesbyjimmy.txt
let's break down this command: take the variable sum. let sum = 0, then add it to the first value in column 1 (sum = 0 + [1st value]). then, sum = sum + [2nd value], and continue this process for each line, then print the final result.

Question 8: how many total bytes did 'ftpuser' upload?
this is a similar process to Q7. we just need to replace the other username with 'ftpuser' in our commands. let's do that now:
SPOILER
cat vsftpd.log | grep 'ftpuser' | grep -i 'upload' | grep 'bytes' | awk -F',' '{print $3}' | awk '{print $1}' > uploadedbytesbyftpuser.txt; cat uploadedbytesbyftpuser.txt
awk '{sum+=$1} END {print sum}' uploadedbytesbyftpuser.txt > ftpusertotalupload.txt; cat ftpusertotalupload.txt

i did some slightly different file-names in the video, but the end result is the same.
Question 9: how many total bytes did ftpuser download?
again, very similar set of commands here as with Q7 and Q8.
SPOILER
cat vsftpd.log | grep 'ftpuser' | grep -i 'download' | grep 'bytes' | awk -F',' '{print $3}' | awk '{print $1}' > downloadedbytesbyftpuser.txt; cat downloadedbytesbyftpuser.txt
awk '{sum+=$1} END {print sum}' downloadedbytesbyftpuser.txt > ftpusertotaldownload.txt; cat ftpusertotaldownload.txt

Question 10: identify the suspicious IP address.
back to the original file, let's just grep -i 'login' (or grep 'LOGIN') and see what we get.
SPOILER
cat vsftpd.log | grep 'LOGIN'|sort -u

it took me a minute to think through this. i tried checking for unique pid numbers, then checked for other users using awk, then tried grep '\[username\]' on the different users to try to find a login without any activity.
finally, after a few minutes & talking through it, i re-grep'd on LOGIN and noticed the bottom line:

grepping on this IP address confirms the answer:
cat vsftpd.log | grep '"10.3.0.6"'
NOTE: i put the IP in double-quotes in order to isolate the IP address because, in this file, the syntax is "IPADDRESS". also, without the double-quotes, you will get a few extra lines of Kbyte/sec information, which we don't need.

we've confirmed that 10.3.0.6 has a log-in and no other activity
VSFTPD Logs? DONE!
BONUS awk to get just the IP address and drop it into a file:
SPOILER
cat vsftpd.log | grep '"10.3.0.6"' | awk '{print $12}' > suspiciousIP.txt; cat suspiciousIP.txt


to get rid of the quotes, simply do this awk command:
awk -F'"' '{print $2}' suspiciousIP.txt > susnoquotes.txt; cat susnoquotes.txt
