Изучаем Xenforo на примере Rutor (Python,OSINT)

Unique Projects

Местный
Работать только с GARANT
Кардинг
Подтвержденный
Заблокирован
Сообщения
324
Реакции
717
Продажи
3
Кешбек
1.25$
Изучаем Xenforo на примере Rutor (Python,OSINT)

В большинстве своем сейчас многие популярные форумы используют используют движок Xenforo.
Как таковых известных уязвимостей в нем нет. Или я пока не нашел)
Однако в этой статьи мы рассмотрим интересные особенности, которые позволяют получать открытую доп информацию о юзерах и еще кое-что по мелочи.

Также будут написаны скрипты для автоматизации вышеуказанных действий. Капчу обходить не стал, может в другой раз. На данный момент берем кукисы с браузера.


Часть 1 - Собираем историю всех постов юзера. Даже если закрыто в приватности.


Продемонстрирую на примере пользователя ADMIN.
Если перейти конкретно на ссылку профиля , то мы увидим баннер о том, что пользователь закрыл доступ к своей истории. Однако перейдя по подобной ссылке, где вписан айди юзера из первой. Мы видим все посты.
/search/member?user_id=88013


На одной из страниц мы видим интересную информацию о том, за сколько и примерно когда был продан форум. Инфа известная, но далеко не всем. Это как пример sensitive information.

Напишем небольшой скрипт для сбора постов. Чтобы взять кукисы из браузера заходим в раздел браузера инструменты веб разработчика и смотрим любой запрос в разделе сеть. Правой кнопкой жмем и копируем кукисы, как CURL. Далее используем библиотеку uncurl чтобы перевести их в формат python request.
В консоли python print(uncurl.parse("""ваш с браузера запрос"""))
Добавляем их вверх скрипта в переменную cookies.

Необходимые зависимости pip3 install lxml cssselect requests

Python:
  def posts(self,userid=target_userid):

        url = main_url + f'/search/member?user_id={userid}'

        print(url)

        posts = []


        headers={

            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",

            "Accept-Encoding": "gzip, deflate",

            "Accept-Language": "en-US,en;q=0.5",

            "Connection": "keep-alive",

            "Referer": main_url,

            "Sec-Fetch-Dest": "document",

            "Sec-Fetch-Mode": "navigate",

            "Sec-Fetch-Site": "same-origin",

            "Sec-Fetch-User": "?1",

            "Upgrade-Insecure-Requests": "1",

            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"

        }


        r = self.session.get(url,headers=headers)

        if self.check_block(r):

            r = self.session.get(url,headers=headers)


        tree = etree.HTML(r.text)

        newurl = r.url

        num = tree.cssselect('li.pageNav-page:nth-child(5) > a:nth-child(1)')[0].get('href').split('=')[-1]


        posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]


        for i in range(2,int(num)+1):

            sleep(randint(5,TIMEOUT))

            url = newurl + f'?page={i}'


            print(url)

            r = self.session.get(url,headers=headers)

            if self.check_block(r):

                r = self.session.get(url,headers=headers)


            tree = etree.HTML(r.text)

            posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]


        return posts

Для парсинга ответов, мы используем библиотеку lxml. Также случайные таймауты. Выводим на экран И сохраняем в csv формат в файл part_one.csv

Теперь достаточно вписать в target_userid id юзера посты которого мы хотим сохранить и готово. У вас должен быть включен тор в системе. Если браузер, то порт будет 9150,если демон то 9050. В ubuntu - sudo apt install tor

И получаем статистику всех постов с датой, названием, и разделом. Переодически нас будет останавливать блок от анти ддоса. Благо он легко обходится сменой identity tor, учел в коде. Кукисы работают на новой сессии всегда автоматом. Также выставлены длительные таймауты.

2023-04-09-032359_955x457_scrot.png


