Неплохая статья на Хабре о Meterpreter, способствует желанию все испробовать. Наибольший интерес, конечно, вызывает кейлоггер, - действительно, полезная штука. Проблема только в том, что, как правило, русские люди пишут по-русски, тогда как keylogrecorder, конечно, об этом не догадывается. Как следствие - просмотр логов его работы не дает желанных результатов :-(. Получается что-то типа такого:
$ cat test.txt
Ujybvs dtiybvb kexfvb?
C jrhtcns[ ujh e;t cytuf
C,t;fkb venysvb hexmzvb
Yf gjnjgktyyst keuf
<return> 'nj ntcn <ctrl> Ntcn 'nj <lctrl> <alt> Fktrcfylh Cthuttdbx Geirby<lmenu>
Может кто, возможно, глядя на это поймет что здесь написано, но я подобными способностями не обладаю.
Первое что приходит на ум - Perl-овый tr, что-нибудь типа:
tr/`qwertyuiop[]asdfghjkl;'zxcvbnm,./ёйцукенгшщзхъфывапролджэячсмитьбю/
При этом программка выглядит так:
$ cat tr1.pl
#!/usr/bin/perl -w
while (){
tr/`qwertyuiop[]asdfghjkl;'zxcvbnm,./ёйцукенгшщзхъфывапролджэячсмитьбю/;
print;
}
Но не все так просто, к моему глубочайшему сожалению. Русские буквы, бывает, кодируются UTF-8 в 2 байта, а английские - в 1 байт...
Абсолютно рабочим вариантом является recode наш tr (всю Perl-овую программку) в кодировку где русские буквы однобайтовые, например так:
$ recode UTF-8..KOI8r tr-koi8r.pl
Затем, этим tr-koi8r.pl можно уже транслировать продукт keylogrecorder-а.
$ cat test.txt | ./tr-koi8r.pl >test2.txt
Помним, что у нас локаль - UTF-8...
у меня на Debian оно выглядит так:
$ locale
LANG=en_US.utf8
LANGUAGE=
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=
..., поэтому результат, test2.txt, следует вернуть в юникод:
$ recode KOI8r..UTF-8 test2.txt
И..., вуаля, уже что-то:
$ cat test2.txt
Uонимы вешними лучами?
C окрестых гор уже снега
Cбежали мутными ручьями
Yа потопленные луга
<rуегкт> это тест <cекд> Nест это <lcекд> <aде> Fлександр Cергеевич Gушкин<lmутг>
Есть кое-какие артефакты, но это потому, что заглавные буквы я забыл (:-) указать в tr, перевелись и управляющие клавиши, типа <lctrl> <alt> и т.п. Тем, не менее, в целом, такой вариант перевода трудов keylogrecorder-а, также возможен: программка на Perl в три строчки, дважды recode и все!
Но, почему-то этот варинат показался мне неспортивным! Решил тряхнуть стариной, написать транслятор на С. Последний раз я интенсивно писал на С уже как десять лет назад, поэтому не могу похвастаться что получилось все сразу просто и быстро. Но, в целом, ничего сложного в коде нет, поэтому не буду много разглагольствовать, просто приведу исходник. Программа учитывает управляющие последовательности типа
$ cat trc.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int checkIfCtrl(char *p);
int main(int argc, char **argv){
const int n = 512;
char *buf, *buf2, *ten, *tru, *tb, *tb2;
char *enl = "`qwertyuiop[]asdfghjkl;'zxcvbnm,.~QWERTYUIOP{}ASDFGHJKL:ZXCVBNM<>\"";
char *rul = "ёйцукенгшщзхъфывапролджэячсмитьбюЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЯЧСМИТЬБЮЭ";
char *enl1 = "/?&^$";
char *rul1 = ".,?:;";
int b = (int) strlen(rul)/strlen(enl), i;
//char *words[] = {"<Next>","<Prior>","<Return>","<Ctrl>","<LCtrl>","<Alt>","<LMenu>","<Back>","<Delete>","<N3>","<N0>","<Right>","<Tab>"};
//int wn = 13;
int wil;
buf = (char *) malloc(n);
memset(buf,0,n);
buf2 = (char *) malloc(n*b);
memset(buf2,0,n*b);
while( 0 != fgets(buf,n,stdin) ){
tb2 = buf2;
for(tb = buf; *tb != '\0'; tb++){
/*for (i=0; i<wn; i++){ //ctrl
wil = strlen(words[i]);
if (strncmp(tb,words[i],wil) == 0){
memcpy(tb2,tb,wil);
tb += wil;
tb2 += wil;
}
}*/
if( (wil = checkIfCtrl(tb)) > 0){ //ctrl
memcpy(tb2,tb,wil);
tb += wil;
tb2 += wil;
}
if ( (ten = strchr(enl, *tb)) != 0 ){
tru = rul + b*(ten-enl);
memcpy(tb2,tru,b);
tb2 += b;
}
else if ( (ten = strchr(enl1, *tb)) != 0 ){
tru = rul1+(ten-enl1);
memcpy(tb2,tru,1);
tb2 += 1;
}
else {
memcpy(tb2,tb,1);
tb2 += 1;
}
}
printf(buf2);
memset(buf2,0,n*b);
memset(buf,0,n);
}
free(buf2);
free(buf);
return 0;
}
/////////////////////////////////////////////////////////////////////////
int checkIfCtrl(char *p){
int lmax = 10, i, flag=0;
char b='<', e='>';
if(*p == b){
for(i=0; i<lmax; i++){
if (*(p+i) == e){
flag = 1+i;
break;
}
}
}
return flag;
}
Сразу прошу снисхождения к моим навыкам академического программирования. Но, если есть предложения по развитию этой микро-программки (во термин - micro-soft), буду рад их увидеть.
Компилируем:
$ gcc trc.c -o trc
Результат работы:
$ cat test.txt | ./trc
Гонимы вешними лучами,
С окрестых гор уже снега
Сбежали мутными ручьями
На потопленные луга
<return> это тест <ctrl> Тест это <lctrl> <alt> Александр Сергеевич Пушкин<lmenu>
Совсем хорошо!
Кривовато, правда... Более правильным кажется использование штатных С-шных функций для двухбайтовых символов, описанных в wchar.h и wctype.h, но просто и быстро у меня это почему-то не получилось (помню на VC под win пару лет назад получалось), поэтому я эту идею бросил, может, в следующий раз...
Представленные здесь варианты решили мою задачу, надеюсь, могут быть полезны и вам.
No comments:
Post a Comment