SpyBot: мониторим статус ВКонтакте и твитим в twitter

Скрипт написан на Python. Работает просто и следующим образом:
1) перед первым запуском нужно прописать ID адрес пользователя ВКонтакте или его алиас (/id123456 или /user_alias) в файл spybot.config напротив значения vkid;
2)

1
python vkontakte_spy_bot.py

далее запускаем скрипт для получение данных для коннекта к twitter через OAuth, для этого переходим по ссылке в твитер, даем разрешение для подключения приложения, получаем PIN-код, вводим его в консольку.
3)

1
2
crontab -e
*/10 * * * * /usr/bin/python /path_to_script/vkontakte_spy_bot.py

далее уже можно смело прописывать скрипт в крон. (обязательное условие держать скрипт и конфиг в одной директории)
4) время в UTC, также just4fun твитим координаты HQ CIA from Langley 😉

Скачать скрипт мониторинга статуса ВКонтакте

UPD: Можно ф-цию получения статуса заменить примерно следующим образом, используя API ВКонтакте
Continue reading «SpyBot: мониторим статус ВКонтакте и твитим в twitter»

Новый релиз сканера уязвимостей RIPS 0.4

Год назад делал уже заметку насчет этого сканера узких мест в PHP приложениях.
Опишу только основные «вкусности» которые появились в новой версии.
Первое на что обратил внимание — это появление графического представления взаимосвязей сканируемых файлов (инклуды, функции).

Также скрипт пытается анализироваться самостоятельно возможные места с SQL-инъекциями (правда пока эта функция в стадии глубокой альфы).
Появился вывод статистики после сканирования.

Rips все еще буксует на крупных проектах которые в основной массе построены на ООП, обещают пофиксить в следующих версиях.
Скачать актуальную версию сканера RIPS. Continue reading «Новый релиз сканера уязвимостей RIPS 0.4»

Vigenere — расчет индекса совпадений

Скрипт подсчитывает индекс совпадений в зависимости от сдвига, для определения длины ключа по методу Фридмана.
В функцию передаем значения первого значения сдвига (k) и общее количество последующих сдвигов текста (seq).
Для примера в скрипт введено значение четвертой части Kryptos’a (K4), если принять во внимание что для ее шифровки использовался метод Виженера — то длина ключа, скорее всего, будет равна 7.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env python
# coding: utf-8
# dev: Dominus <dominus [at]k0derz[dot]ru>
# site: http://k0derz.ru/

def shifts(text, k=1, seq=1):
    print '|---------------|---------------|-----------------------|'
    print '|\tShift\t|\tCount\t|\tPercent, % \t|'
    print '|---------------|---------------|-----------------------|'
    for items in range(seq):
        text_len = len(text)
        a_count = [0 for x in range(text_len)]
        delta = 0
        for index in range(text_len):
            if index < text_len - k:
                index2 = index+k
                a_count[index] = text[index2]
            else:
                    a_count[index] = text[delta]
                    delta = delta + 1
        counter = 0
        for inx in range(text_len):
            if text[inx] == a_count[inx]:
                counter = counter + 1
        print '|\t%d\t|\t%d\t|\t%f\t|' % (k, counter, counter*100.0/text_len)
        k = k + 1
    print '|---------------|---------------|-----------------------|'      

def main():
    text = 'OBKRUOXOGHULBSOLIFBBWFLRVQQPRNGKSSOTWTQSJQSSEKZZWATJKLUDIAWINFBNYPVTTMZFPKWGDKZXTJCDIGKUHUAUEKCAR'
    shifts(text, 1, 17)
   
if __name__ == '__main__':
    main()

Continue reading «Vigenere — расчет индекса совпадений»

Python: анализатор текста

Простой анализатор текста, делает подсчет количества вхождения букв в предоставленный текст и их процентное соотношение к общему количество символов в тексте. Писался для себя и на скорую руку как отмаз за код 😉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env python
# coding: utf-8
# dev: Dominus <dominus [at]k0derz[dot]ru>
# site: http://k0derz.ru/