Python:
[{'title': 'Комната грязи.',
  'forum': 'Форум: ОКНА с Пшекой Шпековой',
  'text': 'Смотрю уже берега конкретно стали путать. Спор был решен в личке. Сейчас решили продолжить срать. Мне че заняться больше нечем, ждать пока кто-то там что-то заскринит. Пойдика ты тоже голову свою остуди на сутки. Продолжите этот безсмысленный срач - сотру двоих спамом и аккаунты удалю',
  'date': 'Пятница в 22:04'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Кидай. Уже заказываю',
  'date': 'Пятница в 18:17'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Ну только если один подарок, для закатывания...',
  'date': 'Пятница в 14:02'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Я смотрю опыт прошлых пользователь ни к чему не привел?',
  'date': 'Понедельник в 22:38'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'По поводу игр в слова. Если и вправду интересно играть в слова, то продолжат играть и с выключенным счетчиком. А если эти темы используются только ради набивки сообщений, чтобы твинком вскочить на рулетку, то ясное дело не интересно будет.',
  'date': '1 Апр 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Это не тема для обсуждений. Тут только можете высказать свои предложения!',
  'date': '1 Апр 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Скоро, очень скоро...',
  'date': '29 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'А то что потерялся смысл счетчиков сообщений, тебя не смущает?',
  'date': '29 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Скоро будут пересмотрены все темы, в которых использовалась накрутка счетчиков сообщений и соответственно реакций.\nКогда будет готов маркет подписей, все счетчики сообщений будут приведены в порядок. Чтобы было видно, кто форумом живет и реально принимает активную позицию в его жизни. А кто...',
  'date': '28 Мар 2023'},
 {'title': 'NFT Collection RuTOR 2023',
  'forum': 'Форум: Новости форума RuTOR',
  'text': 'Коллекция - https://getgems.io/collection/EQAT6Rc1v_REhfHLkJ7QC9PAt_EbRB3K1517Kp0qpUSCJTzs?filter=%7B%22sort%22%3A%22LikesCountDesc%22%7D',
  'date': '28 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Статус приобретается не для красоты, а чтобы было видно, какую комерческую деятельность ведет пользователь.',
  'date': '28 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Зачем? Чтобы увешаться ими?',
  'date': '28 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Какие именно?',
  'date': '27 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Подразумевает то, что пользователи смогут выкладывать свои подписи под сдачу типо как на витрину и магазины автоматом смогут их покупать на тот срок, который им нужен. Пользователь сам не сможет снять или отредактировать эту подпись, пока не пройдет срок аренды.',
  'date': '27 Мар 2023'},
 {'title': 'Чем вызвано твое удивление?',
  'forum': '22 Мар 2023',
  'text': 'Чем вызвано твое удивление?',
  'date': '22 Мар 2023'},
 {'title': 'Я не пойму, вы тут что митинг устроить решили?',
  'forum': '21 Мар 2023',
  'text': 'Я не пойму, вы тут что митинг устроить решили?',
  'date': '21 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Для того чтобы накупили те, кто не имеет отношение к данным сервисам?',
  'date': '20 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Приветствую. У подтвержденного сейчас 4е строчки подписи. В планах ввести своебразный маркет подписей. Сейчас готовятся другие, более важные обновления.',
  'date': '18 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Некоторые решения требуют больше времени',
  'date': '14 Мар 2023'},
 {'title': 'Авторское руководство по заработку на МФО',
  'forum': 'Форум: Платно',
  'text': 'Закрыто на проверку. По поводу проверки пиши @Berlusconi',
  'date': '9 Мар 2023'}]
2023-04-09-032812_1869x811_scrot.png



Часть 2 - Небольшие мелочи. Форум, как файлохранилище. Поиск юзеров по нику.


Давайте зайдем в раздел создания личных сообщений.

Там можно найти такую интересную ссылку
/attachments/upload?type=conversation_message&hash=

Которая позволит нам загружать файлы на сервер. Без привязки их к конкретному диалогу. Потом по прямой ссылке можно иметь доступ к ним. Удобно хранить картинки, лол.

Python:
    def upload_file(self,file='DFF681-DC-EEF7-422-A-97-E9-ADD76-D37-DF9-F.jpg'):
        token = self.get_token()
        hash = self.get_hash()

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0',
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Language': 'en-US,en;q=0.5',
            # 'Accept-Encoding': 'gzip, deflate',
            'Referer': f'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion/attachments/upload?type=conversation_message&hash={hash}',
            'X-Requested-With': 'XMLHttpRequest',
            'Content-Type': 'multipart/form-data; boundary=---------------------------156277210038657417371957125884',
            'Origin': 'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion',
            'Connection': 'keep-alive',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
        }

        params = {
            'type': 'conversation_message',
            'hash': hash,
        }

        data = f'-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="_xfToken"\r\n\r\n{token}\r\n-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="upload"; filename="{file}"\r\nContent-Type: image/jpeg\r\n\r\n-----------------------------156277210038657417371957125884--\r\n'

        response = self.session.post(
            main_url + '/attachments/upload',
            params=params,
            headers=headers,
            data=data,
        )

        print(f'{main_url}/attachments/upload?type=conversation_message&hash={hash}')
        return response
