/ghostseeder

Python script to spoof seeding of torrent files on private trackers

Primary LanguagePython

Ghostseeder

GitHub CI

This Python script spoofs seeding of torrent files to private trackers by sending fake announces.

Private trackers usually reward bonus points for seeding a lot of torrents. But at the same time, trackers don't have an explicit way to verify you actually have the files

Setup

Tested with Python v3.9+

$ git clone https://github.com/jephdo/ghostseeder.git
$ python -m pip intall .
$ python -m ghostseeder --help
usage: __main__.py [-h] -f FOLDER [-p [PORT]] [-v VERSION]

Enter path to a directory of torrent files

optional arguments:
  -h, --help            show this help message and exit
  -f FOLDER, --folder FOLDER
                        A directory containing `.torrent` files. Torrent files should be from a private tracker and the announce url should contain your unique passkey
  -p [PORT], --port [PORT]
                        The port number announced to the tracker to receive incoming connections. Used if you want to change the port number announced to the tracker. Optional, defaults to `6881`
  -v VERSION, --version VERSION
                        The version of qBittorrent that you want to announce to the tracker. This info is used to generate the peer id and user agent string. Setting `-v '3.3.16'` will use qBittorrent
                        v3.3.16. Optional, defaults to `'4.3.9'`
  -r MAX_REQUESTS, --max-requests MAX_REQUESTS
                        Maximum number of allowed HTTP announces per second. Useful especially at startup to mitigate sending a large burst of announces at once.
  -s SEED, --seed SEED  Optional random seed used to make peer-id generation deterministic

Script will announce itself as a qBittorrent client

Example Usage

Add torrent files to a folder:

$ tree torrents/
torrents/
├── archlinux-2022.11.01-x86_64.iso.torrent
├── freebsd
│      ├── FreeBSD-11.4-RELEASE-amd64-disc1.iso.torrent
│      ├── FreeBSD-12.2-RELEASE-amd64-disc1.iso.torrent
│      └── FreeBSD-13.1-RELEASE-amd64-disc1.iso.torrent
└── ubuntu-22.10-desktop-amd64.iso.torrent

1 directory, 5 files
$ python cli.py -f torrents/

The script will search for all .torrent files in the folder passed to it. For example, run this on your server/seedbox:

$ nohup python -m ghostseeder -f torrents/ &>> output.log &

This will run the script in the background and store logs in output.log

Example output

$ python -m ghostseeder -f torrents/ -p 59097
2023-03-10 21:48:30 INFO     Generating torrent client peer id: -qB4450-OcPetHlvbFeW
2023-03-10 21:48:30 INFO     Searching for torrent files located under 'torrents/'
2023-03-10 21:48:30 INFO     Found 5 torrent files
2023-03-10 21:48:30 INFO     Reading and parsing torrent files...
2023-03-10 21:48:30 INFO     Finished reading in torrent files
2023-03-10 21:48:30 INFO     Tracker announces will use the following settings: (port=59097, peer_id='-qB4450-OcPetHlvbFeW', user-agent='qBittorrent/4.4.5')
2023-03-10 21:48:31 INFO     Announcing ubuntu-22.10-desktop-amd64.iso 
2023-03-10 21:48:31 INFO     Re-announcing (#1) ubuntu-22.10-desktop-amd64.iso in 1800 seconds...
...

Example Docker Usage

A Dockerfile is provided and you can run the script as a Docker container by attaching a volume containing torrent files. You can specify optional environment variables to change the port and qBittorrent version:

$ docker build --tag ghostseeder-docker .
$ docker run --name ghostseeder --volume ./torrents:/torrents --detach --env PORT=59097 --env VERSION=4.4.5 ghostseeder-docker

Details of this script

Every private torrent has an announce url to the tracker containing a unique passkey (e.g. https://flacsfor.me/123456789abcdefg37ss9t0awe3dlyqs/announce). When a torrent client begins seeding a torrent, it uses this url to send parameters describing the current state of the torrent (including how much has been downloaded and uploaded). All information about the torrent is self-reported by the client.

Key request parameters to modify are info_hash and left. info_hash identifies the specific torrent and left states how many bytes needed to finish downloading the torrent. This script repeatedly sends HTTP requests to the tracker, setting left=0, declaring to the tracker that you are actively seeding the torrent:

GET https://flacsfor.me/123456789abcdefg37ss9t0awe3dlyqs/announce?info_hash=%D5E%DB%06v%15D%8CLx%21%3B%C5v%1DNf%8E%1B4&peer_id=-qB4450-OcPetHlvbFeW&uploaded=0&downloaded=0&left=0&compact=1&port=6881

More details on the HTTP protocol between trackers and peers here