def main():
   
    a_count = [0 for x in range(123)]
    alpha_count = 0
    f = open('fbi_cipher.txt', 'r') # здесь лежит файлик с анализируемым текстом
    text = f.read()
    f.close()
    for items in text:
        if items.isalpha():
            my_ord = ord(items.lower())
            k = a_count[my_ord]
            index = my_ord
            a_count[index] = k + 1
            alpha_count = alpha_count + 1
    i = 97     
    print '|\tletter\t|\tcount\t|\tpercent, %\t'
    print '|---------------|---------------|---------------------'
    for k in range(26):    
        persent = a_count[i] * 100.0 / alpha_count
        print '|\t%s\t|\t%d\t|\t%s\t' % (chr(i), a_count[i], persent)
        i = i + 1
    print '|---------------|---------------|---------------------' 
    print 'Total letters: %d' % alpha_count

if __name__ == '__main__':
    main()

Continue reading «Python: анализатор текста»

Creepy — парсер геолокаций в соц.сетях

Creepy — это релевантный парсер геолокаций в соц.сетях, сейчас доступны twitter и flickr, координаты берутся как из самих статусов сообщений так и из EXIF информации в фотографиях. Сайт разработчика — http://ilektrojohn.github.com/creepy/

Установка в Ubuntu:

1
2
3
sudo add-apt-repository ppa:jkakavas/creepy
sudo apt-get update
sudo apt-get install creepy

Программа написана на Python. Может понадобиться дополнительная установка модулей.
Проверил ее на профиле Олега Тинькова (@olegtinkov в твиттере). Получил в итоге следующую картину его передвижений по планете Земля ) (масштаб увеличил чтоб захватить все точки). Карты которые можно использовать это гугл, опенстрит и другие. Continue reading «Creepy — парсер геолокаций в соц.сетях»

Python: socket post data (простой пример)

Немного проанализировав метрику Яндекса, увидел заходы на сайт в выдачи о примере отправки POST-запроса, реализованного на Python’e.
Поэтому решил немного переделать этот пример реализации сокетов на python. В заголовке POST запроса написал только необходимый минимум, без учета кукисов и юзерагентов etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env python
'''
post_socket.py.py
author: Dominus
site: http://k0derz.ru/
'''

import socket, sys

def main():
if len(sys.argv) &lt; 4:
print "Usage: python post_socket.py server port data=test"
sys.exit(1);
HOST = sys.argv[1]      # server adress
PORT = int(sys.argv[2]) # server port
DATA_POST = sys.argv[3] # POST data
DATA_LEN  = str(len(DATA_POST))

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # init TCP socket type
s.connect((HOST, PORT))
s.send("POST /search.php HTTP/1.1\r\nHost: "+ HOST +"\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: "+ DATA_LEN +"\r\n\r\n" + DATA_POST) # send DATA to server
data = s.recv(1024)  # recieve info
s.close()
rsp = repr(data)
print rsp

if __name__ == "__main__":
main()

Python: MRA — Mail.ru Agent (SMS)

Решил немного потренироваться в создании пакетов и разборов дампов, выбрал для этого MRA в качестве исследуемого и Python как язык для реализации задуманного.
Хочу сразу уточнить, что ответ сервера при отправки SMS был выбран методом тыка, потому что у меня нет под рукой нативного клиента, который мог бы отправить СМСку.
Основные моменты описаны в коде, оптимизировать ф-ции в коде не стал, т.к. так более наглядней и можно просмотреть все этапы создания пакета для отправки.
В роле снифера выступал wireshark.
Буду очень благодарен за дампы с ответами после отправки SMS.(успешной и нет)
Continue reading «Python: MRA — Mail.ru Agent (SMS)»

Python: Пример использования сокетов

Для примера взял получения информации о сервере Counter-Strike, а именно имя сервера и текущую карту. Соединение происходит по протоколу UDP, затем распарсиваем полученные данные и выводим на экран.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python
'''
cs_client.py
author: Dominus
site: http://k0derz.ru/
'''

import socket, string, sys

def main():    
    if len(sys.argv) < 3:
        print "Usage: python cs_client.py server port"
        sys.exit(1);
    HOST = sys.argv[1]          # server adress
    PORT = int(sys.argv[2]) # server port
   
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # init UDP socket type
    s.connect((HOST, PORT))
    s.send("\xFF\xFF\xFF\xFFTSource Engine Query\x00")   # send INFO request to CS-server
    data = s.recv(1024)  # recieve info
    s.close()
    rsp = repr(data).split("\\x00")
    print "Server name:", rsp[1]
    print "Server map:",  rsp[2]