```
2023-04-09-044650_945x236_scrot.png


Далее, с помощью подобной ссылки /members/find?q=goodn&_xfRequestUri=%2Fconversations%2Fadd%3Fto%3DRUTOR&_xfWithData=1&_xfToken=&_xfResponseType=json мы можем производить поиск юзеров по части никнейма. Может быть достаточно полезно. Разумеется у нас должен предварительно получен xfToken. Это не проблема.
Выдергиваем его с помощью regexp с любой страницы.

Python:
    def search_users(self,name):
        token = self.get_token()
        url = main_url + f'/members/find?q={name}n&_xfRequestUri=%2Fconversations%2Fadd%3Fto%3DRUTOR&_xfWithData=1&_xfToken={token}&_xfResponseType=json'

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        return json.loads(r.text)
2023-04-09-040208_909x909_scrot.png



Часть 3 - Анализируем статистику переходов юзера по форуму.


Немногие отключают в своем профиле доступ для всех. Или конкретно показ статистики посещений тем.
Это кажется незначительной вещью. Но все же все эти моменты, могут выдать больше информации о вас чем вам бы хотелось.

Предположим посещение определенных тем по регионам, указывает на город пользователя. Посещение конкретных услуг или тематик указывает на интересы пользователя. Кроме этого возможное посещение новостных тем тоже позволяет составить интересную картину.

Естественно для этого надо собрать статистику, чем мы сейчас и займемся. Скрипт написан на примере одного юзера и одного потока, но разумеется можно распараллелить в будущем.

2023-04-09-035320_939x238_scrot.png

Python:
    def eye(self,userid=target_userid):
        url = main_url + f'/members/{userid}'
        print(url)

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        while True:
            tree = etree.HTML(r.text)
            name = ''.join(tree.cssselect('.memberHeader-blurb')[-1].itertext()).strip().replace('\t','')

            print(str(datetime.now()) + ' ' + name)

            sleep(randint(3,7))
            r = self.session.get(url,headers=headers)
            if self.check_block(r):
                r = self.session.get(url,headers=headers)
```


Полный скрипт бота со всеми функциями приложен внизу статьи.


-------------------------------
PS:
В статье мы затронули относительно безобидные вещи. Без брутов, обходов капч и прочих шалостей.
Мораль статьи в том, чтобы следить за вашей приватностью, как на уровне отдельного пользователя. Так и на уровне самого форума. Использование крупных движков оставляет множество нюансов. Даже малейшая деталь может дать наблюдателю важные сведения о вашей фигуре. Это может быть неактуально для рядового пользователя, но являться очень серьезным для других фигур.

Помните о безопасности и да пребудет с вами сила!

Python:
import requests
import socks,socket
from random import randint
from time import sleep
from lxml import etree
import os,csv,re
from datetime import datetime
import json

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0'
}

cookies={
    "":"",
    }

main_url = 'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion'
#target_userid = '88013'
target_userid = '354635'

TIMEOUT = 20

def save_csv(file,dicts):
    with open(f'{file}', mode='w', newline='') as file:
        fieldnames = list(dicts[0].keys())
        writer = csv.DictWriter(file, fieldnames=fieldnames, delimiter=';')

        writer.writeheader()

        for d in dicts:
            print(d)
            writer.writerow(d)


def reload_tor():
    print('Рестартим тор сессию')
    os.system('sudo service tor reload')

