Wu-ftpd is no longer supported, but still available in Ubuntu repositories. Thus, one can get running daemon as easily as this:
polishcode@U-10043-386:~$ sudo apt-get install wu-ftpd [sudo] password for
polishcode:Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: linux-headers-2.6.32-28 linux-headers-2.6.32-28-generic Use 'apt-get autoremove' to remove them. The following NEW packages will be installed: wu-ftpd 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 296kB of archives. After this operation, 856kB of additional disk space will be used. Get:1 http://pl.archive.ubuntu.com/ubuntu/ lucid/universe wu-ftpd 2.6.2-31ubuntu1 [296kB] Fetched 296kB in 9s (30.0kB/s) Preconfiguring packages ... Selecting previously deselected package wu-ftpd. (Reading database ... 152837 files and directories currently installed.) Unpacking wu-ftpd (from .../wu-ftpd_2.6.2-31ubuntu1_amd64.deb) ... Processing triggers for ureadahead ... ureadahead will be reprofiled on next reboot Processing triggers for man-db ... Setting up wu-ftpd (2.6.2-31ubuntu1) ... * Starting FTP server wu-ftpd [ OK ]
polishcode@U-10043-386:~$ telnet localhost 21 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220
U-10043-386 FTP server (Version wu-2.6.2(1) Wed Sep 30 08:46:23 UTC 2009) ready.quit 221 Goodbye. Connection closed by foreign host.
The default installed version is 2.6.2, not susceptible to format string flaws:
polishcode@U-10043-386:~/wu-ftpd-2.6.0$ telnet localhost 21 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 U-10043-386 FTP server (Version wu-2.6.2(1) Wed Sep 30 08:44:57 UTC 2009) ready. USER polishcode 331 Password required for polishcode. PASS dupa 230 User polishcode logged in. site exec %x %x %x %x %x %x %x %x 200-%x %x %x %x %x %x %x %x 200 (end of '%x %x %x %x %x %x %x %x') site index %x %x %x %x %x %x %x %x 200-index %x %x %x %x %x %x %x %x 200 (end of 'index %x %x %x %x %x %x %x %x') quit 221-You have transferred 0 bytes in 0 files. 221-Total traffic for this session was 444 bytes in 0 transfers. 221-Thank you for using the FTP service on U-10043-386. 221 Goodbye. Connection closed by foreign host.
polishcode@U-10043-386:~$ sudo apt-cache showpkg wu-ftpd Package: wu-ftpd Versions: 2.6.2-31ubuntu1 (/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_lucid_universe_binary-i386_Packages) Description Language: File: /var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_lucid_universe_binary-i386_Packages MD5: fb738037171b2322d34372f59596ac2e
For learning purposes one needs to substitute 2.6.2 with 2.6.0 version of this ftp daemon. In order to do that, first download appropriate package (you may use icm.edu.pl). Please do not remove 2.6.2 version, as it sets up environment required by 2.6.0 version and it is easier that way.
After retrieving, unpack it to a known location. Read README and INSTALL files bundled with package to get general idea how to prepare and install package. Lets start building the devil (logs partially removed for clarity):
polishcode@U-10043-386:~/wu-ftpd-2.6.0$ ./build lnx
[...]
Making ftpd.
gcc -O3 -fomit-frame-pointer -fno-strength-reduce -pipe -I.. -I../support -L../support -s -DSHADOW_PASSWORD -c -o COPYRIGHT.o COPYRIGHT.c
sh newvers.sh
gcc -O3 -fomit-frame-pointer -fno-strength-reduce -pipe -I.. -I../support -L../support -s -DSHADOW_PASSWORD -c -o vers.o vers.c
gcc -O3 -fomit-frame-pointer -fno-strength-reduce -pipe -I.. -I../support -L../support -s -DSHADOW_PASSWORD -c -o ftpd.o ftpd.c
ftpd.c: In function ‘socket_flush_wait’:
ftpd.c:538: warning: ignoring return value of ‘read’, declared with attribute warn_unused_result
ftpd.c: In function ‘main’:
ftpd.c:761: warning: ignoring return value of ‘freopen’, declared with attribute warn_unused_result
ftpd.c: In function ‘randomsig’:
ftpd.c:1341: warning: ignoring return value of ‘chdir’, declared with attribute warn_unused_result
ftpd.c: In function ‘pass’:
ftpd.c:2795: error: invalid application of ‘sizeof’ to incomplete type ‘struct dqblk’
ftpd.c: In function ‘retrieve’:
ftpd.c:3968: warning: cast from pointer to integer of different size
ftpd.c:4172: warning: format ‘%d’ expects type ‘int’, but argument 6 has type ‘off_t’
ftpd.c:4189: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result
ftpd.c: In function ‘store’:
ftpd.c:4519: warning: format ‘%d’ expects type ‘int’, but argument 6 has type ‘off_t’
ftpd.c:4536: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result
ftpd.c: In function ‘dataconn’:
ftpd.c:4640: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘off_t’
ftpd.c: In function ‘passive’:
ftpd.c:6145: warning: format not a string literal and no format arguments
ftpd.c:6160: warning: format not a string literal and no format arguments
ftpd.c: In function ‘do_daemon’:
ftpd.c:6965: warning: ignoring return value of ‘freopen’, declared with attribute warn_unused_result
make: *** [ftpd.o] Error 1
[...]
Executables are in bin directory:
size: 'bin/ftpd': No such file
text data bss dec hex filename
8590 892 32 9514 252a bin/ftpcount
size: 'bin/ftpshut': No such file
7783 836 16416 25035 61cb bin/ftprestart
8590 892 32 9514 252a bin/ftpwho
6932 740 8256 15928 3e38 bin/ckconfig
9859 868 384 11111 2b67 bin/privatepw
Done
As first encountered error suggests:
ftpd.c:2795: error: invalid application of ‘sizeof’ to incomplete type ‘struct dqblk’
navigate to line 2795 in file src/ftpd.c:
#ifdef QUOTA
memset("a, 0, sizeof(quota));
get_quota(pw->pw_dir, pw->pw_uid);
#endif
Lets search for QUOTA declaration:
polishcode@U-10043-386:~/wu-ftpd-2.6.0$ grep -Rns QUOTA .
There are a few solutions to that problem. Remember that a fully functional ftp server is not what we need here. What we need is a working server with a known flaw for learning purposes. Achieving this can be done in a numerous ways, one of which is commenting out line:
./src/config/config.lnx:92:#define QUOTA
which was pointed out by search done by previous command. Let us rebuild sources. Remember to perform
polishcode@U-10043-386:~/wu-ftpd-2.6.0$ ./build clean
between builds to get rid of intermediate files.
In my box case error in next build is as follows:
ftpd.c:6965: warning: ignoring return value of ‘freopen’, declared with attribute warn_unused_result yacc ftpcmd.y make: yacc: Command not found make: *** [ftpcmd.c] Error 127
yacc tool needs to be installed:
polishcode@U-10043-386:~/wu-ftpd-2.6.0$ sudo apt-get install byacc
Building again gives
access.c: In function ‘parsetime’: access.c:105: warning: assignment makes pointer from integer without a cast access.c:106: error: dereferencing pointer to incomplete type access.c:133: error: dereferencing pointer to incomplete type access.c:133: error: dereferencing pointer to incomplete type
what means there is a problem with time struct:
struct tm *curtime;
The thing is that tm struct is correctly defined in /usr/include/time.h, whereas conditional compilation dereferences to other libraries:
#ifdef TIME_WITH_SYS_TIME #include <time.h> #include <sys/time.h> #elif defined(HAVE_SYS_TIME_H) #include <sys/time.h> #else #include <time.h> #endif
The easiest solution is to undefine both flags: TIME_WITH_SYS_TIME and HAVE_SYS_TIME_H. This will cause usage of #include
First removal is done in file configuration at line 1373, second in file src/config/config.lnx@53.
Getting rid of previous errors gives us following:
extensions.c:1005: error: ‘RE_SYNTAX_POSIX_EXTENDED’ undeclared (first use in this function) extensions.c:1005: error: (Each undeclared identifier is reported only once extensions.c:1005: error: for each function it appears in.)
Just comment out section
#ifdef LINUX re_syntax_options = RE_SYNTAX_POSIX_EXTENDED; #endif
Right now you should get beautifully shaped "Done":
Executables are in bin directory: text data bss dec hex filename 164302 10652 97280 272234 4276a bin/ftpd 7660 492 16 8168 1fe8 bin/ftpcount 9482 500 10308 20290 4f42 bin/ftpshut 7025 464 12320 19809 4d61 bin/ftprestart 7660 492 16 8168 1fe8 bin/ftpwho 6378 416 8256 15050 3aca bin/ckconfig 8721 480 384 9585 2571 bin/privatepw Done
Almost there - code compiles now. Before installing it, turn off previously started 2.6.2 daemon ($ wu-ftpd stop). Perform (step not necessary):
polishcode@U-10043-386:~/wu-ftpd-2.6.0$ sudo ./build install [sudo] password for polishcode: make args are : make opts are : installing binaries. install -c -o bin -g bin -m 110 bin/ftpd /usr/sbin/in.ftpd install -c -o bin -g bin -m 111 bin/ftpshut /usr/bin/ftpshut install -c -o bin -g bin -m 111 bin/ftprestart /usr/bin/ftprestart install -c -o bin -g bin -m 111 bin/ftpcount /usr/bin/ftpcount install -c -o bin -g bin -m 111 bin/ftpwho /usr/bin/ftpwho install -c -o bin -g bin -m 111 bin/privatepw /usr/bin/privatepw installing manpages. install -c -o bin -g bin -m 444 doc/ftpcount.1 /usr/man/man1/ftpcount.1 install -c -o bin -g bin -m 444 doc/ftpwho.1 /usr/man/man1/ftpwho.1 install -c -o bin -g bin -m 444 doc/ftpaccess.5 /usr/man/man5/ftpaccess.5 install -c -o bin -g bin -m 444 doc/ftpconversions.5 /usr/man/man5/ftpconversions.5 install -c -o bin -g bin -m 444 doc/ftphosts.5 /usr/man/man5/ftphosts.5 install -c -o bin -g bin -m 444 doc/xferlog.5 /usr/man/man5/xferlog.5 install -c -o bin -g bin -m 444 doc/ftpd.8 /usr/man/man8/ftpd.8 install -c -o bin -g bin -m 444 doc/ftpshut.8 /usr/man/man8/ftpshut.8 install -c -o bin -g bin -m 444 doc/ftprestart.8 /usr/man/man8/ftprestart.8 install -c -o bin -g bin -m 444 util/privatepw/privatepw.8 /usr/man/man8/privatepw
Open for edit (as root) file /etc/init.d/wu-ftpd. The difference between versions is that previously, there were several binaries, each performing dedicated task (daemon itself, stopping daemon, restarting etc. - see above log). In 2.6.2, there is only one binary (at the begging of /etc/init.d/wu-ftpd): DAEMON=/usr/sbin/wu-ftpd. Fastest, but least elegant solution is to substitute paths from newer to older in that file:
#DAEMON=/usr/sbin/wu-ftpd DAEMON=/home/polishcode/wu-ftpd-2.6.0/bin/ftpd
We are practically there. Ladies and gentleman, may I introduce the format string vulnerability itself:
polishcode@U-10043-386:~$ telnet localhost 21 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 U-10043-386 FTP server (Version wu-2.6.0(1) Sun Sep 18 14:02:50 CEST 2011) ready. USER polishcode 331 Password required for polishcode. PASS dupa 230 User polishcode logged in. site exec %x %x %x %x %x %x %x %x 200-0 806b431 806d2cd 8354ea0 0 0 0 0 200 (end of '%x %x %x %x %x %x %x %x') site index %x %x %x %x %x %x %x %x 200-index 0 806b431 806d2cd bf8b85ac 0 0 0 0 200 (end of 'index %x %x %x %x %x %x %x %x') quit 221-You have transferred 0 bytes in 0 files. 221-Total traffic for this session was 466 bytes in 0 transfers. 221-Thank you for using the FTP service on U-10043-386. 221 Goodbye. Connection closed by foreign host.
Of course, performing simple path substitution in /etc/init.d/wu-ftpd introduces inability to stop/restart the daemon, but hope you may figure out this one by yourselves.
Happy learning everyone!
1 comment:
Thank you for your sharing. I was in the same situation when i installed wu-ftpd-2.6.0, and your blog helped me resolve most of the compiling errors. But now my trouble is that after i substitute the paths from newer to older, wu-ftpd-2.6.0 could not run normally, the situation is: when "ftp localhost", after i input the username, the program does not respond. Do you have any advice? Looking forward your reply sincerely.
Post a Comment