if __name__ == "__main__":
    main()

Linux: Opera Passwords Recovery

Пароли в Opara лежат в файле wand.dat, который расположен в директории ~/.opera/. Немного полазив по сайтам сделал собирательный пример выуживания паролей. В основе пример из этой статьи, 2005 года еще, http://www.reteam.org/blog/archives/00000012.htm. Причина написания поста, в том, что софт который есть в сети, почему-то, стоит денег, многие некорректно декриптуют содержимое, и так, ближе к теме:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// sna@reteam.org  - 6th of April 2005
// unwand.cpp //
#include <iostream>
#include <string.h>

#include <openssl/md5.h>
#include <openssl/des.h>


const unsigned char opera_salt[11] =
{
    0x83, 0x7D, 0xFC, 0x0F, 0x8E, 0xB3, 0xE8, 0x69, 0x73, 0xAF, 0xFF
};

int main(int argc, char **argv)
{
    if(argc != 2)
    {
        std::cout << "Usage: unwand <opera wand file>" << std::endl;
        return 1;
    }

    FILE *fdWand = fopen(argv[1], "rb");

    if(NULL == fdWand)
    {
        perror("Failed to open file");
        return 1;
    }

    fseek(fdWand, 0, SEEK_END);
    unsigned long fileSize = ftell(fdWand);

    unsigned char *wandData = (unsigned char *)malloc(fileSize);

    if(NULL == wandData)
    {
        fclose(fdWand);
        perror("Memory allocation failed");
        return 1;
    }

    rewind(fdWand);
    fread(wandData, fileSize, 1, fdWand);
    fclose(fdWand);

    unsigned long wandOffset = 0;

    //
    // main loop, find and process encrypted blocks
    //

    while(wandOffset < fileSize)
    {
        // find key length field at start of block
        unsigned char *wandKey = (unsigned char *)
            memchr(wandData + wandOffset, DES_KEY_SZ, fileSize - wandOffset);

        if(NULL == wandKey)
        {
            break;
        }

        wandOffset = ++wandKey - wandData;
        // create pointers to length fields
        unsigned char *blockLengthPtr = wandKey - 8;
        unsigned char *dataLengthPtr = wandKey + DES_KEY_SZ;

        if(blockLengthPtr < wandData || dataLengthPtr > wandData + fileSize)
        {
            continue;
        }

        // convert big-endian numbers to native
        unsigned long
            blockLength  = *blockLengthPtr++ << 24;
            blockLength |= *blockLengthPtr++ << 16;
            blockLength |= *blockLengthPtr++ <<  8;
            blockLength |= *blockLengthPtr;

        unsigned long
            dataLength  = *dataLengthPtr++ << 24;
            dataLength |= *dataLengthPtr++ << 16;
            dataLength |= *dataLengthPtr++ <<  8;
            dataLength |= *dataLengthPtr;

        // as discussed in the article
        if(blockLength != dataLength + DES_KEY_SZ + 4 + 4)
        {
            continue;
        }

        // perform basic sanity checks on data length
        if(dataLength > fileSize - (wandOffset + DES_KEY_SZ + 4)
            || dataLength < 8 || dataLength % 8 != 0)
        {
            continue;
        }

        unsigned char
            hashSignature1[MD5_DIGEST_LENGTH],
            hashSignature2[MD5_DIGEST_LENGTH],
            tmpBuffer[512];

        //
        // hashing of (salt, key), (hash, salt, key)
        //

        memcpy(tmpBuffer, opera_salt, sizeof(opera_salt));
        memcpy(tmpBuffer + sizeof(opera_salt), wandKey, DES_KEY_SZ);

        MD5(tmpBuffer, sizeof(opera_salt) + DES_KEY_SZ, hashSignature1);

        memcpy(tmpBuffer, hashSignature1, sizeof(hashSignature1));
        memcpy(tmpBuffer + sizeof(hashSignature1),
            opera_salt, sizeof(opera_salt));

        memcpy(tmpBuffer + sizeof(hashSignature1) +
            sizeof(opera_salt), wandKey, DES_KEY_SZ);

        MD5(tmpBuffer, sizeof(hashSignature1) +
            sizeof(opera_salt) + DES_KEY_SZ, hashSignature2);

        //
        // schedule keys. key material from hashes
        //

        DES_key_schedule key_schedule1, key_schedule2, key_schedule3;

        DES_set_key_unchecked((const_DES_cblock *)&hashSignature1[0],
            &key_schedule1);

        DES_set_key_unchecked((const_DES_cblock *)&hashSignature1[8],
            &key_schedule2);

        DES_set_key_unchecked((const_DES_cblock *)&hashSignature2[0],
            &key_schedule3);

        DES_cblock iVector;
        memcpy(iVector, &hashSignature2[8], sizeof(DES_cblock));

        unsigned char *cryptoData = wandKey + DES_KEY_SZ + 4;

        //
        // decrypt wand data in place using 3DES-CBC
        //

        DES_ede3_cbc_encrypt(cryptoData, cryptoData, dataLength,
            &key_schedule1, &key_schedule2, &key_schedule3, &iVector, 0);

        if(0x00 == *cryptoData || 0x08 == *cryptoData)
        {
            std::wcout << L"<null>" << std::endl;
        }
        else
        {
            // remove padding (data padded up to next block)
            unsigned char *padding = cryptoData + dataLength - 1;
            memset(padding - (*padding - 1), 0x00, *padding);
                    //uncomment if Windows platform
            //std::wcout << (wchar_t *)cryptoData << std::endl;
           
            // dump byte-aligned data[dataLength] little endian UTF-16 as UTF-8. (c) Madhu
            for (unsigned int i = 0; i < dataLength; i+=2) {
                int uch = cryptoData[i];
                uch = uch | cryptoData[i+1];
                if (uch == 0) break;
                if (uch > 0x7FF)
                    std::cout << (unsigned char) (((uch >> 12) & 0xF) | 0xE0)
                            << (unsigned char) (((uch >> 6) & 0x3F) | 0x80)
                            << (unsigned char) ((uch & 0x3F) | 0x80);
                else if (uch > 0x7F)
                    std::cout << (unsigned char) (((uch >> 6) & 0x1F) | 0xC0)
                            << (unsigned char) ((uch & 0x3F) | 0x80);
                else std::cout << (unsigned char) uch;             
            }                      
        }
        std::cout << std::endl;;
        wandOffset = wandOffset + DES_KEY_SZ + 4 + dataLength;
    }

    free(wandData);
    return 0;
}