class spy:

    def __init__(self):
        self.session = requests.Session()
        self.session.headers = headers

        self.session.proxies = {
            'http': 'socks5h://localhost:9050',
            'https': 'socks5h://localhost:9050'
        }

        self.session.cookies.update(cookies)

    def get_token(self):
        url = main_url + '/whats-new/news-feed'

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)


        return re.findall('_xfToken" value="([^"]{1,})',r.text)[0]


    def parse_one(self,el):
        one = {}

        dop = [n for n in ''.join(el.cssselect('.contentRow-minor')[0].itertext()).strip().split('\t') if n != '']

        try:
            one['title'] = ''.join(el.cssselect('.contentRow-title')[0].itertext()).strip()
            one['forum'] = dop[-1]
            one['text'] = ''.join(el.cssselect('.contentRow-snippet')[0].itertext()).strip()
            one['date'] = dop[2].rstrip()
        except Exception as msg:
            print(msg)
            return {}

        return one

    def check_block(self,r):
        if 'DDOS fliter' in r.text:
            reload_tor()
            sleep(5)
            return True
        else:
            return False

    def posts(self,userid=target_userid):
        url = main_url + f'/search/member?user_id={userid}'
        print(url)
        posts = []

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        tree = etree.HTML(r.text)
        newurl = r.url
        num = tree.cssselect('li.pageNav-page:nth-child(5) > a:nth-child(1)')[0].get('href').split('=')[-1]

        posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]

        for i in range(2,int(num)+1):
            sleep(randint(5,TIMEOUT))
            url = newurl + f'?page={i}'

            print(url)
            r = self.session.get(url,headers=headers)
            if self.check_block(r):
                r = self.session.get(url,headers=headers)

            tree = etree.HTML(r.text)
            posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]

        return posts

    def eye(self,userid=target_userid):
        url = main_url + f'/members/{userid}'
        print(url)

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        while True:
            tree = etree.HTML(r.text)
            name = ''.join(tree.cssselect('.memberHeader-blurb')[-1].itertext()).strip().replace('\t','')

            print(str(datetime.now()) + ' ' + name)

            sleep(randint(3,7))
            r = self.session.get(url,headers=headers)
            if self.check_block(r):
                r = self.session.get(url,headers=headers)

    def search_users(self,name):
        token = self.get_token()
        url = main_url + f'/members/find?q={name}n&_xfRequestUri=%2Fconversations%2Fadd%3Fto%3DRUTOR&_xfWithData=1&_xfToken={token}&_xfResponseType=json'

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        return json.loads(r.text)

    def get_hash(self):
        url = main_url + '/conversations/add'

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        return re.findall('_hash" value="([^"]{1,})',r.text)[0]

    def upload_file(self,file='DFF681-DC-EEF7-422-A-97-E9-ADD76-D37-DF9-F.jpg'):
        token = self.get_token()
        hash = self.get_hash()

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0',
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Language': 'en-US,en;q=0.5',
            # 'Accept-Encoding': 'gzip, deflate',
            'Referer': f'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion/attachments/upload?type=conversation_message&hash={hash}',
            'X-Requested-With': 'XMLHttpRequest',
            'Content-Type': 'multipart/form-data; boundary=---------------------------156277210038657417371957125884',
            'Origin': 'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion',
            'Connection': 'keep-alive',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
        }

        params = {
            'type': 'conversation_message',
            'hash': hash,
        }

        data = f'-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="_xfToken"\r\n\r\n{token}\r\n-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="upload"; filename="{file}"\r\nContent-Type: image/jpeg\r\n\r\n-----------------------------156277210038657417371957125884--\r\n'

        response = self.session.post(
            main_url + '/attachments/upload',
            params=params,
            headers=headers,
            data=data,
        )

        print(f'{main_url}/attachments/upload?type=conversation_message&hash={hash}')
        return response

def main():
    bot = spy()

    #posts = bot.posts()
    #save_csv('part_one.csv',posts)

    bot.eye()
    #self.upload_file('file.txt')

if __name__ == "__main__":
    main()
 
Написал скорее для форума, чтобы пофиксили что-то. Ну и для юзеров, чтобы понимали, что все на виду.
 
Да разумеется, закрытых тоже чекает. Проверял на админе RUTOR.

Для этого вверху впиши нужный айди юзера. Для твоего аккаунта к примеру это target_userid = '387766'
И раскомментируй внизу скрипта.
posts = bot.posts()
save_csv('part_one.csv',posts)



К примеру 10 страниц акка PANDORA приложил.
Сообщение обновлено:


Пора:-8
Понял , а в чем смысл этого ?
 
Понял , а в чем смысл этого ?
Смысл в сборе информации связанной с юзером. Человек хочет сохранить какое-то инкогнито и закрывает профиль. Тем не менее скрипт собирает инфу по ссылке с айди.

Использование разнообразно, анализ стиля речи, выяснение деталей для составления профиля личности, сравнение с другими пользователями или же постами в совершенно других сетях для корреляции.

Чем больше постов тем больше вероятность, того что пользователь где-то накосячил и сам слил лишнюю инфу о себе.
 
Смысл в сборе информации связанной с юзером. Человек хочет сохранить какое-то инкогнито и закрывает профиль. Тем не менее скрипт собирает инфу по ссылке с айди.

Использование разнообразно, анализ стиля речи, выяснение деталей для составления профиля личности, сравнение с другими пользователями или же постами в совершенно других сетях для корреляции.

Чем больше постов тем больше вероятность, того что пользователь где-то накосячил и сам слил лишнюю инфу о себе.
Да все уже сдианонены давно бро , просто не ищют и не принимают кормятся , исходя из того что биткойн полностью отслеживаемый до Фиата , а кат дроп без разницы , везде камеры и не только и другие параметры индедификаторы на купюрах . Захотят найти найдут , опыт у Русских такой же как у иностранных коллег по деанону. Не чего не делают потому что доля с наркобизнеса с всех регионов идёт в РФ депутатам ) ты знал что анализ биткойн транзакции устанавливает твой реальный айпи в обход ВПН и всех шифров ?)
 
ты знал что анализ биткойн транзакции устанавливает твой реальный айпи в обход ВПН и всех шифров ?)
Не айпи, а связь с личностью если не использовать миксеры и прочее. Это логично, что финансовые следы всегда опасны. Особенно в открытых блокчейнах
Поэтому надо использовать монеро
 
Это пока что первая статья, где я ничего не понял) от слова совсем)
 
Я думаю , примерно также трехбуквенные люди собирают инфу о своих пациентах:-8
 
