Ни для кого не секрет, что в Unix системах вся информация предоставляется в виде файлов.
В Linux есть файл /proc/kcore, который является «алиасом» на физическую память системы.
Мануалы говорят, что полная длина этого файла — это размер физической памяти (RAM) плюс 4KB, но повертев этот файл на разных системах я пришел к выводу, что размер файла равен размеру RAM + SWAP.
Аналогично этому файлу можно использовать устройства /dev/mem или /dev/kmem, но взаимодействие с ними в данном топике я не буду рассматривать.
Имея под рукой «слепок памяти», первое что захотелось проверить — можно ли использовать эту «память» для восстановления/получения паролей пользователей системы.
Непечатные символы нам для этой задачи не пригодятся точно, т.к. в паролях мы их использовать все равно не можем/не будем, поэтому используя команду strings мы можем от них избавиться, перегнав /proc/kcore в текстовый файл:
# strings /proc/kcore > /tmp/kdump
Подсчитаем количество получившихся строк
# wc -l /tmp/kdump
4438050 (данная цифра была получена на системе с 3 гигабайтами оперативной памяти)
при таком варианте запуска команды мы получаем очень много ненужных и неуникальных данных, добавим сортировку:
# strings /proc/kcore | sort -u > /tmp/kdump.uniq
# wc -l /tmp/kdump.uniq
3330526
Записей все равно много, давайте представим, что используемые пароли больше 6 символов — добавим ключик -n 6:
# strings -n 6 /proc/kcore | sort -u > /tmp/kdump.uniq.6
# wc -l /tmp/kdump.uniq.6
674397
Таким образом мы получили некий файл с некими данными, давайте попробуем его использовать в качестве словаря для программы john the ripper и посмотрим получится ли расшифровать пароли из файла /etc/shadow
# john --wordlist=/tmp/kdump.uniq.6 /etc/shadow
Loaded 5 password hashes with 5 different salts (FreeBSD MD5 [32/32])
....
Если аккаунты активны и для входа использовались пароли, а не ключи, то есть шанс расшифровать /etc/shadow с нашим свеженьким словарем.Из 5 машин, на которых я тестировал данную методологию удалось расшифровать 3 неизвестных мне пароля.
С помощью kcore можно получить много интересной информации, например обнаружение LKM руткитов или исполнение скрытых команд, предлагаю пообсуждать это в комментах ;)
P.S. ради эксперимента был написан свой парсер kcore, который в качестве параметров принимает минимальную и максимальную длину возможных паролей, если кому-то интересно, то могу выложить.
UPD: ниже исходник парсера, который был написан для тестов
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
void usage(char* argv0)
{
printf("Usage: %s [options] <filename>\n",argv0);
printf("-m [MIN] minimal length of string (Default: 4)\n");
printf("-M [MAX] maximal length of string (Default: 12)\n");
printf("<filename> file that u want to dump\n");
exit(1);
}
int main(int argc, char* argv[])
{
FILE *fp;
int arg, i, binvalid;
int MIN=4;
int MAX=12;
char pass[MAX+1],ch;
char* filename;
while((arg = getopt(argc, argv, "m:M:")) != EOF)
{
switch(arg)
{
case 'm' : MIN=atoi(optarg);
break;
case 'M' : MAX=atoi(optarg);
break;
default : usage(argv[0]);
break;
}
}
if(optind >= argc)
{
usage(argv[0]);
}
filename = argv[optind];
fp=fopen(filename,"r");
if(!fp)
{
printf("ERROR: Unable open file: %s\n",filename);
return 1;
}
i=0;
do
{
ch=(char)fgetc(fp);
if(feof(fp)) break;
if( ch>33 && ch < 127 )
{
i++;
pass[i-1]=ch;
if(i>= MAX)
{
pass[i]='\0';
printf("%s\n",pass);
i=0;
}
}
else
{
if(i>=MIN)
{
pass[i] = '\0';
printf("%s\n",pass);
}
i=0;
}
}
while(1);
fclose(fp);
}