Open-source project
baderj/domain_generation_algorithms avatar
baderj/domain_generation_algorithms

domain_generation_algorithms re-implements malware DGA families in Python

Some results of my DGA reversing efforts

691 stars162 forksPythonGPL-2.0

At a glance

What is it?
This repository is the output of one analyst's reversing work: one directory per malware family, each with a Python re-implementation of that family's domain generation algorithm, and a README that indexes the families with example domains and links to the write-ups. It is a research archive, not a detection product, and it is only as current as the write-ups it was built from.
Who is it for?
Adopt this repository when you work on sinkholing, blocklist generation or DGA detection and you need a faithful local implementation of a specific family, or when you want to compare families by reading their algorithms side by side. Do not adopt it as a general detection engine, since it produces domains rather than finding them, and it contains no feed, no resolver and no alerting.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 141 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One directory per malware family

The repository description is deliberately modest: some results of my DGA reversing efforts. The README expands it to Domain Generation Algorithms of Malware reimplemented in Python, and the top level directory listing shows how the work is organised. There is a folder per family, and among them `banjori/`, `bazarbackdoor/`, `bumblebee/`, `charbot/`, `chinad/`, `corebot/`, `darkcracks/`, `dircrypt/`, `dmsniff/`, `dnschanger/`, `expiro/`, `fobber/`, `fosniw/`, `gozi/`, `kraken/`, `locky/`, `m0yv/`, `monerodownloader/`, `murofet/`, `mydoom/`, `necurs/`, `newgoz/`, `ngioweb/`, `nymaim/`, `nymaim2/`, `orchard/`, `padcrypt/`, `pitou/`, `pizd/`, `proslikefan/`, `pushdo/`, `pykspa/`, `qadars/`, `qakbot/`, `qsnatch/`, `ramdo/`, `ramnit/`, `ranbyus/`, `reconyc/`, `sharkbot/`, `shiotob/`, `simda/`, `sisron/`, `suppobox/`, `symmi/`, `tempedreve/`, `tinba/`, `tufik/`, `unnamed_downloader/`, `unnamed_javascript_dga/`, `vawtrak/`, `verblecon/` and `zloader/`.

That is a catalogue of around fifty families, each of which was a real incident at some point, and the licensing is GPL-2.0 with a LICENSE file at the root.

The interesting division of labour is that the algorithms live in code and the explanation lives in the README. For a family with published research, the README gives a link to that write-up and a handful of example domains. The domains are inert strings, and they are the fastest way to see what a given algorithm produces.

The README is an index of families, links and sample output

Each family gets a collapsible section with a Links entry and an Example Domains list. The links point at the research that the re-implementation is based on, and they are consistently specific.

For `banjori`, also known as MultiBanker 2 and BankPatch(er), the link is to a 2015 write-up on the DGA of banjori, and the example domains show the shape of the output:

code
- earnestnessbiophysicalohax.com
- kwtoestnessbiophysicalohax.com
- rvcxestnessbiophysicalohax.com

For `corebot`, the link is to a September 2015 analysis, and the domains are random looking strings under a dynamic DNS provider:

code
- lkhylm0mhyfuhg.ddns.net
- s63234wluv5v365bwp5.ddns.net
- afe6mfy23xcxgfa.ddns.net

`dircrypt` links to a March 2015 analysis with plain consonant heavy domains, `dnschanger`, also known as Alureon, links to a January 2016 write-up, `gozi`, also known as Ursnif, Snifula and Papras, links to a government CERT blog post, and `locky` links to a Forcepoint security labs post about Locky's new DGA.

So the repository is a bridge between a paper and a script. If you want to know why a family generates what it generates, the README points you at the answer, and if you want to see it generate, the directory has the code.

A buggy algorithm gets its own section

The `bazarbackdoor` entry, also known as BazarLoader Team9Backdoor, is the most instructive section in the README, because it separates a working algorithm from a broken one.

The example domains are listed under two headings, Real DGA and Buggy DGA. The real ones look like the output of a normal algorithm:

code
- adegjkaiggjm.bazar
- eehhjmejjhjo.bazar
- dehiildjjiin.bazar

The buggy ones are different in a way that is not random. They are prefixed with escape characters and use a different suffix, and the README's links point to two separate write-ups, one on the DGA of bazarbackdoor and one on the buggy DGA of bazarbackdoor, plus a third on yet another BazarLoader DGA.

This is the kind of detail that a detection engineer actually needs. A blocklist built only from the real algorithm misses every domain the broken variant produced, and a broken variant that emits a leading backslash is a signature in itself. Re-implementing the family locally, as this repository does, is what makes it possible to generate both sets and see the difference rather than trusting a list someone published.

m0yv separates the time-independent and time-dependent versions

The `m0yv` entry is the one that shows the structure of the code rather than the output.

The README notes that the time independent version is in `dga.py` and the time-dependent version is in `dga-td.py`. That is a meaningful distinction for a domain generation algorithm. A time-independent algorithm derives its domain from a fixed seed, so the same set of domains comes out every time. A time-dependent one mixes the current time into the seed, so the domain set changes with the clock, and that is what lets a bot keep reaching new infrastructure while the defender's list ages.