Для меня это темный лес
 
Изучаем Xenforo на примере Rutor (Python,OSINT)

В большинстве своем сейчас многие популярные форумы используют используют движок Xenforo.
Как таковых известных уязвимостей в нем нет. Или я пока не нашел)
Однако в этой статьи мы рассмотрим интересные особенности, которые позволяют получать открытую доп информацию о юзерах и еще кое-что по мелочи.

Также будут написаны скрипты для автоматизации вышеуказанных действий. Капчу обходить не стал, может в другой раз. На данный момент берем кукисы с браузера.


Часть 1 - Собираем историю всех постов юзера. Даже если закрыто в приватности.

Продемонстрирую на примере пользователя ADMIN.
Если перейти конкретно на ссылку профиля , то мы увидим баннер о том, что пользователь закрыл доступ к своей истории. Однако перейдя по подобной ссылке, где вписан айди юзера из первой. Мы видим все посты.
/search/member?user_id=88013


На одной из страниц мы видим интересную информацию о том, за сколько и примерно когда был продан форум. Инфа известная, но далеко не всем. Это как пример sensitive information.

Напишем небольшой скрипт для сбора постов. Чтобы взять кукисы из браузера заходим в раздел браузера инструменты веб разработчика и смотрим любой запрос в разделе сеть. Правой кнопкой жмем и копируем кукисы, как CURL. Далее используем библиотеку uncurl чтобы перевести их в формат python request.
В консоли python print(uncurl.parse("""ваш с браузера запрос"""))
Добавляем их вверх скрипта в переменную cookies.

Необходимые зависимости pip3 install lxml cssselect requests

Python:
  def posts(self,userid=target_userid):

        url = main_url + f'/search/member?user_id={userid}'

        print(url)

        posts = []


        headers={

            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",

            "Accept-Encoding": "gzip, deflate",

            "Accept-Language": "en-US,en;q=0.5",

            "Connection": "keep-alive",

            "Referer": main_url,

            "Sec-Fetch-Dest": "document",

            "Sec-Fetch-Mode": "navigate",

            "Sec-Fetch-Site": "same-origin",

            "Sec-Fetch-User": "?1",

            "Upgrade-Insecure-Requests": "1",

            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"

        }


        r = self.session.get(url,headers=headers)

        if self.check_block(r):

            r = self.session.get(url,headers=headers)


        tree = etree.HTML(r.text)

        newurl = r.url

        num = tree.cssselect('li.pageNav-page:nth-child(5) > a:nth-child(1)')[0].get('href').split('=')[-1]


        posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]


        for i in range(2,int(num)+1):

            sleep(randint(5,TIMEOUT))

            url = newurl + f'?page={i}'


            print(url)

            r = self.session.get(url,headers=headers)

            if self.check_block(r):

                r = self.session.get(url,headers=headers)


            tree = etree.HTML(r.text)

            posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]


        return posts

Для парсинга ответов, мы используем библиотеку lxml. Также случайные таймауты. Выводим на экран И сохраняем в csv формат в файл part_one.csv

Теперь достаточно вписать в target_userid id юзера посты которого мы хотим сохранить и готово. У вас должен быть включен тор в системе. Если браузер, то порт будет 9150,если демон то 9050. В ubuntu - sudo apt install tor

И получаем статистику всех постов с датой, названием, и разделом. Переодически нас будет останавливать блок от анти ддоса. Благо он легко обходится сменой identity tor, учел в коде. Кукисы работают на новой сессии всегда автоматом. Также выставлены длительные таймауты.

Посмотреть вложение 829562

