├── doc ├── VERSION └── LICENSE ├── .travis.yml ├── .gitignore ├── txt ├── logo.txt └── archive_formats.txt ├── license ├── code-of-conduct.md ├── readme.md ├── termcolor.py └── dymerge.py /doc/VERSION: -------------------------------------------------------------------------------- 1 | 0.2 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.6" 4 | - "2.7" 5 | script: 6 | - python -c "import dymerge; import termcolor;" 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | env/ 2 | build/ 3 | develop-eggs/ 4 | dist/ 5 | downloads/ 6 | eggs/ 7 | .eggs/ 8 | lib/ 9 | lib64/ 10 | parts/ 11 | sdist/ 12 | var/ 13 | *.egg-info/ 14 | *.egg 15 | *.manifest 16 | *.spec 17 | pip-log.txt 18 | pip-delete-this-directory.txt 19 | .scrapy 20 | target/ 21 | .python-version 22 | venv/ 23 | ENV/ 24 | *.pyc 25 | *.tmp 26 | *.bak 27 | *.cfg 28 | -------------------------------------------------------------------------------- /txt/logo.txt: -------------------------------------------------------------------------------- 1 | ____ 2 | /\ _`\ /'\_/`\ 3 | \ \ \/\ \ __ __/\ \ __ _ __ __ __ 4 | \ \ \ \ \/\ \/\ \ \ \__\ \ /'__`\/\` __\/'_ `\ /'__`\ 5 | \ \ \_\ \ \ \_\ \ \ \_/\ \/\ __/\ \ \//\ \_\ \/\ __/ 6 | \ \____/\/`____ \ \_\\ \_\ \____\\ \_\\ \____ \ \____\ 7 | \/___/ `/___/ \/_/ \/_/\/____/ \/_/ \/____\ \/____/ 8 | /\___/ /\____/ 9 | \/__/ Made with <3 by k4m4 \_/__/ 10 | -------------------------------------------------------------------------------- /txt/archive_formats.txt: -------------------------------------------------------------------------------- 1 | .7z 2 | .??_ 3 | .?Q? 4 | .?Z? 5 | .F 6 | .Z 7 | .ace 8 | .afa 9 | .alz 10 | .apk 11 | .arc 12 | .arj 13 | .b1 14 | .ba 15 | .bh 16 | .bz2 17 | .cab 18 | .car 19 | .cfs 20 | .cpt 21 | .dar 22 | .dd 23 | .dgc 24 | .dmg 25 | .ear 26 | .ecc 27 | .gca 28 | .gz 29 | .ha 30 | .hki 31 | .ice 32 | .infl 33 | .jar 34 | .kgb 35 | .lha 36 | .lz 37 | .lzh 38 | .lzma 39 | .lzo 40 | .lzx 41 | .pak 42 | .paq6 43 | .paq7 44 | .paq8 45 | .par 46 | .par2 47 | .partimg 48 | .pea 49 | .pim 50 | .pit 51 | .qda 52 | .rar 53 | .rk 54 | .rz 55 | .s7z 56 | .sda 57 | .sea 58 | .sen 59 | .sfark 60 | .sfx 61 | .shk 62 | .sit 63 | .sitx 64 | .sqx 65 | .sz 66 | .tar 67 | .tar.Z 68 | .tar.bz2 69 | .tar.gz 70 | .tbz2 71 | .tgz 72 | .tlz 73 | .uc 74 | .uc0 75 | .uc2 76 | .uca 77 | .ucn 78 | .ue2 79 | .uha 80 | .ur2 81 | .war 82 | .wim 83 | .xar 84 | .xp3 85 | .xz 86 | .yz1 87 | .z 88 | .zip 89 | .zipx 90 | .zoo 91 | .zpaq 92 | .zz -------------------------------------------------------------------------------- /doc/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Nikolaos Kamarinakis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2017 Nikolaos Kamarinakis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at nikolaskam@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |

2 | DyMerge Logo 3 |