The links here point to a malpedia entry for the family and to a video titled Sinkholing the Domain Generation Algorithm of m0yv, which is the defensive framing of the whole exercise. Sinkholing means registering the domains the algorithm will produce so that the malware's requests land on a server you control. Doing that well requires knowing the algorithm exactly, including its time dependence, and the example domains in the README show the shape of the output:

code
- pywolwnvd.biz
- ssbzmoy.biz
- cvgrf.biz

The `monerodownloader` entry shows a different pattern again, with a fixed label carried across several suffixes:

code
- 31b4bd31fg1x2.org
- 31b4bd31fg1x2.tickets
- 31b4bd31fg1x2

The sample domains reveal the algorithm families

Reading the example lists side by side is the quickest way to see how many different shapes a DGA can take, and the README is long enough to show a good spread.

Some families are dictionary based. The `gozi` domains are Latin words strung together, such as `quodpresidentemaxsagit.com` and `pertantumfitusu.com`, which is a direct consequence of a word list plus a length limit. The `banjori` domains are the same trick, with a fixed suffix glued to varying leading text.

Some are counters. The `fosniw` entry lists `app2.winsoft0.com` through `app2.winsoft9.com`, an enumeration rather than a hash.

Some are structured random strings. The `bumblebee` domains are short alphanumeric labels under a single suffix, `cmid1s1zeiu.life` and `3v1n35i5kwx.life`, and the `chinad` domains spread across several suffixes, `.cn`, `.ru`, `.info`, `.net` and `.biz`, which is a way of making a single algorithm harder to block on one suffix.

The `locky` family is notable for how many suffixes it rotates through, `.tf`, `.yt`, `.us`, `.be`, `.pm`, `.it`, `.ru` and `.uk` in the sample list.

And the two `kraken` versions are filed separately, `kraken/v1` and `kraken/v2`, both linked to the same write-up about Kraken's two domain generation algorithms, with visibly different output shapes, the first using shared suffixes such as `mooo.com` and `dyndns.org` and the second producing plain label and suffix pairs. The README's own note on `darkcracks` shows a mixed-case pattern, `sTDFUgOAgjL.com`, which is another way of making a generated string look unlike a hash.

How you would actually use the archive

There are no install instructions in the README, and there is no packaging, no test suite and no continuous integration in the top level entries, which are the family directories plus the README and the LICENSE file. So the practical route is to clone the repository and use the scripts in the family directory you care about.

The intended use is the one the links point to: you need the algorithm to generate what the malware would generate, either to register the domains ahead of time so that the traffic lands somewhere you control, or to build a detection signature, or to hunt historically through logs for domains that match the pattern.

That is also where the limits are. The repository covers the families someone has already reversed and written up, and the top level directory list is longer than the README's documented set, so the coverage is uneven. A family that was never analysed is not there, and a family analysed in 2015 reflects the algorithm as it was in 2015, which is often exactly the point of these algorithms, since malware families change them to shake off blocklists.

The README also shows that the re-implementations are not always faithful in the way you might want. The buggy bazarbackdoor variant is preserved as a separate output, which is the right call for detection, but it means you cannot assume a directory produces one clean stream of domains.

Editorial conclusion

Adopt this repository when you work on sinkholing, blocklist generation or DGA detection and you need a faithful local implementation of a specific family, or when you want to compare families by reading their algorithms side by side. Do not adopt it as a general detection engine, since it produces domains rather than finding them, and it contains no feed, no resolver and no alerting. Verify first which families the repository actually covers, since the top level lists about fifty directories while the README documents only a subset, and check the age of the specific family you care about, because the newest release tag is v1.0.0 from 2018-03-29 and the last push was on 2026-06-04.

Frequently asked questions

What is the domain_generation_algorithms repository?

It holds Python re-implementations of the domain generation algorithms used by malware, one directory per family, and is described as the results of the author's DGA reversing efforts. The README indexes the families with links to the published research and lists of example domains for each.

How do I use these DGA implementations?

The README documents no installation step and the repository has no packaged entry point, so the practical route is to clone it and run the script in the family directory you need, for example dga.py for the time-independent m0yv version and dga-td.py for the time-dependent one. The intended use is generating candidate domains for sinkholing, blocking or hunting.

Which malware families are covered?

The top level has roughly fifty family directories, including banjori, bazarbackdoor, bumblebee, chinad, corebot, darkcracks, dircrypt, dnschanger, fobber, fosniw, gozi, kraken, locky, m0yv, murofet, mydoom, necurs, pykspa, qakbot, ramnit, vawtrak and zloader, while the README documents a smaller subset with links and example domains.

Why does the README list both a real and a buggy DGA for bazarbackdoor?

The bazarbackdoor entry separates the working algorithm's output from a broken variant that emits escape characters and a different suffix, and it links to separate write-ups for the DGA of bazarbackdoor, the buggy DGA of bazarbackdoor and yet another BazarLoader DGA. Keeping both is what lets a detection effort cover the domains the broken variant produced.

Official sources

  1. baderj/domain_generation_algorithms on GitHub
  2. Issues
  3. License: GPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/baderj-domain-generation-algorithms.svg)](https://hysenlabs.com/projects/baderj-domain-generation-algorithms)

Was this useful?