Python:
[{'title': 'Комната грязи.',
  'forum': 'Форум: ОКНА с Пшекой Шпековой',
  'text': 'Смотрю уже берега конкретно стали путать. Спор был решен в личке. Сейчас решили продолжить срать. Мне че заняться больше нечем, ждать пока кто-то там что-то заскринит. Пойдика ты тоже голову свою остуди на сутки. Продолжите этот безсмысленный срач - сотру двоих спамом и аккаунты удалю',
  'date': 'Пятница в 22:04'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Кидай. Уже заказываю',
  'date': 'Пятница в 18:17'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Ну только если один подарок, для закатывания...',
  'date': 'Пятница в 14:02'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Я смотрю опыт прошлых пользователь ни к чему не привел?',
  'date': 'Понедельник в 22:38'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'По поводу игр в слова. Если и вправду интересно играть в слова, то продолжат играть и с выключенным счетчиком. А если эти темы используются только ради набивки сообщений, чтобы твинком вскочить на рулетку, то ясное дело не интересно будет.',
  'date': '1 Апр 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Это не тема для обсуждений. Тут только можете высказать свои предложения!',
  'date': '1 Апр 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Скоро, очень скоро...',
  'date': '29 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'А то что потерялся смысл счетчиков сообщений, тебя не смущает?',
  'date': '29 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Скоро будут пересмотрены все темы, в которых использовалась накрутка счетчиков сообщений и соответственно реакций.\nКогда будет готов маркет подписей, все счетчики сообщений будут приведены в порядок. Чтобы было видно, кто форумом живет и реально принимает активную позицию в его жизни. А кто...',
  'date': '28 Мар 2023'},
 {'title': 'NFT Collection RuTOR 2023',
  'forum': 'Форум: Новости форума RuTOR',
  'text': 'Коллекция - https://getgems.io/collection/EQAT6Rc1v_REhfHLkJ7QC9PAt_EbRB3K1517Kp0qpUSCJTzs?filter=%7B%22sort%22%3A%22LikesCountDesc%22%7D',
  'date': '28 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Статус приобретается не для красоты, а чтобы было видно, какую комерческую деятельность ведет пользователь.',
  'date': '28 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Зачем? Чтобы увешаться ими?',
  'date': '28 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Какие именно?',
  'date': '27 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Подразумевает то, что пользователи смогут выкладывать свои подписи под сдачу типо как на витрину и магазины автоматом смогут их покупать на тот срок, который им нужен. Пользователь сам не сможет снять или отредактировать эту подпись, пока не пройдет срок аренды.',
  'date': '27 Мар 2023'},
 {'title': 'Чем вызвано твое удивление?',
  'forum': '22 Мар 2023',
  'text': 'Чем вызвано твое удивление?',
  'date': '22 Мар 2023'},
 {'title': 'Я не пойму, вы тут что митинг устроить решили?',
  'forum': '21 Мар 2023',
  'text': 'Я не пойму, вы тут что митинг устроить решили?',
  'date': '21 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Для того чтобы накупили те, кто не имеет отношение к данным сервисам?',
  'date': '20 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Приветствую. У подтвержденного сейчас 4е строчки подписи. В планах ввести своебразный маркет подписей. Сейчас готовятся другие, более важные обновления.',
  'date': '18 Мар 2023'},
 {'title': 'Предложения и пожелания по работе форума',
  'forum': 'Форум: Вопросы и предложения к команде RuTOR',
  'text': 'Некоторые решения требуют больше времени',
  'date': '14 Мар 2023'},
 {'title': 'Авторское руководство по заработку на МФО',
  'forum': 'Форум: Платно',
  'text': 'Закрыто на проверку. По поводу проверки пиши @Berlusconi',
  'date': '9 Мар 2023'}]
Посмотреть вложение 829563


Часть 2 - Небольшие мелочи. Форум, как файлохранилище. Поиск юзеров по нику.

Давайте зайдем в раздел создания личных сообщений.

Там можно найти такую интересную ссылку
/attachments/upload?type=conversation_message&hash=

Которая позволит нам загружать файлы на сервер. Без привязки их к конкретному диалогу. Потом по прямой ссылке можно иметь доступ к ним. Удобно хранить картинки, лол.

Python:
    def upload_file(self,file='DFF681-DC-EEF7-422-A-97-E9-ADD76-D37-DF9-F.jpg'):
        token = self.get_token()
        hash = self.get_hash()

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0',
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Language': 'en-US,en;q=0.5',
            # 'Accept-Encoding': 'gzip, deflate',
            'Referer': f'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion/attachments/upload?type=conversation_message&hash={hash}',
            'X-Requested-With': 'XMLHttpRequest',
            'Content-Type': 'multipart/form-data; boundary=---------------------------156277210038657417371957125884',
            'Origin': 'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion',
            'Connection': 'keep-alive',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
        }

        params = {
            'type': 'conversation_message',
            'hash': hash,
        }

        data = f'-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="_xfToken"\r\n\r\n{token}\r\n-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="upload"; filename="{file}"\r\nContent-Type: image/jpeg\r\n\r\n-----------------------------156277210038657417371957125884--\r\n'

        response = self.session.post(
            main_url + '/attachments/upload',
            params=params,
            headers=headers,
            data=data,
        )

        print(f'{main_url}/attachments/upload?type=conversation_message&hash={hash}')
        return response