4 | 5 | 6 | > A simple, yet powerful tool - written purely in python - which takes given wordlists and merges them into one dynamic dictionary that can then be used as ammunition for a successful dictionary based (or bruteforce) attack. 7 | 8 | - Compatible with Python 2.6 & 2.7. 9 | - Author: [Nikolaos Kamarinakis](mailto:nikolaskam@gmail.com) ([nikolaskama.me](https://nikolaskama.me/)) 10 | 11 |
12 | 13 | [![Build Status](https://travis-ci.org/k4m4/dymerge.svg?branch=master)](https://travis-ci.org/k4m4/dymerge) 14 | [![Donations Badge](https://yourdonation.rocks/images/badge.svg)](https://yourdonation.rocks) 15 | [![License Badge](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/k4m4/dymerge/blob/master/license) 16 | [![Say Thanks](https://img.shields.io/badge/say-thanks-ff69b4.svg)](https://saythanks.io/to/k4m4) 17 | [![GitHub Stars](https://img.shields.io/github/stars/k4m4/dymerge.svg)](https://github.com/k4m4/dymerge/stargazers) 18 | 19 | --- 20 | 21 |

✨Read my latest post: Why DyMerge Sucks.

22 | 23 | --- 24 | 25 |

26 | Visit nikolaskama.me/dymergeproject for more information. Check out my blog and follow me on Twitter. 27 |

28 | 29 |
30 | 31 | # Installation 32 | 33 | You can install DyMerge by cloning the [Git Repo](https://github.com/k4m4/dymerge): 34 | 35 | ``` 36 | ~ ❯❯❯ git clone https://github.com/k4m4/dymerge.git 37 | ~ ❯❯❯ cd dymerge/ 38 | ~/dymerge ❯❯❯ python dymerge.py 39 | ``` 40 | 41 |
42 | 43 | # Usage 44 | 45 | ``` 46 | Usage: python dymerge.py {dictionaries} [options] 47 | 48 | Options: 49 | --version show program's version number and exit 50 | -h, --help show this help message and exit 51 | -o OUTPUT_FILE, --output=OUTPUT_FILE 52 | output filename 53 | -i INCLUDE_VALUES, --include=INCLUDE_VALUES 54 | include specified values in dictionary 55 | -z ZIP_TYPE, --zip=ZIP_TYPE 56 | zip file with specified archive format 57 | -s, --sort sort output alphabetically 58 | -u, --unique remove dictionary duplicates 59 | -r, --reverse reverse dictionary items 60 | -f, --fast finish task asap 61 | 62 | Examples: 63 | python dymerge.py ~/dictionaries/ -s -u -o ~/powerful.txt 64 | python dymerge.py /usr/share/wordlists/rockyou.txt /lists/cewl.txt -s -u 65 | python dymerge.py /lists/cewl.txt /lists/awlg.txt -s -u -i and,this 66 | python dymerge.py ~/fsocity.dic -u -r -o ~/clean.txt 67 | python dymerge.py /dicts/crunch.txt /dicts/john.txt -u -f -z bz2 68 | ``` 69 | 70 | To view all available options run: 71 | 72 | ``` 73 | ~/dymerge ❯❯❯ python dymerge.py -h 74 | ``` 75 | 76 |
77 | 78 | # Demo 79 | 80 | Here's a short demo: 81 | 82 | [![DyMerge Demo](https://asciinema.org/a/84067.png)](https://asciinema.org/a/84067?autoplay=1) 83 | 84 | (For more demos click [here](https://asciinema.org/~k4m4)) 85 | 86 |
87 | 88 | # Developer 89 | 90 | - **Nikolaos Kamarinakis** (k4m4) - [@nikolaskama](https://twitter.com/nikolaskama) 91 | 92 |
93 | 94 | # License 95 | 96 | Copyright 2016-2017 by [Nikolaos Kamarinakis](mailto:nikolaskam@gmail.com). Some rights reserved. 97 | 98 | DyMerge is under the terms of the [MIT License](https://www.tldrlegal.com/l/mit), following all clarifications stated in the [license file](https://raw.githubusercontent.com/k4m4/dymerge/master/license). 99 | 100 |
101 | 102 | For more information head over to the [official project page](https://nikolaskama.me/dymergeproject/). 103 | You can also go ahead and email me anytime at **nikolaskam{at}gmail{dot}com**. -------------------------------------------------------------------------------- /termcolor.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | # Copyright (c) 2008-2011 Volvox Development Team 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | # 22 | # Author: Konstantin Lepa 23 | 24 | """ANSII Color formatting for output in terminal.""" 25 | 26 | from __future__ import print_function 27 | import os 28 | 29 | 30 | __ALL__ = [ 'colored', 'cprint' ] 31 | 32 | VERSION = (1, 1, 0) 33 | 34 | ATTRIBUTES = dict( 35 | list(zip([ 36 | 'bold', 37 | 'dark', 38 | '', 39 | 'underline', 40 | 'blink', 41 | '', 42 | 'reverse', 43 | 'concealed' 44 | ], 45 | list(range(1, 9)) 46 | )) 47 | ) 48 | del ATTRIBUTES[''] 49 | 50 | 51 | HIGHLIGHTS = dict( 52 | list(zip([ 53 | 'on_grey', 54 | 'on_red', 55 | 'on_green', 56 | 'on_yellow', 57 | 'on_blue', 58 | 'on_magenta', 59 | 'on_cyan', 60 | 'on_white' 61 | ], 62 | list(range(40, 48)) 63 | )) 64 | ) 65 | 66 | 67 | COLORS = dict( 68 | list(zip([ 69 | 'grey', 70 | 'red', 71 | 'green', 72 | 'yellow', 73 | 'blue', 74 | 'magenta', 75 | 'cyan', 76 | 'white', 77 | ], 78 | list(range(30, 38)) 79 | )) 80 | ) 81 | 82 | 83 | RESET = '\033[0m' 84 | 85 | 86 | def colored(text, color=None, on_color=None, attrs=None): 87 | """Colorize text. 88 | 89 | Available text colors: 90 | red, green, yellow, blue, magenta, cyan, white. 91 | 92 | Available text highlights: 93 | on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white. 94 | 95 | Available attributes: 96 | bold, dark, underline, blink, reverse, concealed. 97 | 98 | Example: 99 | colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink']) 100 | colored('Hello, World!', 'green') 101 | """ 102 | if os.getenv('ANSI_COLORS_DISABLED') is None: 103 | fmt_str = '\033[%dm%s' 104 | if color is not None: 105 | text = fmt_str % (COLORS[color], text) 106 | 107 | if on_color is not None: 108 | text = fmt_str % (HIGHLIGHTS[on_color], text) 109 | 110 | if attrs is not None: 111 | for attr in attrs: 112 | text = fmt_str % (ATTRIBUTES[attr], text) 113 | 114 | text += RESET 115 | return text 116 | 117 | 118 | def cprint(text, color=None, on_color=None, attrs=None, **kwargs): 119 | """Print colorize text. 120 | 121 | It accepts arguments of print function. 122 | """ 123 | 124 | print((colored(text, color, on_color, attrs)), **kwargs) 125 | 126 | 127 | if __name__ == '__main__': 128 | print('Current terminal type: %s' % os.getenv('TERM')) 129 | print('Test basic colors:') 130 | cprint('Grey color', 'grey') 131 | cprint('Red color', 'red') 132 | cprint('Green color', 'green') 133 | cprint('Yellow color', 'yellow') 134 | cprint('Blue color', 'blue') 135 | cprint('Magenta color', 'magenta') 136 | cprint('Cyan color', 'cyan') 137 | cprint('White color', 'white') 138 | print(('-' * 78)) 139 | 140 | print('Test highlights:') 141 | cprint('On grey color', on_color='on_grey') 142 | cprint('On red color', on_color='on_red') 143 | cprint('On green color', on_color='on_green') 144 | cprint('On yellow color', on_color='on_yellow') 145 | cprint('On blue color', on_color='on_blue') 146 | cprint('On magenta color', on_color='on_magenta') 147 | cprint('On cyan color', on_color='on_cyan') 148 | cprint('On white color', color='grey', on_color='on_white') 149 | print('-' * 78) 150 | 151 | print('Test attributes:') 152 | cprint('Bold grey color', 'grey', attrs=['bold']) 153 | cprint('Dark red color', 'red', attrs=['dark']) 154 | cprint('Underline green color', 'green', attrs=['underline']) 155 | cprint('Blink yellow color', 'yellow', attrs=['blink']) 156 | cprint('Reversed blue color', 'blue', attrs=['reverse']) 157 | cprint('Concealed Magenta color', 'magenta', attrs=['concealed']) 158 | cprint('Bold underline reverse cyan color', 'cyan', 159 | attrs=['bold', 'underline', 'reverse']) 160 | cprint('Dark blink concealed white color', 'white', 161 | attrs=['dark', 'blink', 'concealed']) 162 | print(('-' * 78)) 163 | 164 | print('Test mixing:') 165 | cprint('Underline red on grey color', 'red', 'on_grey', 166 | ['underline']) 167 | cprint('Reversed green on red color', 'green', 'on_red', ['reverse']) 168 | -------------------------------------------------------------------------------- /dymerge.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # dymerge.py 3 | 4 | """ 5 | Copyright (C) 2016 Nikolaos Kamarinakis (nikolaskam@gmail.com) 6 | See License at nikolaskama.me (https://nikolaskama.me/dymergeproject) 7 | 8 | ____ 9 | /\ _`\ /'\_/`\ 10 | \ \ \/\ \ __ __/\ \ __ _ __ __ __ 11 | \ \ \ \ \/\ \/\ \ \ \__\ \ /'__`\/\` __\/'_ `\ /'__`\ 12 | \ \ \_\ \ \ \_\ \ \ \_/\ \/\ __/\ \ \//\ \_\ \/\ __/ 13 | \ \____/\/`____ \ \_\\ \_\ \____\\ \_\\ \____ \ \____\ 14 | \/___/ `/___/ \/_/ \/_/\/____/ \/_/ \/____\ \/____/ 15 | /\___/ /\____/ 16 | \/__/ Made with <3 by k4m4 \_/__/ 17 | """ 18 | 19 | import sys, os, optparse, time, zipfile, tarfile, bz2, gzip, imp, StringIO 20 | from time import sleep 21 | from termcolor import colored 22 | 23 | def displayLogo(): 24 | logo = [] 25 | print info 26 | try: 27 | path = 'txt/logo.txt' 28 | with open(path, 'r') as myFile: 29 | lines = myFile.readlines() 30 | for line in lines: 31 | logo.append(line.rstrip('\n')) 32 | for line in logo: 33 | sys.stdout.write(line+'\n') 34 | 35 | # some people just don't like seeing logos in their clis... 36 | except IOError: # (Ignored) Error --> "No Such (logo.txt) File" 37 | return 38 | 39 | def flushPrint(msg, error=False, ext=False): 40 | if ext: 41 | msg, msg_e = msg.split(' --> ') 42 | msg += ' --> ' 43 | 44 | if fast: 45 | if error: 46 | sys.stdout.write(colored('\n[-] ', 'red')) 47 | sys.stdout.write(colored(msg, 'red')) 48 | if ext: 49 | sys.stdout.write(colored(msg_e, 'red', attrs = ['bold'])) 50 | else: 51 | sys.stdout.write(colored('\n[+] ', 'green')) 52 | sys.stdout.write(colored(msg, 'green')) 53 | if ext: 54 | sys.stdout.write(colored(msg_e, 'green', attrs = ['bold'])) 55 | else: 56 | if error: 57 | sys.stdout.write(colored('\n[-] ', 'red')) 58 | for char in msg: 59 | sleep(0.03) 60 | sys.stdout.write(colored(char, 'red')) 61 | sys.stdout.flush() 62 | if ext: 63 | for char in msg_e: 64 | sleep(0.03) 65 | sys.stdout.write(colored(char, 'red', attrs = ['bold'])) 66 | sys.stdout.flush() 67 | else: 68 | sys.stdout.write(colored('\n[+] ', 'green')) 69 | for char in msg: 70 | sleep(0.03) 71 | sys.stdout.write(colored(char, 'green')) 72 | sys.stdout.flush() 73 | if ext: 74 | for char in msg_e: 75 | sleep(0.03) 76 | sys.stdout.write(colored(char, 'green', attrs = ['bold'])) 77 | sys.stdout.flush() 78 | 79 | def delayEffect(): 80 | if fast: 81 | return 82 | else: 83 | time.sleep(.5) 84 | 85 | def appendListGenerator(option, opt, value, parser): 86 | setattr(parser.values, option.dest, value.split(',')) 87 | 88 | def readFiles(): 89 | if len(argv) > 1: 90 | flushPrint("Reading Dictionaries") 91 | delayEffect() 92 | flushPrint("Merging Dictionaries") 93 | else: 94 | flushPrint("Reading Dictionary(ies)") 95 | for i in range(len(argv)): 96 | """ 97 | if os.path.isdir(argv[i]): 98 | files = os.listdir(argv[i]) 99 | path = argv[i] 100 | for file in files: 101 | argv.append(str(path) + os.sep + file) 102 | print('argv:', argv) # {TESTING} 103 | argv.remove(argv[i]) 104 | print('files:', files) # {TESTING} 105 | """ 106 | try: 107 | with open(argv[i], 'r') as myFile: 108 | if os.path.getsize(argv[i]) > 0: 109 | lines = myFile.readlines() 110 | for line in lines: 111 | wordList.append(line.rstrip('\n')) 112 | else: # Error --> "File (dict.) is empty" 113 | delayEffect() 114 | flushPrint("Dictionary Is Empty --> Please Enter A Valid File", True, True) 115 | flushPrint("System Exit\n", True) 116 | raise SystemExit 117 | 118 | # Error --> "File (dict.) is compressed" 119 | commonFormats = open('txt/archive_formats.txt').read().split('\n') 120 | for archiveFormat in commonFormats: 121 | if archiveFormat == '': # just in case you've been playing around... 122 | return 123 | if (argv[i]).endswith(archiveFormat): 124 | print(archiveFormat) 125 | print('yes') 126 | delayEffect() 127 | flushPrint("Invalid Dictionary File Format --> Please Enter A Valid File", True, True) 128 | flushPrint("System Exit\n", True) 129 | raise SystemExit 130 | 131 | except IOError: # Error --> "No such (dict.) file" 132 | delayEffect() 133 | flushPrint("Dictionary(ies) Not Found --> Please Enter A Valid Path", True, True) 134 | flushPrint("System Exit\n", True) 135 | raise SystemExit 136 | 137 | def includeValues(): 138 | flushPrint("Including Prompted Values") 139 | for value in include_values: 140 | wordList.append(value) 141 | 142 | def makeUnique(): 143 | global wordList 144 | 145 | flushPrint("Removing All Duplicates") 146 | # wordList = list(set(wordList)) --> This Messes Up The Order 147 | seen = set() 148 | seen_add = seen.add 149 | wordList = [i for i in wordList if not (i in seen or seen_add(i))] 150 | 151 | def sortList(): 152 | global wordList 153 | 154 | flushPrint("Sorting Dictionary Alphabetically") 155 | wordList = sorted(wordList) 156 | 157 | def reverseList(): 158 | global wordList 159 | 160 | flushPrint("Reversing Dictionary Items") 161 | wordList = list(reversed(wordList)) 162 | 163 | def uniqueOutFile(fName, fType): 164 | global dicFile 165 | global zipFile 166 | global compress 167 | global outFile 168 | 169 | if compress: 170 | checkFile = zipFile 171 | fType += '.' + zipType 172 | else: 173 | checkFile = dicFile 174 | if os.path.exists(checkFile): 175 | fList = list(fName) 176 | exists = True 177 | fName += '-{}' 178 | i = 1 179 | while exists: 180 | tempFile = (str(fName)+'.'+str(fType)) 181 | tempFile = tempFile.format(i) 182 | if os.path.exists(tempFile): 183 | i += 1 184 | else: 185 | outFile = tempFile 186 | exists = False 187 | else: 188 | outFile = checkFile 189 | 190 | def zipIt(): 191 | global wordList 192 | global dicFile 193 | global zipFile 194 | global zipType 195 | global dicFileIn 196 | 197 | flushPrint("Zipping File") 198 | wordListStr = '\n'.join(wordList) 199 | 200 | if zipType == 'zip': 201 | with zipfile.ZipFile('%s' % (outFile), 'w', zipfile.ZIP_DEFLATED) as zf: 202 | try: 203 | zf.writestr(dicFileIn, wordListStr) 204 | finally: 205 | zf.close() 206 | elif zipType == 'tar' or zipType == 'tar.bz2' or zipType == 'tar.gz': 207 | if zipType == 'tar': 208 | mode = 'w' 209 | elif zipType == 'tar.bz2': 210 | mode = 'w:bz2' 211 | else: 212 | mode = 'w:gz' 213 | with tarfile.open('%s' % (outFile), '%s' % (mode), ) as zf: 214 | try: 215 | zfInfo = tarfile.TarInfo('%s' % (dicFileIn)) 216 | zfInfo.size = len(wordListStr) 217 | zf.addfile(zfInfo, StringIO.StringIO(wordListStr)) 218 | finally: 219 | zf.close() 220 | elif zipType == 'gz': 221 | with gzip.GzipFile('%s' % (outFile), 'w', compresslevel = 9) as zf: 222 | try: 223 | zf.writelines(wordListStr) 224 | finally: 225 | zf.close() 226 | elif zipType == 'bz2': 227 | with bz2.BZ2File('%s' % (outFile), 'w', compresslevel = 9) as zf: 228 | try: 229 | zf.writelines(wordListStr) 230 | finally: 231 | zf.close() 232 | 233 | def taskComplete(): 234 | global wordList 235 | global dicFile 236 | global zipType 237 | global zipFile 238 | global outFile 239 | global compress 240 | global dicFileIn 241 | 242 | dicFile = output_file 243 | dList = dicFile.split('/') 244 | dicFileIn = dList[len(dList)-1] 245 | 246 | dList2 = dicFileIn.split('.') 247 | if len(dList2[0]) < 1: 248 | dList2[0] = 'dymerged' 249 | dicFileIn = '.'.join(dList2) 250 | dList[len(dList)-1] = dicFileIn 251 | dicFile = '/'.join(dList) 252 | 253 | zipType = zip_type 254 | 255 | compress = False 256 | 257 | # to compress or to !compress 258 | if zipType != 'txt': 259 | compress = True 260 | 261 | f = dicFile.split('.') 262 | fName = f[0] 263 | # check if file format was inputed 264 | if len(f) > 1: 265 | fType = f[1] 266 | else: 267 | fName = dicFile 268 | fType = 'txt' 269 | 270 | # convert format into legit extension 271 | if zipType == 'bzip2': 272 | zipType = 'bz2' 273 | elif zipType == 'gzip': 274 | zipType = 'gz' 275 | elif zipType == 'bz2tar': 276 | zipType = 'tar.bz2' 277 | elif zipType == 'gztar': 278 | zipType = 'tar.gz' 279 | 280 | dicFile = (str(fName) + '.' + str(fType)) 281 | zipFile = (str(dicFile) + '.' + str(zipType)) 282 | 283 | uniqueOutFile(fName, fType) 284 | 285 | if not compress: 286 | try: 287 | with open(outFile, 'w+') as myFile: 288 | for word in wordList: 289 | myFile.write(str(word)+'\n') 290 | except IOError: # Error --> "Invalid Output File Path" 291 | delayEffect() 292 | flushPrint("Invalid Path To Out File Given --> Please Enter a Valid Path", True, True) 293 | flushPrint("System Exit\n", True) 294 | raise SystemExit 295 | else: 296 | # validate compression file type 297 | formats = ['zip', 'bz2', 'gz', 'tar', 'tar.bz2', 'tar.gz'] 298 | if zipType in formats: 299 | delayEffect() 300 | zipIt() 301 | else: 302 | delayEffect() 303 | flushPrint("Invalid Zip Format --> Please Enter A Valid Zip Format", True, True) 304 | flushPrint("Choose from --> 'zip', 'bz2', 'gz', 'tar', 'bz2tar', 'gztar'", True, True) 305 | flushPrint("System Exit\n", True) 306 | raise SystemExit 307 | 308 | flushPrint("Task Successfully Complete") 309 | delayEffect() 310 | saved = "Final Dictionary Saved As --> " + str(outFile) 311 | flushPrint(saved, False, True) 312 | print "\nComp/tional Time Elapsed:", (time.clock() - start) 313 | 314 | def globalizeValues(o, i, z, s, u, r, f, a): 315 | global output_file 316 | global include_values 317 | global zip_type 318 | global sort 319 | global unique 320 | global reverse 321 | global fast 322 | global argv 323 | 324 | output_file = o 325 | include_values = i 326 | zip_type = z 327 | sort = s 328 | unique = u 329 | reverse = r 330 | fast = f 331 | argv = a 332 | 333 | def main(): 334 | 335 | global start 336 | global info 337 | global wordList 338 | 339 | start = time.clock() 340 | 341 | optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog 342 | 343 | version = open('doc/VERSION').read().replace('\n','') 344 | info = 'DyMerge ' + version + ' Nikolaos Kamarinakis (nikolaskama.me)' 345 | 346 | examples = ('\nExamples:\n'+ 347 | ' python dymerge.py ~/dictionaries/ -s -u -o ~/powerful.txt\n' + 348 | ' python dymerge.py /usr/share/wordlists/rockyou.txt /lists/cewl.txt -s -u\n' + 349 | ' python dymerge.py /lists/cewl.txt /lists/awlg.txt -s -u -i and,this\n' + 350 | ' python dymerge.py ~/fsocity.dic -u -r -o ~/clean.txt\n' + 351 | ' python dymerge.py /dicts/crunch.txt /dicts/john.txt -u -f -z bz2\n') 352 | 353 | parser = optparse.OptionParser(epilog=examples, 354 | usage='python %prog {dictionaries} [options]', 355 | prog='dymerge.py', version=('DyMerge ' + version)) 356 | 357 | parser.add_option('-o', '--output', action='store', default='dymerged.txt', 358 | dest='output_file', help='output filename') 359 | 360 | parser.add_option('-i', '--include', action='callback', 361 | callback=appendListGenerator, type='string', 362 | dest='include_values', help='include specified values in dictionary') 363 | 364 | parser.add_option('-z', '--zip', action='store', default='txt', 365 | dest='zip_type', help='zip file with specified archive format') 366 | 367 | parser.add_option('-s', '--sort', action='store_true', default=False, 368 | dest='sort', help='sort output alphabetically') 369 | 370 | parser.add_option('-u', '--unique', action='store_true', default=False, 371 | dest='unique', help='remove dictionary duplicates') 372 | 373 | parser.add_option('-r', '--reverse', action='store_true', default=False, 374 | dest='reverse', help='reverse dictionary items') 375 | 376 | parser.add_option('-f', '--fast', action='store_true', default=False, 377 | dest='fast', help='finish task asap') 378 | 379 | (options, argv) = parser.parse_args() 380 | 381 | """ 382 | print 'ARGV :', sys.argv[1:] 383 | print 'OUTPUT :', options.output_file 384 | print 'INCLUDE :', options.include_values 385 | print 'ZIP :', options.zip_type 386 | print 'SORT :', options.sort 387 | print 'UNIQUE :', options.unique 388 | print 'REVERSE :', options.reverse 389 | print 'FAST :', options.fast 390 | print 'DICTS :', argv 391 | """ 392 | output_file = options.output_file 393 | include_values = options.include_values 394 | zip_type = options.zip_type 395 | sort = options.sort 396 | unique = options.unique 397 | reverse = options.reverse 398 | fast = options.fast 399 | 400 | globalizeValues(options.output_file, options.include_values, \ 401 | options.zip_type, options.sort, options.unique, \ 402 | options.reverse, options.fast, argv) 403 | 404 | wordList = [] 405 | 406 | displayLogo() 407 | 408 | argLen = len(sys.argv[1:]) 409 | dicLen = len(argv) 410 | dirLen = 0 411 | # directory argument implementation 412 | for path in argv: 413 | dirPath = os.path.isdir(path) 414 | if dirPath: 415 | files = os.listdir(path) 416 | dicLen -= 1 417 | for file in files: 418 | argv.append(str(path) + os.sep + file) 419 | dicLen += len(os.listdir(path)) 420 | argLen += len(os.listdir(path)) 421 | argv.remove(path) 422 | 423 | if argLen > 1 and dicLen > 0: 424 | 425 | flushPrint("Starting Dictionary Merge Task") 426 | 427 | readFiles() 428 | delayEffect() 429 | 430 | if include_values != None: 431 | includeValues() 432 | delayEffect() 433 | 434 | if unique: 435 | makeUnique() 436 | delayEffect() 437 | 438 | if sort: 439 | sortList() 440 | delayEffect() 441 | 442 | if reverse: 443 | reverseList() 444 | delayEffect() 445 | 446 | taskComplete() 447 | 448 | elif argLen > 0 and dicLen < 1: 449 | flushPrint("No Dictionaries To Merge --> Use '-h' For Usage Help", True, True) 450 | flushPrint("System Exit\n", True) 451 | elif argLen > 0 and dicLen > 0 and dicLen < 2: 452 | flushPrint("No Options Selected --> Use '-h' For Usage Help", True, True) 453 | flushPrint("System Exit\n", True) 454 | else: 455 | flushPrint("Use '-h' Or '--help' For Usage Options\n") 456 | 457 | if __name__ == '__main__': 458 | try: 459 | main() 460 | except KeyboardInterrupt: 461 | flushPrint("System Exit\n", True) 462 | raise SystemExit 463 | --------------------------------------------------------------------------------