Компиляция:

1
g++ -Wall -o unwand -lssl unwand.cpp

Запуск программы:

1
./unwand ~/.opera/wand.dat

DharmaEncoder

Хочу обратить внимание на этот новый проект под названием DharmaEncoder. Очень удобный энкодер/декодер написанный на python с использованием PyGtk, который в данный момент поддерживает:
— URL
— Full Url
— Base64
— Hex
— MD5 Hash
— SHA1 Hash
— SQL Char String
— Unicode %u00
— и т.д.

Nautilus: конвертируем изображения в JPEG или PNG

topng
topng

Иногда приходится конвертировать изображения с одного формата в другой, основные это JPEG и PNG.
Добавим сценарии в контекстное меню Nautilus при клике правой кнопки на файле.
Continue reading «Nautilus: конвертируем изображения в JPEG или PNG»

Получаем местонахождение через GPS-инфо в изображении

gps_exif
gps_exif

Многие мобильные телефоны оснащенные GPS навигаторами вставляют информацию о местонахождении в фотографию(т.е. в EXIF).
На написание этого скрипта подвигло выступление одного хакера создавшего сайт мониторинга местоположения через сервис Twitter’a.
В общем для работы скрипта необходимо установить модуль Image::EXIF (sudo cpan -i Image::EXIF), возможно, также придется установить и другой пакет, если первый не будет собираться (sudo cpan -i YAML возможно еще и sudo apt-get install libexif-dev), на выходе получаем собственно сами координаты и название места, где было сделано фото. Continue reading «Получаем местонахождение через GPS-инфо в изображении»