```
Посмотреть вложение 829566

Далее, с помощью подобной ссылки /members/find?q=goodn&_xfRequestUri=%2Fconversations%2Fadd%3Fto%3DRUTOR&_xfWithData=1&_xfToken=&_xfResponseType=json мы можем производить поиск юзеров по части никнейма. Может быть достаточно полезно. Разумеется у нас должен предварительно получен xfToken. Это не проблема.
Выдергиваем его с помощью regexp с любой страницы.

Python:
    def search_users(self,name):
        token = self.get_token()
        url = main_url + f'/members/find?q={name}n&_xfRequestUri=%2Fconversations%2Fadd%3Fto%3DRUTOR&_xfWithData=1&_xfToken={token}&_xfResponseType=json'

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        return json.loads(r.text)
Посмотреть вложение 829567


Часть 3 - Анализируем статистику переходов юзера по форуму.

Немногие отключают в своем профиле доступ для всех. Или конкретно показ статистики посещений тем.
Это кажется незначительной вещью. Но все же все эти моменты, могут выдать больше информации о вас чем вам бы хотелось.

Предположим посещение определенных тем по регионам, указывает на город пользователя. Посещение конкретных услуг или тематик указывает на интересы пользователя. Кроме этого возможное посещение новостных тем тоже позволяет составить интересную картину.

Естественно для этого надо собрать статистику, чем мы сейчас и займемся. Скрипт написан на примере одного юзера и одного потока, но разумеется можно распараллелить в будущем.

Посмотреть вложение 829565
Python:
    def eye(self,userid=target_userid):
        url = main_url + f'/members/{userid}'
        print(url)

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        while True:
            tree = etree.HTML(r.text)
            name = ''.join(tree.cssselect('.memberHeader-blurb')[-1].itertext()).strip().replace('\t','')

            print(str(datetime.now()) + ' ' + name)

            sleep(randint(3,7))
            r = self.session.get(url,headers=headers)
            if self.check_block(r):
                r = self.session.get(url,headers=headers)
```


Полный скрипт бота со всеми функциями приложен внизу статьи.

-------------------------------
PS:
В статье мы затронули относительно безобидные вещи. Без брутов, обходов капч и прочих шалостей.
Мораль статьи в том, чтобы следить за вашей приватностью, как на уровне отдельного пользователя. Так и на уровне самого форума. Использование крупных движков оставляет множество нюансов. Даже малейшая деталь может дать наблюдателю важные сведения о вашей фигуре. Это может быть неактуально для рядового пользователя, но являться очень серьезным для других фигур.

Помните о безопасности и да пребудет с вами сила!

Python:
import requests
import socks,socket
from random import randint
from time import sleep
from lxml import etree
import os,csv,re
from datetime import datetime
import json

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0'
}

cookies={
    "":"",
    }

main_url = 'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion'
#target_userid = '88013'
target_userid = '354635'

TIMEOUT = 20

def save_csv(file,dicts):
    with open(f'{file}', mode='w', newline='') as file:
        fieldnames = list(dicts[0].keys())
        writer = csv.DictWriter(file, fieldnames=fieldnames, delimiter=';')

        writer.writeheader()

        for d in dicts:
            print(d)
            writer.writerow(d)


def reload_tor():
    print('Рестартим тор сессию')
    os.system('sudo service tor reload')

class spy:

    def __init__(self):
        self.session = requests.Session()
        self.session.headers = headers

        self.session.proxies = {
            'http': 'socks5h://localhost:9050',
            'https': 'socks5h://localhost:9050'
        }

        self.session.cookies.update(cookies)

    def get_token(self):
        url = main_url + '/whats-new/news-feed'

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)


        return re.findall('_xfToken" value="([^"]{1,})',r.text)[0]


    def parse_one(self,el):
        one = {}

        dop = [n for n in ''.join(el.cssselect('.contentRow-minor')[0].itertext()).strip().split('\t') if n != '']

        try:
            one['title'] = ''.join(el.cssselect('.contentRow-title')[0].itertext()).strip()
            one['forum'] = dop[-1]
            one['text'] = ''.join(el.cssselect('.contentRow-snippet')[0].itertext()).strip()
            one['date'] = dop[2].rstrip()
        except Exception as msg:
            print(msg)
            return {}

        return one

    def check_block(self,r):
        if 'DDOS fliter' in r.text:
            reload_tor()
            sleep(5)
            return True
        else:
            return False

    def posts(self,userid=target_userid):
        url = main_url + f'/search/member?user_id={userid}'
        print(url)
        posts = []

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        tree = etree.HTML(r.text)
        newurl = r.url
        num = tree.cssselect('li.pageNav-page:nth-child(5) > a:nth-child(1)')[0].get('href').split('=')[-1]

        posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]

        for i in range(2,int(num)+1):
            sleep(randint(5,TIMEOUT))
            url = newurl + f'?page={i}'

            print(url)
            r = self.session.get(url,headers=headers)
            if self.check_block(r):
                r = self.session.get(url,headers=headers)

            tree = etree.HTML(r.text)
            posts += [self.parse_one(one) for one in tree.cssselect('.block-container .block-body li .contentRow-main') if self.parse_one(one) != {}]

        return posts

    def eye(self,userid=target_userid):
        url = main_url + f'/members/{userid}'
        print(url)

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        while True:
            tree = etree.HTML(r.text)
            name = ''.join(tree.cssselect('.memberHeader-blurb')[-1].itertext()).strip().replace('\t','')

            print(str(datetime.now()) + ' ' + name)

            sleep(randint(3,7))
            r = self.session.get(url,headers=headers)
            if self.check_block(r):
                r = self.session.get(url,headers=headers)

    def search_users(self,name):
        token = self.get_token()
        url = main_url + f'/members/find?q={name}n&_xfRequestUri=%2Fconversations%2Fadd%3Fto%3DRUTOR&_xfWithData=1&_xfToken={token}&_xfResponseType=json'

        headers={
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive",
            "Referer": main_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
        }

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        return json.loads(r.text)

    def get_hash(self):
        url = main_url + '/conversations/add'

        r = self.session.get(url,headers=headers)
        if self.check_block(r):
            r = self.session.get(url,headers=headers)

        return re.findall('_hash" value="([^"]{1,})',r.text)[0]

    def upload_file(self,file='DFF681-DC-EEF7-422-A-97-E9-ADD76-D37-DF9-F.jpg'):
        token = self.get_token()
        hash = self.get_hash()

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0',
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Language': 'en-US,en;q=0.5',
            # 'Accept-Encoding': 'gzip, deflate',
            'Referer': f'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion/attachments/upload?type=conversation_message&hash={hash}',
            'X-Requested-With': 'XMLHttpRequest',
            'Content-Type': 'multipart/form-data; boundary=---------------------------156277210038657417371957125884',
            'Origin': 'http://rutordarkgwkpgdo4fpes7dneu7yxoacozztslvcjcw6zhhlajiom3ad.onion',
            'Connection': 'keep-alive',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
        }

        params = {
            'type': 'conversation_message',
            'hash': hash,
        }

        data = f'-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="_xfToken"\r\n\r\n{token}\r\n-----------------------------156277210038657417371957125884\r\nContent-Disposition: form-data; name="upload"; filename="{file}"\r\nContent-Type: image/jpeg\r\n\r\n-----------------------------156277210038657417371957125884--\r\n'

        response = self.session.post(
            main_url + '/attachments/upload',
            params=params,
            headers=headers,
            data=data,
        )

        print(f'{main_url}/attachments/upload?type=conversation_message&hash={hash}')
        return response

def main():
    bot = spy()

    #posts = bot.posts()
    #save_csv('part_one.csv',posts)

    bot.eye()
    #self.upload_file('file.txt')

if __name__ == "__main__":
    main()
Шалость удалась, спасибо было интересно
 
Спасибо)))) Будь многоликий! В плане общения, везде.
 
Последнее редактирование:
Это что, привет с 2003?
Сообщение обновлено:

Ты бы лучше написал что значит для пользователей вот эта хуйня

2.png
1.png
 
Последнее редактирование:

Похожие темы

Начните зарабатывать на создании автономных агентов на Python, работающих на основе искусственного интеллекта. AI будет работать именно на вас Курс рекомендован: Бизнесменам и манимейкерам Если вы не можете позволить себе нанять команду менеджеров, маркетологов, аналитиков и программистов, то...
Ответы
0
Просмотры
428
Всех приветствуем! Мы команда «Мой Пробив» @punchosint_bot (OSINT-бот в телеграмме). Нашему проекту 2 месяца и сегодня мы расскажем наш личный опыт в сфере SMM. В проекте участвует приглашенный SMM специалист с 5-ти летним опытом работы НЕ в даркнете. Далее рассказ будет от его лица. Когда...
Ответы
10
Просмотры
Слив курса How to Code - Web3 автоматизация на Python [Ahillary] Наш курс будет поделён на 3 основные части: Python c нуля - мы будем изучать основы самого языка Web3, основы - это самая главная часть, внутри которой мы будем учиться автоматизировать web3 процессы Web3, допчасть - как понятно...
Ответы
1
Просмотры
703
Здравствуйте. Редко участвую в конкурсах, однако вот. Решил расписать вам технологию изготовления мной, специального решения автопродаж. Написано с нуля, и решает все основные вопросы, которые нужны для подобного типа решений.Это будут бот(ы) для телеграм и удобная веб админка для управления...
Ответы
13
Просмотры
Переносной модем-телефон с изменением IMEI. Это пособие не нарушает УК РФ, но в других странах изменение IMEI может быть уголовно-наказуемо. Будьте осторожны. Речь пойдет об изменении IMEI на телефонах Nokia (KaiOS) модельного ряда - 8110 4g. Nokia 6300 4G. 2720 Flip 4g. либо 800 Tough 4g. ...
Ответы
38
Просмотры
Назад
Сверху Снизу