├── .coveragerc
├── .dockerignore
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── tests_multi_os.yml
├── .gitignore
├── .gitmodules
├── .readthedocs.yml
├── Dockerfile
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.md
├── TODO
├── all_tests.sh
├── chepy
├── __init__.py
├── __init__.pyi
├── __main__.py
├── __version__.py
├── __version__.pyi
├── config.py
├── config.pyi
├── core.py
├── core.pyi
├── extras
│ ├── __init__.py
│ ├── __init__.pyi
│ ├── bruteforce.py
│ ├── bruteforce.pyi
│ ├── characters.py
│ ├── characters.pyi
│ ├── combinatons.py
│ ├── combinatons.pyi
│ ├── crypto.py
│ ├── crypto.pyi
│ ├── misc.py
│ └── misc.pyi
└── modules
│ ├── __init__.py
│ ├── __init__.pyi
│ ├── aritmeticlogic.py
│ ├── aritmeticlogic.pyi
│ ├── codetidy.py
│ ├── codetidy.pyi
│ ├── compression.py
│ ├── compression.pyi
│ ├── dataformat.py
│ ├── dataformat.pyi
│ ├── datetimemodule.py
│ ├── datetimemodule.pyi
│ ├── encryptionencoding.py
│ ├── encryptionencoding.pyi
│ ├── exceptions.py
│ ├── exceptions.pyi
│ ├── extractors.py
│ ├── extractors.pyi
│ ├── hashing.py
│ ├── hashing.pyi
│ ├── internal
│ ├── __init__.py
│ ├── __init__.pyi
│ ├── cli.py
│ ├── cli.pyi
│ ├── colors.py
│ ├── colors.pyi
│ ├── constants.py
│ ├── constants.pyi
│ ├── helpers.py
│ ├── ls47.py
│ └── rison.py
│ ├── language.py
│ ├── language.pyi
│ ├── links.py
│ ├── links.pyi
│ ├── networking.py
│ ├── networking.pyi
│ ├── other.py
│ ├── other.pyi
│ ├── publickey.py
│ ├── publickey.pyi
│ ├── search.py
│ ├── search.pyi
│ ├── utils.py
│ └── utils.pyi
├── cli.py
├── docs
├── Makefile
├── assets
│ ├── cc_encoding.png
│ ├── clicolors.png
│ ├── ctf.gif
│ ├── hmac_hash.png
│ └── plugin.gif
├── chepy.md
├── cli.md
├── conf.py
├── config.md
├── core.md
├── examples.md
├── extras.rst
├── faq.md
├── index.md
├── internal.rst
├── make.bat
├── modules.rst
├── modules
│ ├── aritmeticlogic.rst
│ ├── codetidy.rst
│ ├── compression.rst
│ ├── dataformat.rst
│ ├── datetimemodule.rst
│ ├── encryptionencoding.rst
│ ├── extractors.rst
│ ├── hashing.rst
│ ├── language.rst
│ ├── links.rst
│ ├── multimedia.rst
│ ├── networking.rst
│ ├── other.rst
│ ├── publickey.rst
│ └── utils.rst
├── plugins.md
├── pullrequest.md
├── requirements.txt
└── usage.md
├── logo.png
├── requirements.txt
├── setup.cfg
├── setup.py
├── tests
├── __init__.py
├── files
│ ├── elf
│ ├── encoding
│ ├── fake_secrets.txt
│ ├── ff.exe
│ ├── flags
│ ├── hello
│ ├── keyboard.pcap
│ ├── lsb.png
│ ├── msb.png
│ ├── pbuf
│ ├── pkcs12
│ ├── private.pem
│ ├── public.pem
│ ├── qr.png
│ ├── qr
│ │ ├── aztec.qr.png
│ │ └── basic.qr.png
│ ├── script.py
│ ├── test.db
│ ├── test.der
│ ├── test.html
│ ├── test.js
│ ├── test.json
│ ├── test.pcapng
│ ├── test.pem
│ ├── test.tar.gz
│ ├── test.xml
│ ├── test.zip
│ ├── vuln_code
│ └── wordlist.txt
├── test_aritmeticlogic.py
├── test_cli.py
├── test_codetidy.py
├── test_compression.py
├── test_conf.py
├── test_core.py
├── test_ctf.py
├── test_dataformat.py
├── test_datetime.py
├── test_encryptionencoding.py
├── test_extractors.py
├── test_extras
│ ├── __init__.py
│ ├── test_bruteforce.py
│ ├── test_characters.py
│ ├── test_combinations.py
│ ├── test_crypto_extras.py
│ └── test_misc.py
├── test_file_encoding.py
├── test_hashing.py
├── test_language.py
├── test_links.py
├── test_networking.py
├── test_other.py
├── test_publickey.py
├── test_search.py
└── test_utils.py
└── tests_plugins
├── _test_git.py
├── test_additionalextractors.py
├── test_binary.py
├── test_extract_plugin.py
├── test_forensics.py
├── test_hash.py
├── test_ml.py
├── test_multimedia.py
├── test_pcap.py
├── test_protobuf.py
├── test_qr.py
├── test_sqlite.py
└── test_useragent.py
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | omit =
3 | chepy/__main__.py
4 | chepy/config.py
5 | chepy/modules/internal/cli.py
6 | chepy/chepy_plugins/*
7 |
8 |
9 | [report]
10 | fail_under = 100
11 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .gitignore
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is. Do keep in mind that Chepy is attempting to provide functionality that a web app does, which makes it difficult at times to work with certain types of user input.
12 |
13 | **To Reproduce**
14 | Provide sufficient detail to reproduce the bug. Make sure to provide link to file, and data required to reproduce.
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Screenshots**
20 | If applicable, add screenshots to help explain your problem.
21 |
22 | **Desktop (please complete the following information):**
23 | - OS: [e.g. iOS]
24 | - Python Version [e.g. 22]
25 | - Chepy Version [e.g. 22]
26 |
27 | **Additional context**
28 | Add any other context about the problem here.
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 | **Make sure to include data and expected output**
13 |
14 | **Describe the solution you'd like**
15 | A clear and concise description of what you want to happen.
16 |
17 | **Describe alternatives you've considered**
18 | A clear and concise description of any alternative solutions or features you've considered.
19 |
20 | **Additional context**
21 | Add any other context or screenshots about the feature request here.
22 |
--------------------------------------------------------------------------------
/.github/workflows/tests_multi_os.yml:
--------------------------------------------------------------------------------
1 | name: tests
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test:
7 |
8 | runs-on: ${{ matrix.os }}
9 | strategy:
10 | fail-fast: false
11 | max-parallel: 6
12 | matrix:
13 | os: [ubuntu-latest, windows-latest, macOS-latest]
14 | python-version:
15 | - "3.12"
16 |
17 | steps:
18 | - uses: actions/checkout@v4
19 | - name: Set up Python ${{ matrix.python-version }}
20 | uses: actions/setup-python@v5
21 | with:
22 | python-version: ${{ matrix.python-version }}
23 | cache: 'pip'
24 |
25 | # - uses: actions/cache@v3
26 | # if: startsWith(runner.os, 'Linux')
27 | # with:
28 | # path: ~/.cache/pip
29 | # key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
30 | # restore-keys: |
31 | # ${{ runner.os }}-pip-
32 |
33 | # - uses: actions/cache@v3
34 | # if: startsWith(runner.os, 'macOS')
35 | # with:
36 | # path: ~/Library/Caches/pip
37 | # key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
38 | # restore-keys: |
39 | # ${{ runner.os }}-pip-
40 |
41 | # - uses: actions/cache@v3
42 | # if: startsWith(runner.os, 'Windows')
43 | # with:
44 | # path: ~\AppData\Local\pip\Cache
45 | # key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
46 | # restore-keys: |
47 | # ${{ runner.os }}-pip-
48 |
49 | - name: Install
50 | # if: steps.devcache.outs.cache-hit != 'true'
51 | run: |
52 | git submodule update --init --recursive
53 | pip install -r requirements.txt
54 | python -m pip install --upgrade pip
55 | pip install .[extras]
56 |
57 | - name: Install test requirements
58 | run: |
59 | pip install sphinx recommonmark pytest==8.1.1 pytest-cov==5.0.0 pyperclip
60 |
61 | - name: Test with pytest
62 | env:
63 | COVERAGE_CORE: sysmon
64 | run: |
65 | pytest -v --disable-pytest-warnings --cov-report=xml --cov=chepy --cov-config=.coveragerc tests/
66 | coverage report -m
67 |
68 | - name: Test plugins osx
69 | if: matrix.os == 'macOS-latest'
70 | run: |
71 | sed -iE 's/enableplugins = false/enableplugins = true/' ~/.chepy/chepy.conf
72 | sed -iE '/chepy/d' chepy/chepy_plugins/requirements.txt
73 | pip install -r chepy/chepy_plugins/requirements.txt
74 | pip install .
75 | pytest -v --disable-pytest-warnings tests_plugins/
76 | python -c "from chepy import Chepy"
77 |
78 | - name: Test plugins ubuntu
79 | if: contains(matrix.os, 'ubuntu')
80 | run: |
81 | sed -i 's/enableplugins = false/enableplugins = true/' ~/.chepy/chepy.conf
82 | sed -i '/chepy/d' chepy/chepy_plugins/requirements.txt
83 | pip install -r chepy/chepy_plugins/requirements.txt
84 | pip install .
85 | pytest --disable-pytest-warnings tests_plugins/
86 | python -c "from chepy import Chepy"
87 |
88 | - name: Test plugins windows
89 | if: matrix.os == 'windows-latest'
90 | run: |
91 | Set-Content -Path ~/.chepy/chepy.conf -Value (Get-Content ~/.chepy/chepy.conf | %{$_ -replace "enableplugins = false","enableplugins = true"})
92 | Set-Content -Path chepy/chepy_plugins/requirements.txt -Value (Get-Content -Path chepy/chepy_plugins/requirements.txt | Select-String -Pattern 'chepy' -NotMatch)
93 | pip install -r chepy/chepy_plugins/requirements.txt
94 | pytest --disable-pytest-warnings tests_plugins/
95 | python -c "from chepy import Chepy"
96 |
97 | # - name: Test with bandit
98 | # run: |
99 | # bandit --recursive chepy/ --ignore-nosec --skip B101,B413,B303,B310,B112,B304,B320,B410,B404,B608,B311,B324
100 |
101 | # - name: Test docs
102 | # if: ${{ !env.ACT }} && contains(matrix.os, 'ubuntu')
103 | # run: |
104 | # make -C docs/ clean html
105 |
106 | publish:
107 | runs-on: ubuntu-latest
108 | needs: test
109 | if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
110 | steps:
111 | - uses: actions/checkout@v4
112 | - name: setup
113 | uses: actions/setup-python@v5
114 | with:
115 | python-version: "3.10"
116 | - name: build
117 | run: |
118 | python setup.py sdist
119 | - name: publish
120 | uses: pypa/gh-action-pypi-publish@v1.4.2
121 | if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
122 | with:
123 | user: __token__
124 | password: ${{ secrets.PYPI_PASSWORD }}
125 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | pyvenv.cfg
3 | .envrc
4 | hexfile.bin
5 | share/
6 |
7 | .bandit.json
8 | .scannerwork
9 | .DS_Store
10 | .vscode/
11 | .test
12 | ignore/
13 | node_modules/
14 |
15 | # Byte-compiled / optimized / DLL files
16 | __pycache__/
17 | *.py[cod]
18 | *$py.class
19 |
20 | # C extensions
21 | *.so
22 |
23 | # Distribution / packaging
24 | .Python
25 | build/
26 | develop-eggs/
27 | dist/
28 | downloads/
29 | eggs/
30 | .eggs/
31 | lib/
32 | lib64/
33 | parts/
34 | sdist/
35 | var/
36 | wheels/
37 | *.egg-info/
38 | .installed.cfg
39 | *.egg
40 | MANIFEST
41 |
42 | # PyInstaller
43 | # Usually these files are written by a python script from a template
44 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
45 | *.manifest
46 | *.spec
47 |
48 | # Installer logs
49 | pip-log.txt
50 | pip-delete-this-directory.txt
51 |
52 | # Unit test / coverage reports
53 | htmlcov/
54 | .tox/
55 | .coverage
56 | .coverage.*
57 | .cache
58 | nosetests.xml
59 | coverage.xml
60 | *.cover
61 | .hypothesis/
62 | .pytest_cache/
63 |
64 | # Translations
65 | *.mo
66 | *.pot
67 |
68 | # Django stuff:
69 | *.log
70 | local_settings.py
71 | db.sqlite3
72 |
73 | # Flask stuff:
74 | instance/
75 | .webassets-cache
76 |
77 | # Scrapy stuff:
78 | .scrapy
79 |
80 | # Sphinx documentation
81 | docs/_build/
82 |
83 | # PyBuilder
84 | target/
85 |
86 | # Jupyter Notebook
87 | .ipynb_checkpoints
88 |
89 | # pyenv
90 | .python-version
91 |
92 | # celery beat schedule file
93 | celerybeat-schedule
94 |
95 | # SageMath parsed files
96 | *.sage.py
97 |
98 | # Environments
99 | .env
100 | .venv
101 | env/
102 | venv/
103 | ENV/
104 | env.bak/
105 | venv.bak/
106 |
107 | # Spyder project settings
108 | .spyderproject
109 | .spyproject
110 |
111 | # Rope project settings
112 | .ropeproject
113 |
114 | # mkdocs documentation
115 | /site
116 |
117 | # mypy
118 | .mypy_cache/
119 | sonar-project.properties.local
120 | slim.report.json
121 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "chepy/chepy_plugins"]
2 | path = chepy/chepy_plugins
3 | url = https://github.com/securisec/chepy_plugins
4 |
--------------------------------------------------------------------------------
/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | build:
4 | os: ubuntu-22.04
5 | tools:
6 | python: "3.10"
7 |
8 | python:
9 | install:
10 | - method: pip
11 | path: .
12 | - requirements: docs/requirements.txt
13 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8.0
2 |
3 | WORKDIR /chepy
4 | COPY requirements.txt /chepy
5 | RUN pip install -r /chepy/requirements.txt \
6 | && pip install python-magic virtualenv \
7 | && virtualenv -p python3 /chepy/venv \
8 | && pip install pytest pytest-cov bandit \
9 | && pip install scapy markdown pefile pyelftools pydriller requests
10 |
11 | COPY . /chepy/
12 | RUN cd /chepy \
13 | && sed -i '/chepy/d' chepy/chepy_plugins/requirements.txt \
14 | && pip install -e . \
15 | && venv/bin/pip3 install . \
16 | && venv/bin/pip3 install -r chepy/chepy_plugins/requirements.txt \
17 | && mkdir -p /chepy/venv/lib/python3.8/site-packages/chepy/chepy/chepy_plugins \
18 | && cp -r /chepy/chepy/chepy_plugins/data/ /chepy/venv/lib/python3.8/site-packages/chepy/chepy_plugins/ \
19 | && pip install -r /chepy/chepy/chepy_plugins/requirements.txt
20 |
21 | RUN cd /chepy/ && pytest --disable-pytest-warnings --cov-report=xml --cov=chepy --cov-config=.coveragerc tests/
22 | RUN sed -i 's/enableplugins = false/enableplugins = true/' /root/.chepy/chepy.conf
23 | RUN cd /chepy/ && pytest --disable-pytest-warnings tests_plugins/
24 | RUN python -c "from chepy import Chepy"
25 |
26 | RUN cd /chepy/ && bandit --recursive chepy/ --ignore-nosec --skip B101,B413,B303,B310,B112,B304,B320,B410,B404,B608
27 | RUN rm -rf /chepy/tests \
28 | && rm -rf /chepy/build \
29 | && rm -rf /chepy/dist \
30 | && rm -rf /chepy/ignore \
31 | && rm -rf /chepy/docs \
32 | && rm -rf /chepy/plugins_test
33 |
34 |
35 | FROM python:3.8.0-slim
36 | COPY --from=0 /chepy /chepy
37 | RUN apt update \
38 | && apt install exiftool libmagic-dev -y \
39 | && apt-get clean \
40 | && rm -rf /var/lib/apt/lists/* \
41 | && /chepy/venv/bin/chepy -v \
42 | && sed -i 's/enableplugins = false/enableplugins = true/' /root/.chepy/chepy.conf
43 | WORKDIR /data
44 | VOLUME ["/data"]
45 |
46 | ENTRYPOINT ["/chepy/venv/bin/chepy"]
47 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include requirements.txt
2 | include chepy/chepy_plugins/data/*
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: test test-all
2 |
3 |
4 | test:
5 | COVERAGE_CORE=sysmon python -m pytest --noconftest -v --disable-pytest-warnings --cov-report=xml --cov=chepy --cov-config=.coveragerc tests/
6 |
7 | test-all: test
8 | COVERAGE_CORE=sysmon python -m pytest --noconftest -v --disable-pytest-warnings tests_plugins/
9 |
10 | # git log --format=%B 4.0.0..5.0.0 | sed '/^\s*$/d' | sort | uniq
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 
6 |
7 |
8 |
9 | [](http://chepy.readthedocs.io/en/latest/)
10 | [](https://pypi.python.org/pypi/chepy)
11 |
12 | [](https://codecov.io/gh/securisec/chepy)
13 |
14 | [](https://github.com/securisec/chepy)
15 | 
16 |
17 | [](https://pepy.tech/project/chepy)
18 |
19 |
20 |
21 | # Chepy
22 |
23 |
24 | 
25 |
26 | Chepy is a python library with a handy cli that is aimed to mirror some of the capabilities of [CyberChef](https://gchq.github.io/CyberChef/). A reasonable amount of effort was put behind Chepy to make it compatible to the various functionalities that CyberChef offers, all in a pure Pythonic manner. There are some key advantages and disadvantages that Chepy has over Cyberchef. The Cyberchef concept of _stacking_ different modules is kept alive in Chepy.
27 |
28 | There is still a long way to go for Chepy as it does not offer every single ability of Cyberchef.
29 |
30 | ## Feel free to give the project a ⭐️!
31 |
32 | ## Docs
33 | [Refer to the docs for full usage information](http://chepy.readthedocs.io/en/latest/)
34 |
35 | ## Example
36 | [For all usage and examples, see the docs.](http://chepy.readthedocs.io/en/latest/)
37 |
38 | Chepy has a stacking mechanism similar to Cyberchef. For example, this in Cyberchef:
39 |
40 |
41 |
42 | This is equivalent to
43 |
44 | ```python
45 | from chepy import Chepy
46 |
47 | file_path = "/tmp/demo/encoding"
48 |
49 | print(
50 | Chepy(file_path)
51 | .load_file()
52 | .reverse()
53 | .rot_13()
54 | .from_base64()
55 | .from_base32()
56 | .hexdump_to_str()
57 | .o
58 | )
59 |
60 | ```
61 |
62 | ## Chepy vs Cyberchef
63 |
64 | #### Advantages
65 | - Chepy is pure python with a supporting and accessible python api
66 | - Chepy has a CLI
67 | - Chepy CLI has full autocompletion.
68 | - Supports pe, elf, and other various file format specific parsing.
69 | - Extendable via [plugins](https://chepy-plugins.readthedocs.io/en/latest/)
70 | - Infinitely scalable as it can leverage the full Python library.
71 | - Chepy can interface with the full Cyberchef web app to a certain degree. It is easy to move from Chepy to Cyberchef if need be.
72 | - The Chepy python library is significantly faster than the Cyberchef Node library.
73 | - Works with HTTP/S requests without CORS issues.
74 | - `magic` support via the Chepy ML plugin.
75 |
76 | #### Disadvantages
77 | - Chepy does not offer every single thing that Cyberchef does
78 |
79 |
80 | ## Installation
81 | Chepy can be installed in a few ways.
82 |
83 | ### Pypi
84 | ```bash
85 | pip3 install chepy
86 | # optionally with extra requirements
87 | pip3 install chepy[extras]
88 | ```
89 |
90 | ### Git
91 | ```bash
92 | git clone --recursive https://github.com/securisec/chepy.git
93 | cd chepy
94 | pip3 install -e .
95 | # I use -e here so that if I update later with git pull, I dont have it install it again (unless dependencies have changed)
96 | ```
97 |
98 |
102 |
103 | #### Standalone binary
104 | One can build Chepy to be a standalone binary also. This includes packaging all the dependencies together.
105 | ```bash
106 | git clone https://github.com/securisec/chepy.git
107 | cd chepy
108 | pip install .
109 | pip install pyinstaller
110 | pyinstaller cli.py --name chepy --onefile
111 | ```
112 | The binary will be in the dist/ folder.
113 |
114 | ### Plugins
115 | [Check here for plugins docs](https://chepy-plugins.readthedocs.io/en/latest/)
116 |
117 | ### Used by
118 | [Remnux linux](https://docs.remnux.org/discover-the-tools/examine+static+properties/deobfuscation#chepy)
119 |
120 | ```eval_rst
121 | .. toctree::
122 | :maxdepth: 3
123 | :caption: Contents:
124 |
125 | usage.md
126 | examples.md
127 | cli.rst
128 | chepy.md
129 | core.md
130 | modules.rst
131 | extras.rst
132 | plugins.md
133 | pullrequest.md
134 | config.md
135 | faq.md
136 |
137 |
138 | Indices and tables
139 | ==================
140 |
141 | * :ref:`genindex`
142 | * :ref:`modindex`
143 | * :ref:`search`
144 | ```
145 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | Fix:
2 |
3 | Code:
4 | ☐ add more examples in docstrings
5 | ☐ Luhn validator https://guptaavi352.medium.com/ctflearn-writeups-9f247c2fe94c
6 |
7 | New ideas:
8 | ☐ rubber ducky encode/decode
9 | ☐ save registers https://t.co/pBNRufibY8?amp=1
10 | ☐ cbor encode/decode https://github.com/agronholm/cbor2 (plugin)
11 | ☐ fuzzy search
12 | ☐ 🚧 pgp, generate, encrypt, decrypt, verify
13 | ☐ swap little and big endian
14 | ☐ ignore error method
15 | ☐ swap bytes
16 | ☐ homophonic decoder
17 | ☐ append method for core to add data to the state
18 | ☐ qr create
19 | ☐ random from state
20 | ☐ ascii shift cipher kqfl ? snyjHYK"8fwymdxf~xdm8qq5$ = niteCTF{3arth_says_h3ll0} somewhat
21 | ☐ ✨ affine bruteforce
22 | ☐ ✨ zero-width encode
23 | ☐ ✨ hill cipher encode/decode/brute
24 | ☐ 💡 maybe a decorator function to convert all inputs into bytes when possible? this will allow for a consistant bytes approach to all functions
25 | ☐ ✨ amf encode/decode
26 | ☐ ✨ aes cmac
27 | ☐ ✨ whitespace encoding https://www.dcode.fr/whitespace-language
28 | ☐ beaufort
29 | ☐ 🔥 update python_requires in setup.py on python version change
30 | ☐ update base85 https://github.com/gorakhargosh/mom/blob/master/mom/codec/base85.py#L343
31 |
32 | Bug:
33 |
34 | Extras:
35 | ☐ xor two files
36 |
37 | Cli:
38 | ☐ optionally show output window in a split screen window
39 | ☐ lower the chepy prompt lower. that empty space is not being used
40 | ☐ write to file with prompt toolkit path autocomplete
41 | ☐ pipe input to chepy
42 |
43 | Enhance:
44 |
45 | Plugins:
46 |
47 | Misc:
48 | ☐ cyberchef recipe to chepy recipe converter
49 |
50 | Archive:
51 | ✔ @high disable plugins from code
52 | ✔ 🐙 update config to use envars for plugins
53 | ✔ register support in callstack
54 | ✔ ecb no padding in aes/des
55 | ✔ update ml model with different spacing for hex, binary etc
56 |
--------------------------------------------------------------------------------
/all_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function check_test {
4 | "$@"
5 | local status=$?
6 | if [ $status -ne 0 ]; then
7 | echo -e "\n\033[31;7m$1 Failed" >&2
8 | exit
9 | fi
10 | return $status
11 | }
12 |
13 | # pytest and coverage
14 | check_test pytest --disable-pytest-warnings --cov=chepy --cov-config=.coveragerc tests/
15 |
16 | # pytest plugins
17 | check_test pytest --disable-pytest-warnings tests_plugins/
18 |
19 | # bandit
20 | check_test bandit --recursive chepy/ --ignore-nosec --skip B101,B413,B303,B310,B112,B304,B320,B410,B404
21 |
22 | # docs
23 | check_test make -C docs/ clean html
24 |
25 | # plugin docs
26 | check_test make -C ~/dev/chepy_plugins/docs clean html
27 |
28 | # build docker
29 | # check_test docker build -t chepy .
30 |
--------------------------------------------------------------------------------
/chepy/__init__.py:
--------------------------------------------------------------------------------
1 | import pretty_errors
2 | from docstring_parser import parse as _doc_parse
3 | from types import FunctionType
4 |
5 | from .modules.aritmeticlogic import AritmeticLogic
6 | from .modules.codetidy import CodeTidy
7 | from .modules.compression import Compression
8 | from .modules.dataformat import DataFormat
9 | from .modules.datetimemodule import DateTime
10 | from .modules.encryptionencoding import EncryptionEncoding
11 | from .modules.extractors import Extractors
12 | from .modules.hashing import Hashing
13 | from .modules.language import Language
14 | from .modules.links import Links
15 | from .modules.networking import Networking
16 | from .modules.other import Other
17 | from .modules.publickey import Publickey
18 | from .modules.search import Search
19 | from .modules.utils import Utils
20 | from .modules.internal.colors import cyan
21 |
22 | from .config import ChepyConfig
23 |
24 | _plugins = ChepyConfig().load_plugins()
25 |
26 |
27 | class Chepy(
28 | AritmeticLogic,
29 | CodeTidy,
30 | Compression,
31 | DataFormat,
32 | DateTime,
33 | EncryptionEncoding,
34 | Extractors,
35 | Hashing,
36 | Language,
37 | Links,
38 | Networking,
39 | Other,
40 | Publickey,
41 | Search,
42 | Utils,
43 | *_plugins
44 | ):
45 | """Chepy class that exposes all functionality of Chepy and its plugins."""
46 |
47 | pass
48 |
49 |
50 | def show_plugins(): # pragma: no cover
51 | hold = {}
52 | for p in _plugins:
53 | hold[p.__name__] = [
54 | name
55 | for name, attr in vars(p).items()
56 | if isinstance(attr, FunctionType) and not name.startswith("_")
57 | ]
58 | return hold
59 |
60 |
61 | def search_chepy_methods(search: str) -> None: # pragma: no cover
62 | """Search for Chepy methods
63 |
64 | Args:
65 | search (str): String to search for
66 | """
67 | methods = dir(Chepy)
68 | for method in methods:
69 | if search in method and not method.startswith("_"):
70 | docs = _doc_parse(getattr(Chepy, method).__doc__).short_description
71 | print(cyan(method), docs)
72 |
--------------------------------------------------------------------------------
/chepy/__init__.pyi:
--------------------------------------------------------------------------------
1 | from typing import Dict, List
2 |
3 | from .modules.aritmeticlogic import AritmeticLogic
4 | from .modules.codetidy import CodeTidy
5 | from .modules.compression import Compression
6 | from .modules.dataformat import DataFormat
7 | from .modules.datetimemodule import DateTime
8 | from .modules.encryptionencoding import EncryptionEncoding
9 | from .modules.extractors import Extractors
10 | from .modules.hashing import Hashing
11 | from .modules.language import Language
12 | from .modules.links import Links
13 | from .modules.multimedia import Multimedia
14 | from .modules.networking import Networking
15 | from .modules.other import Other
16 | from .modules.publickey import Publickey
17 | from .modules.search import Search
18 | from .modules.utils import Utils
19 |
20 | class Chepy(
21 | AritmeticLogic,
22 | CodeTidy,
23 | Compression,
24 | DataFormat,
25 | DateTime,
26 | EncryptionEncoding,
27 | Extractors,
28 | Hashing,
29 | Language,
30 | Links,
31 | Multimedia,
32 | Networking,
33 | Other,
34 | Publickey,
35 | Search,
36 | Utils,
37 | ): ...
38 |
39 | def search_chepy_methods(search: str) -> None: ...
40 | def show_plugins() -> Dict[str, List[str]]: ...
41 |
--------------------------------------------------------------------------------
/chepy/__version__.py:
--------------------------------------------------------------------------------
1 | __version__ = "7.4.0" # pragma: no cover
2 | __author__ = "@securisec" # pragma: no cover
3 |
--------------------------------------------------------------------------------
/chepy/__version__.pyi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/chepy/__version__.pyi
--------------------------------------------------------------------------------
/chepy/config.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | import logging
4 | import importlib
5 | import inspect
6 | import pkgutil
7 | import json
8 | from pathlib import Path
9 | from configparser import ConfigParser
10 |
11 |
12 | class ChepyConfig(object):
13 | def __init__(self):
14 | home = Path.home()
15 | self.chepy_dir = (
16 | Path(".chepy").resolve()
17 | if Path(".chepy").exists()
18 | else Path(home / ".chepy")
19 | )
20 | self.chepy_conf = Path(self.chepy_dir / "chepy.conf")
21 |
22 | if not self.chepy_conf.exists(): # pragma: no cover
23 | self.chepy_dir.mkdir(exist_ok=True)
24 | c = ConfigParser()
25 |
26 | c["Plugins"] = {
27 | "EnablePlugins": "false",
28 | "PluginPath": str(Path(__file__).parent / "chepy_plugins"),
29 | }
30 | c["Cli"] = {}
31 | cli_options = c["Cli"]
32 | cli_options["history_path"] = str(self.chepy_dir / "chepy_history")
33 | cli_options["prompt_char"] = ">"
34 | cli_options["prompt_colors"] = "#00ffff #ff0000 #ffd700"
35 | cli_options["show_rprompt"] = "false"
36 | cli_options["prompt_rprompt"] = "#00ff48"
37 | cli_options["prompt_bottom_toolbar"] = "#000000"
38 | cli_options["prompt_toolbar_version"] = "#00ff48"
39 | cli_options["prompt_toolbar_states"] = "#60cdd5"
40 | cli_options["prompt_toolbar_buffers"] = "#ff00ff"
41 | cli_options["prompt_toolbar_type"] = "#ffd700"
42 | cli_options["prompt_toolbar_plugins"] = "#ffccbc"
43 | cli_options["prompt_toolbar_errors"] = "#ff0000"
44 | cli_options["prompt_cli_method"] = "#ffd700"
45 | cli_options["prompt_plugin_method"] = "#30d8ff"
46 | cli_options["cli_info_color"] = "#c2c2ff"
47 | cli_options["prompt_search_background"] = "#00aaaa #000000"
48 | cli_options["prompt_search_fuzzy"] = "#00aaaa"
49 |
50 | Path(str(self.chepy_dir / "chepy_history")).touch()
51 | if not self.chepy_conf.exists():
52 | with open(str(self.chepy_conf), "w") as f:
53 | c.write(f)
54 |
55 | self.config = ConfigParser()
56 | self.config.read(str(self.chepy_conf))
57 |
58 | plugin_path = self.__get_conf_value("None", "PluginPath", "Plugins")
59 | self.enable_plugins = json.loads(
60 | self.__get_conf_value("false", "EnablePlugins", "Plugins")
61 | )
62 |
63 | plugin_envar = os.environ.get("CHEPY_PLUGINS", "")
64 | if plugin_envar == "true":
65 | self.enable_plugins = True
66 | elif plugin_envar != "":
67 | self.enable_plugins = False
68 |
69 | if self.enable_plugins:
70 | if plugin_path != "None":
71 | self.plugin_path = Path(plugin_path).expanduser().resolve()
72 | else:
73 | self.plugin_path = Path(plugin_path)
74 | else:
75 | self.plugin_path = Path("None")
76 |
77 | self.history_path = self.__get_conf_value(
78 | str(self.chepy_dir / "chepy_history"), "history_path"
79 | )
80 | self.prompt_char = self.__get_conf_value(">", "prompt_char")
81 | self.prompt_colors = self.__get_conf_value(
82 | "#00ffff #ff0000 #ffd700", "prompt_colors"
83 | )
84 | self.show_rprompt = json.loads(self.__get_conf_value("false", "show_rprompt"))
85 | self.prompt_rprompt = self.__get_conf_value("#00ff48", "prompt_rprompt")
86 | self.prompt_bottom_toolbar = self.__get_conf_value(
87 | "#000000", "prompt_bottom_toolbar"
88 | )
89 | self.prompt_toolbar_version = self.__get_conf_value(
90 | "#00ff48", "prompt_toolbar_version"
91 | )
92 | self.prompt_toolbar_states = self.__get_conf_value(
93 | "#60cdd5", "prompt_toolbar_states"
94 | )
95 | self.prompt_toolbar_buffers = self.__get_conf_value(
96 | "#ff00ff", "prompt_toolbar_buffers"
97 | )
98 | self.prompt_toolbar_type = self.__get_conf_value(
99 | "#ffd700", "prompt_toolbar_type"
100 | )
101 | self.prompt_toolbar_plugins = self.__get_conf_value(
102 | "#ffccbc", "prompt_toolbar_plugins"
103 | )
104 | self.prompt_toolbar_errors = self.__get_conf_value(
105 | "#ff0000", "prompt_toolbar_errors"
106 | )
107 | self.prompt_search_background = self.__get_conf_value(
108 | "#00aaaa #000000", "prompt_search_background"
109 | )
110 | self.prompt_search_fuzzy = self.__get_conf_value(
111 | "#00aaaa", "prompt_search_fuzzy"
112 | )
113 | self.prompt_cli_method = self.__get_conf_value("#ffd700", "prompt_cli_method")
114 | self.prompt_plugin_method = self.__get_conf_value(
115 | "#30d8ff", "prompt_plugin_method"
116 | )
117 | self.cli_info_color = self.__get_conf_value("#c2c2ff", "cli_info_color")
118 |
119 | def __get_conf_value(self, default: str, option: str, section: str = "Cli"):
120 | if self.config.has_section(section):
121 | if self.config.has_option(section, option):
122 | return self.config[section][option]
123 | else:
124 | return default
125 | else:
126 | return default
127 |
128 | def load_plugins(self): # pragma: no cover
129 | plugins = []
130 | if self.plugin_path.stem != "None":
131 | sys.path.append(str(self.plugin_path))
132 |
133 | my_plugins = [
134 | importlib.import_module(name)
135 | for finder, name, ispkg in pkgutil.iter_modules()
136 | if (name.startswith("chepy_") and name != "chepy_plugins")
137 | ]
138 |
139 | for plugin in my_plugins:
140 | try:
141 | klass, mod = inspect.getmembers(plugin, inspect.isclass)[0]
142 | loaded = getattr(plugin, klass)
143 | plugins.append(loaded)
144 | except:
145 | logging.warning(f"Error loading {plugin.__name__}")
146 | return plugins
147 |
--------------------------------------------------------------------------------
/chepy/config.pyi:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | class ChepyConfig:
4 | chepy_dir: Any = ...
5 | chepy_conf: Any = ...
6 | config: Any = ...
7 | enable_plugins: Any = ...
8 | plugin_path: Any = ...
9 | history_path: Any = ...
10 | prompt_char: Any = ...
11 | prompt_colors: Any = ...
12 | show_rprompt: Any = ...
13 | prompt_rprompt: Any = ...
14 | prompt_bottom_toolbar: Any = ...
15 | prompt_toolbar_version: Any = ...
16 | prompt_toolbar_states: Any = ...
17 | prompt_toolbar_buffers: Any = ...
18 | prompt_toolbar_type: Any = ...
19 | prompt_toolbar_plugins: Any = ...
20 | prompt_toolbar_errors: Any = ...
21 | prompt_cli_method: Any = ...
22 | prompt_plugin_method: Any = ...
23 | cli_info_color: Any = ...
24 | def __init__(self) -> None: ...
25 | def load_plugins(self): ...
26 |
--------------------------------------------------------------------------------
/chepy/core.pyi:
--------------------------------------------------------------------------------
1 | import logging
2 | from typing import Any, List, Mapping, Tuple, Union, TypeVar, Literal, Callable, Dict
3 |
4 | jsonpickle: Any
5 |
6 | ChepyCoreT = TypeVar('ChepyCoreT', bound='ChepyCore')
7 |
8 | class ChepyDecorators:
9 | @staticmethod
10 | def call_stack(func: Any, *args: Any, **kwargs: Any): ...
11 | @staticmethod
12 | def is_stdout(func: Any, *args: Any, **kwargs: Any): ...
13 |
14 | class ChepyCore:
15 | states: Any = ...
16 | buffers: Any = ...
17 | write: Any = ...
18 | bake: Any = ...
19 | cyberchef: Any = ...
20 | read_file: Any = ...
21 | log_level: Any = ...
22 | log_format: str = ...
23 | _registers: Dict[str, Union[str, bytes]] = ...
24 | _log: logging.Logger = ...
25 | def __init__(self, *data: Any) -> None: ...
26 | def _convert_to_bytes(self) -> bytes: ...
27 | def _to_bytes(self, data: Any) -> bytes: ...
28 | def _convert_to_bytearray(self) -> bytearray: ...
29 | def _convert_to_str(self) -> str: ...
30 | def _convert_to_int(self) -> int: ...
31 | def _str_to_bytes(self, s: str) -> bytes: ...
32 | def _get_nested_value(self: ChepyCoreT, data: dict, key:str, split_by: str=".") -> Any: ...
33 | def _bytes_to_str(self, s: bytes) -> str: ...
34 | @property
35 | def state(self): ...
36 | @state.setter
37 | def state(self: ChepyCoreT, val: Any) -> None: ...
38 | def fork(self: ChepyCoreT, methods: List[Union[Tuple[Union[str, Callable], dict], Tuple[Union[str, Callable[None, ChepyCoreT]],]]]) -> ChepyCoreT: ...
39 | def for_each(self: ChepyCoreT, methods: List[Union[Tuple[Union[str, Callable], Dict[str, Any]], Tuple[Union[str, Callable[None, ChepyCoreT]],]]], merge: Union[str, bytes, None]=None) -> ChepyCoreT: ...
40 | def set_state(self: ChepyCoreT, data: Any) -> ChepyCoreT: ...
41 | def create_state(self: ChepyCoreT): ...
42 | def copy_state(self: ChepyCoreT, index: int=...) -> ChepyCoreT: ...
43 | def change_state(self: ChepyCoreT, index: int) -> ChepyCoreT: ...
44 | def switch_state(self: ChepyCoreT, index: int) -> ChepyCoreT: ...
45 | def delete_state(self: ChepyCoreT, index: int) -> ChepyCoreT: ...
46 | def get_state(self: ChepyCoreT, index: int) -> ChepyCoreT: ...
47 | def save_buffer(self: ChepyCoreT, index: int=...) -> ChepyCoreT: ...
48 | def load_buffer(self: ChepyCoreT, index: int) -> ChepyCoreT: ...
49 | def delete_buffer(self: ChepyCoreT, index: int) -> ChepyCoreT: ...
50 | def substring(self: ChepyCoreT, pattern: str, group: int=...) -> ChepyCoreT: ...
51 | @property
52 | def o(self): ...
53 | @property
54 | def out(self: ChepyCoreT) -> ChepyCoreT: ...
55 | def out_as_any(self: ChepyCoreT) -> str: ...
56 | def get_by_index(self: ChepyCoreT, *indexes: int) -> ChepyCoreT: ...
57 | def get_by_key(self: ChepyCoreT, *keys: Union[str, bytes], py_style: bool=False, split_key: Union[str, None] = '.') -> ChepyCoreT: ...
58 | def copy_to_clipboard(self: ChepyCoreT) -> None: ...
59 | def copy(self: ChepyCoreT) -> None: ...
60 | def web(self: ChepyCoreT, magic: bool=..., cyberchef_url: str=...) -> None: ...
61 | def http_request(self: ChepyCoreT, method: str=..., params: dict=..., json: dict=..., headers: dict=..., cookies: dict=...) -> ChepyCoreT: ...
62 | def load_from_url(self: ChepyCoreT, method: str=..., params: dict=..., json: dict=..., headers: dict=..., cookies: dict=...) -> ChepyCoreT: ...
63 | def load_dir(self: ChepyCoreT, pattern: str=...) -> ChepyCoreT: ...
64 | def load_file(self: ChepyCoreT, binary_mode: bool=..., encoding: Union[str, None]=...) -> ChepyCoreT: ...
65 | def write_to_file(self: ChepyCoreT, path: str) -> None: ...
66 | def write_binary(self: ChepyCoreT, path: str) -> None: ...
67 | @property
68 | def recipe(self) -> List[Dict[str, Union[str, Dict[str, Any]]]]: ...
69 | def run_recipe(self: ChepyCoreT, recipes: List[Mapping[str, Union[str, Mapping[str, Any]]]]) -> ChepyCoreT: ...
70 | def save_recipe(self: ChepyCoreT, path: str) -> ChepyCoreT: ...
71 | def load_recipe(self: ChepyCoreT, path: str) -> ChepyCoreT: ...
72 | def run_script(self: ChepyCoreT, path: str, save_state: bool=...) -> ChepyCoreT: ...
73 | def loop(self: ChepyCoreT, iterations: int, callback: Union[str, Callable], args: dict=...) -> ChepyCoreT: ...
74 | def loop_list(self: ChepyCoreT, callback: Union[str, Callable], args: dict=...) -> ChepyCoreT: ...
75 | def loop_dict(self: ChepyCoreT, keys: list, callback: Union[str, Callable], args: dict=...) -> ChepyCoreT: ...
76 | def debug(self: ChepyCoreT, verbose: bool=...) -> ChepyCoreT: ...
77 | def reset(self: ChepyCoreT) -> ChepyCoreT: ...
78 | def print(self: ChepyCoreT) -> ChepyCoreT: ...
79 | def load_command(self: ChepyCoreT) -> ChepyCoreT: ...
80 | def pretty(self: ChepyCoreT, indent: int=...) -> ChepyCoreT: ...
81 | def plugins(self: ChepyCoreT, enable: Literal['true', 'false']) -> None: ...
82 | def set_plugin_path(self: ChepyCoreT, path: str) -> None: ...
83 | def subsection(self: ChepyCoreT, pattern: str, methods: List[Tuple[Union[str, object], dict]], group: int=...) -> ChepyCoreT: ...
84 | def callback(self: ChepyCoreT, callback_function: Callable[[Any], Any]) -> ChepyCoreT: ...
85 | def register(self: ChepyCoreT, pattern: Union[str, bytes], ignore_case: bool=False, multiline: bool=False, dotall: bool=False, unicode: bool=False, extended: bool=False) -> ChepyCoreT: ...
86 | def prefix(self: ChepyCoreT, data: Union[str, bytes]) -> ChepyCoreT: ...
87 | def suffix(self: ChepyCoreT, data: Union[str, bytes]) -> ChepyCoreT: ...
88 | def get_register(self: ChepyCoreT, key: str) -> Union[str, bytes]: ...
89 | def set_register(self: ChepyCoreT, key: str, val: Union[str, bytes]) -> ChepyCoreT: ...
90 | def dump_json(self: ChepyCoreT) -> ChepyCoreT: ...
91 | def walk_dir(self: ChepyCoreT) -> ChepyCoreT: ...
92 | def search_dir(self: ChepyCoreT, pattern: Union[str, bytes]) -> ChepyCoreT: ...
93 |
--------------------------------------------------------------------------------
/chepy/extras/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/chepy/extras/__init__.py
--------------------------------------------------------------------------------
/chepy/extras/__init__.pyi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/chepy/extras/__init__.pyi
--------------------------------------------------------------------------------
/chepy/extras/bruteforce.py:
--------------------------------------------------------------------------------
1 | import zipfile
2 | from pathlib import Path
3 |
4 |
5 | def _expand_path(path):
6 | return str(Path(path).expanduser().absolute())
7 |
8 |
9 | def zip_password_bruteforce(path: str, wordlist: str) -> str:
10 | z = zipfile.ZipFile(_expand_path(path))
11 | with open(_expand_path(wordlist)) as f:
12 | for password in f:
13 | password = password.strip().encode()
14 | try:
15 | z.setpassword(password)
16 | z.testzip()
17 | return password
18 | except RuntimeError: # pragma: no cover
19 | continue
20 |
--------------------------------------------------------------------------------
/chepy/extras/bruteforce.pyi:
--------------------------------------------------------------------------------
1 | def zip_password_bruteforce(path: str, wordlist: str) -> str: ...
2 |
--------------------------------------------------------------------------------
/chepy/extras/characters.py:
--------------------------------------------------------------------------------
1 | from string import ascii_lowercase, ascii_uppercase, digits
2 |
3 |
4 | def base64_char_sets() -> dict:
5 | """Get various combinations of base64 character sets
6 |
7 | Returns:
8 | dict: Dict of various char sets
9 | """
10 | return {
11 | "standard": ascii_uppercase + ascii_lowercase + digits + "+/=", # A-Za-z0-9+/=
12 | "url_safe": ascii_uppercase + ascii_lowercase + digits + "-_", # A-Za-z0-9-_
13 | "filename_safe": ascii_uppercase
14 | + ascii_lowercase
15 | + digits
16 | + "+\\-=", # A-Za-z0-9+\-=
17 | "itoa64": "./"
18 | + digits
19 | + ascii_uppercase
20 | + ascii_lowercase
21 | + "=", # ./0-9A-Za-z=
22 | "xml": ascii_uppercase + ascii_lowercase + digits + "_.", # A-Za-z0-9_.
23 | "y64": ascii_uppercase + ascii_lowercase + digits + "._-", # A-Za-z0-9._-
24 | "z64": digits + ascii_lowercase + ascii_uppercase + "+/=", # 0-9a-zA-Z+/=
25 | "radix64": digits + ascii_uppercase + ascii_lowercase + "+/=", # 0-9A-Za-z+/=
26 | "uuencoding": " -_",
27 | "xxencoding": "+\\-"
28 | + digits
29 | + ascii_uppercase
30 | + ascii_lowercase, # +\-0-9A-Za-z
31 | "unix_crypt": "./" + digits + ascii_uppercase + ascii_lowercase, # ./0-9A-Za-z
32 | }
33 |
--------------------------------------------------------------------------------
/chepy/extras/characters.pyi:
--------------------------------------------------------------------------------
1 | def base64_char_sets() -> dict: ...
2 |
--------------------------------------------------------------------------------
/chepy/extras/combinatons.py:
--------------------------------------------------------------------------------
1 | import itertools
2 | from typing import List, Any, Iterator
3 |
4 |
5 | def generate_combo(
6 | words: List[Any], min_length: int = 0, max_length: int = None, join_by: str = None
7 | ) -> Iterator[tuple]:
8 | """Creates all possible combinations from the `words` being passed.
9 | Returns a generator. `length` controls the length of the permutations.
10 |
11 | Args:
12 | words (List[Any]): List of strings.
13 | min_length (int, optional): Minimum length of permutations. By default, 0 which
14 | will generate all
15 | max_length (int, optional): Maximum length of permutations.
16 | By default, it is the length of the `words` list
17 |
18 | Returns:
19 | Iterator[tuple]: A generator containing tuples of combinations
20 | """
21 | if min_length > 0 and max_length is not None:
22 | for L in range(min_length, max_length + 1):
23 | for subset in itertools.permutations(words, L):
24 | yield join_by.join(subset) if join_by is not None else subset
25 | elif max_length is None:
26 | for L in range(min_length, len(words) + 1):
27 | for subset in itertools.permutations(words, L):
28 | yield join_by.join(subset) if join_by is not None else subset
29 | else:
30 | for subset in itertools.permutations(words, max_length):
31 | yield join_by.join(subset) if join_by is not None else subset
32 |
33 |
34 | def hex_chars() -> list:
35 | """Returns an array of all the hex characters
36 |
37 | Returns:
38 | list: List of all hex characters
39 | """
40 | return list("{:02x}".format(x) for x in range(0, 256))
41 |
42 |
--------------------------------------------------------------------------------
/chepy/extras/combinatons.pyi:
--------------------------------------------------------------------------------
1 | from typing import Any, Iterator, List
2 |
3 | def generate_combo(words: List[Any], min_length: int=..., max_length: int=..., join_by: str=...) -> Iterator[tuple]: ...
4 | def hex_chars() -> list: ...
5 |
--------------------------------------------------------------------------------
/chepy/extras/crypto.py:
--------------------------------------------------------------------------------
1 | import json
2 | import lazy_import
3 | from typing import Iterator, Dict, List, Union
4 | from binascii import hexlify, unhexlify
5 | from itertools import cycle
6 | from urllib.request import urlopen
7 | RSA = lazy_import.lazy_module("Crypto.PublicKey.RSA")
8 |
9 | from .combinatons import generate_combo, hex_chars
10 | from chepy import Chepy
11 |
12 |
13 | def factordb(n: int) -> dict: # pragma: no cover
14 | """Query the factordb api and get primes if available
15 |
16 | Args:
17 | n (int): n is the modulus for the public key and the private keys
18 |
19 | Returns:
20 | dict: response from api as a dictionary. None if status code is not 200
21 | """
22 | res = urlopen("http://factordb.com/api/?query={}".format(str(n)))
23 | if res.status != 200:
24 | return None
25 | return json.loads(res.read().decode())
26 |
27 |
28 | def construct_private_key(
29 | n: int, e: int, d: int, format: str = "PEM", passphrase: str = None
30 | ) -> str: # pragma: no cover
31 | """Construct a private key given n, e and d
32 |
33 | Args:
34 | n (int): n
35 | e (int): e
36 | d (int): d
37 | format (str, optional): Supports PEM, DER and OpenSSH. Defaults to "PEM".
38 | passphrase (str, optional): [description]. Defaults to None.
39 |
40 | Returns:
41 | str: Private key
42 | """
43 | valid_formats = ["PEM", "DER", "OpenSSH"]
44 | assert format in valid_formats, "Valid formats are {}".format(
45 | " ".join(valid_formats)
46 | )
47 | priv = RSA.construct((n, e, d))
48 | return priv.export_key(format=format, passphrase=passphrase)
49 |
50 |
51 | def xor_bruteforce_multi(
52 | data: str, min: int = 0, max: int = None, errors: str = "backslashreplace"
53 | ) -> Iterator[Dict[str, str]]:
54 | """Bruteforce multibyte xor encryption. For faster results, use pypy3.
55 | It is important to set the min and max values if the key size is known.
56 |
57 | Args:
58 | data (str): XORed data
59 | min (int, optional): Minimum key length. Default will start at 1 byte
60 | . Defaults to 0.
61 | max (int, optional): Maximum key length. Maximum value is 257 bytes. Defaults to None.
62 | errors (str, optional): How should the errors be handled? Defaults to backslashreplace.
63 | Valid options are replace, ignore, backslashreplace
64 |
65 | Returns:
66 | Iterator[Dict[str, str]]: A dictionary where key is key, and value is xored data
67 |
68 | Yields:
69 | Iterator[Dict[str, str]]: A generator which contains a dictionary with the
70 | keys: `key` and `out`
71 | """
72 | for key in generate_combo(
73 | hex_chars(), min_length=min, max_length=max, join_by=""
74 | ): # pragma: no cover
75 | yield {
76 | "key": key,
77 | "out": Chepy(data).xor(key).bytearray_to_str(errors=errors).o,
78 | }
79 |
80 |
81 | def xor_repeating_key(
82 | data1: bytes, data2: bytes, min: int = 1, max: int = 257
83 | ) -> Union[bytes, None]: # pragma: no cover
84 | """Recover repeating key xor keys.
85 |
86 | Args:
87 | data1 (bytes): File 1 path
88 | data2 (bytes): File 2 path
89 | min (int, optional): Min chars to test. Defaults to 1.
90 | max (int, optional): Max chars to test. Defaults to 257.
91 |
92 | Returns:
93 | Union[bytes, None]: Key as hex bytes or None if no key found
94 | """
95 |
96 | def find_same(s: bytes):
97 | i = (s + s).find(s, 1, -1)
98 | return None if i == -1 else s[:i]
99 |
100 | for i in range(min, max):
101 | d1 = data1[:i]
102 |
103 | d2 = data2[:i]
104 |
105 | x = bytes(a ^ b for a, b in zip(d1, d2))
106 | o = find_same(x)
107 | if o is not None:
108 | return o
109 |
110 |
111 | def xor(data: bytes, key: bytes) -> bytes: # pragma: no cover
112 | """XOR data with a hex key
113 |
114 | Args:
115 | data (bytes): Data to be xored
116 | key (bytes): Hex key to xor data with
117 |
118 | Returns:
119 | bytes: XORed data
120 |
121 | Example:
122 | >>> xor(b"hello", unhexlify(b"aabbccdd"))
123 | b'c2dea0b1c5'
124 | """
125 | return hexlify(bytes(a ^ b for a, b in zip(data, cycle(key))))
126 |
127 |
128 | def one_time_pad_crib(
129 | cipherText1: Union[bytes, str], cipherText2: Union[bytes, str], crib: bytes
130 | ) -> List[str]:
131 | """One time pad crib attack.
132 |
133 | Args:
134 | cipherText1 (Union[bytes, str]): Cipher text 1 as hex
135 | cipherText2 (Union[bytes, str]): Cipher text 2 as hex
136 | crib (bytes): Crib (known text) as bytes
137 |
138 | Returns:
139 | List[str]: List of possible plaintexts
140 | """
141 | cipherText1 = unhexlify(cipherText1)
142 | cipherText2 = unhexlify(cipherText2)
143 | xored = bytearray(a ^ b for a, b in zip(cipherText1, cipherText2))
144 | hold = []
145 | for offset in range(0, len(xored) - len(crib) + 1):
146 | piece = xored[offset : offset + len(crib)]
147 | piece = bytearray(a ^ b for a, b in zip(crib, piece))
148 | if all(32 <= c <= 126 for c in piece):
149 | piece = (
150 | ("." * offset)
151 | + piece.decode()
152 | + ("." * (len(xored) - len(crib) - offset))
153 | )
154 | hold.append(piece)
155 | return hold
156 |
157 |
158 | def generate_rsa_keypair(
159 | bits: int = 1024, passphrase: str = None
160 | ) -> Dict[str, dict]: # pragma: no cover
161 | """Generates an RSA keypair with the specified number of bits.
162 |
163 | Args:
164 | bits: The number of bits for the RSA keypair.
165 |
166 | Returns:
167 | A tuple of the RSA public key and RSA private key, both in PEM format.
168 | """
169 |
170 | keypair = RSA.generate(bits)
171 | return {
172 | "pem": {
173 | "public": keypair.publickey().exportKey("PEM"),
174 | "private": keypair.exportKey("PEM", passphrase=passphrase),
175 | },
176 | "der": {
177 | "public": keypair.publickey().exportKey("DER"),
178 | "private": keypair.exportKey("DER", passphrase=passphrase),
179 | },
180 | }
181 |
--------------------------------------------------------------------------------
/chepy/extras/crypto.pyi:
--------------------------------------------------------------------------------
1 | from typing import Dict, Iterator, Union, Any
2 |
3 | def factordb(n: int) -> dict: ...
4 | def construct_private_key(n: int, e: int, d: int, format: str=..., passphrase: str=...) -> str: ...
5 | def xor_bruteforce_multi(data: str, min: int=..., max: int=..., errors: str=...) -> Iterator[Dict[str, str]]: ...
6 | def xor_repeating_key(data1:bytes, data2: bytes, min: int =..., max: int = ...) -> Union[bytes, None]: ...
7 | def generate_rsa_keypair(bits: int=..., passphrase: str=...) -> Dict[str, Dict[str, Any]] : ...
--------------------------------------------------------------------------------
/chepy/extras/misc.py:
--------------------------------------------------------------------------------
1 | import collections
2 | import math
3 | from typing import Any
4 |
5 |
6 | def shannon_entropy(data: Any, unit="shannon") -> float:
7 | """Calculate the Shannon entropy of any data type. Units
8 | could be `natural`, `shannon` or `hartley`
9 |
10 | - 0 represents no randomness (i.e. all the bytes in the data have the same value)
11 | whereas 8, the maximum, represents a completely random string.
12 | - Standard English text usually falls somewhere between 3.5 and 5.
13 | - Properly encrypted or compressed data of a reasonable length should have an entropy of over 7.5.
14 |
15 | Args:
16 | data (Any): Any data type
17 | unit (str, optional): Unit type. Defaults to "shannon".
18 |
19 | Returns:
20 | float: Calculated entropy
21 | """
22 | base = {"shannon": 2.0, "natural": math.exp(1), "hartley": 10.0}
23 |
24 | if len(data) <= 1: # pragma: no cover
25 | return 0
26 |
27 | counts = collections.Counter()
28 |
29 | for d in data:
30 | counts[d] += 1
31 |
32 | ent = 0
33 |
34 | probs = [float(c) / len(data) for c in counts.values()]
35 | for p in probs:
36 | if p > 0.0:
37 | ent -= p * math.log(p, base[unit])
38 |
39 | return ent
40 |
41 |
42 | def index_of_coincidence(data: Any) -> float:
43 | """Index of Coincidence (IC) is the probability of two randomly
44 | selected characters being the same.
45 |
46 | - 0 represents complete randomness (all characters are unique), whereas 1 represents no randomness (all characters are identical).
47 | - English text generally has an IC of between 0.67 to 0.78.
48 | - 'Random' text is determined by the probability that each letter occurs the same number of times as another.
49 |
50 | `Reference `__
51 |
52 | Args:
53 | data (Any): Any data type
54 |
55 | Returns:
56 | float: IC as float
57 | """
58 | cipher_flat = "".join([x.upper() for x in data.split() if x.isalpha()])
59 |
60 | N = len(cipher_flat)
61 | freqs = collections.Counter(cipher_flat)
62 | alphabet = map(chr, range(ord("A"), ord("Z") + 1))
63 | freqsum = 0.0
64 |
65 | for letter in alphabet:
66 | freqsum += freqs[letter] * (freqs[letter] - 1)
67 |
68 | try:
69 | IC = freqsum / (N * (N - 1))
70 | except ZeroDivisionError:
71 | IC = 0
72 |
73 | return IC
74 |
--------------------------------------------------------------------------------
/chepy/extras/misc.pyi:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | def shannon_entropy(data: Any, unit: Any=...) -> float: ...
4 | def index_of_coincidence(data: Any) -> float: ...
5 |
--------------------------------------------------------------------------------
/chepy/modules/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/chepy/modules/__init__.py
--------------------------------------------------------------------------------
/chepy/modules/__init__.pyi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/chepy/modules/__init__.pyi
--------------------------------------------------------------------------------
/chepy/modules/aritmeticlogic.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar, Union, Literal
3 |
4 | AritmeticLogicT = TypeVar("AritmeticLogicT", bound="AritmeticLogic")
5 |
6 | class AritmeticLogic(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def add(self: AritmeticLogicT, n: Union[int, str]) -> AritmeticLogicT: ...
10 | def addition(self: AritmeticLogicT, delimiter: Union[str, None]=None) -> AritmeticLogicT: ...
11 | def sub(self: AritmeticLogicT, n: Union[int, str]) -> AritmeticLogicT: ...
12 | def subtract(self: AritmeticLogicT, delimiter: Union[str, None]=None) -> AritmeticLogicT: ...
13 | def multiply(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ...
14 | def divide(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ...
15 | def power(self: AritmeticLogicT, n: int) -> AritmeticLogicT: ...
16 | def sum(self: AritmeticLogicT) -> AritmeticLogicT: ...
17 | def mean(self: AritmeticLogicT) -> AritmeticLogicT: ...
18 | def median(self: AritmeticLogicT) -> AritmeticLogicT: ...
19 | def int_to_base(self: AritmeticLogicT, base: Union[int, str]) -> AritmeticLogicT: ...
20 | def bit_shift_right(self: AritmeticLogicT, amount: int=1, operation_type: Literal['logical', 'arithmetic']='logical') -> AritmeticLogicT: ...
21 | def bit_shift_left(self: AritmeticLogicT, amount: int=1) -> AritmeticLogicT: ...
22 |
--------------------------------------------------------------------------------
/chepy/modules/codetidy.py:
--------------------------------------------------------------------------------
1 | from typing import TypeVar
2 |
3 | import json
4 | import random
5 |
6 | import pydash
7 | import regex as re
8 | from ..core import ChepyCore, ChepyDecorators
9 |
10 | CodeTidyT = TypeVar("CodeTidyT", bound="CodeTidy")
11 |
12 |
13 | class CodeTidy(ChepyCore):
14 | def __init__(self, *data):
15 | super().__init__(*data)
16 |
17 | @ChepyDecorators.call_stack
18 | def minify_json(self) -> CodeTidyT:
19 | """Minify JSON string
20 |
21 | Returns:
22 | Chepy: The Chepy object.
23 |
24 | Examples:
25 | >>> c = Chepy("/path/to/file.json").load_file()
26 | >>> print(c.minify_json())
27 | """
28 | self.state = json.dumps(
29 | json.loads(self._convert_to_str()), separators=(",", ":")
30 | )
31 | return self
32 |
33 | @ChepyDecorators.call_stack
34 | def beautify_json(self, indent: int = 2) -> CodeTidyT:
35 | """Beautify minified JSON
36 |
37 | Args:
38 | indent (int, optional): Indent level. Defaults to 2.
39 |
40 | Returns:
41 | Chepy: The Chepy object.
42 |
43 | Examples:
44 | >>> c = Chepy("/path/to/file.json").load_file()
45 | >>> print(c.beautify_json(indent=4))
46 | """
47 | self.state = json.dumps(json.loads(self._convert_to_str()), indent=indent)
48 | return self
49 |
50 | @ChepyDecorators.call_stack
51 | def to_upper_case(self, by: str = "all") -> CodeTidyT:
52 | """Convert string to uppercase
53 |
54 | Args:
55 | by (str, optional): Convert all, by word or by sentence. Defaults to 'all'.
56 |
57 | Returns:
58 | Chepy: The Chepy object.
59 |
60 | Examples:
61 | Uppercase by word
62 |
63 | >>> Chepy("some String").to_upper_case(by="word").o
64 | "Some String"
65 |
66 | Uppercase by sentence
67 |
68 | >>> Chepy("some String").to_upper_case(by="sentence").o
69 | "Some string"
70 |
71 | Uppercase all
72 |
73 | >>> Chepy("some String").to_upper_case(by="all").o
74 | "SOME STRING"
75 | """
76 | assert by in [
77 | "all",
78 | "word",
79 | "sentence",
80 | ], "Valid options are all, word and sentence"
81 | if by == "all":
82 | self.state = self._convert_to_str().upper()
83 | elif by == "word":
84 | self.state = self._convert_to_str().title()
85 | elif by == "sentence":
86 | self.state = self._convert_to_str().capitalize()
87 | return self
88 |
89 | @ChepyDecorators.call_stack
90 | def to_lower_case(self) -> CodeTidyT:
91 | """Convert string to lowercase
92 |
93 | Converts every character in the input to lower case.
94 |
95 | Returns:
96 | Chepy: The Chepy object.
97 |
98 | Examples:
99 | >>> Chepy("HelLo WorLd").to_lower_case().o
100 | "hello world"
101 | """
102 | self.state = self._convert_to_str().lower()
103 | return self
104 |
105 | @ChepyDecorators.call_stack
106 | def to_snake_case(self) -> CodeTidyT:
107 | """Convert string to snake case
108 |
109 | Converts the input string to snake case. Snake case is all lower case
110 | with underscores as word boundaries. e.g. this_is_snake_case.
111 |
112 | Returns:
113 | Chepy: The Chepy object.
114 |
115 | Examples:
116 | >>> Chepy("helloWorld").to_snake_case().o
117 | "hello_world"
118 | """
119 | s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", self._convert_to_str())
120 | self.state = re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()
121 | return self
122 |
123 | @ChepyDecorators.call_stack
124 | def to_camel_case(self, ignore_space: bool = False) -> CodeTidyT:
125 | """Convert string to camel case
126 |
127 | Converts the input string to camel case. Camel case is all lower case
128 | except letters after word boundaries which are uppercase. e.g. thisIsCamelCase
129 |
130 | Args:
131 | ignore_space (bool, optional): Ignore space boundaries. Defaults to False.
132 |
133 | Returns:
134 | Chepy: The Chepy object.
135 |
136 | Examples:
137 | >>> Chepy("some Data_test").to_camel_case().o
138 | "someDataTest"
139 |
140 | To ignore space, we can set the `ignore_space` to True
141 | >>> Chepy("some Data_test").to_camel_case(ignore_space=True).o
142 | "some DataTest"
143 | """
144 | if ignore_space:
145 | r = re.compile(r"_.|\-.")
146 | else:
147 | r = re.compile(r"_.|\-.|\s.")
148 | self.state = r.sub(lambda x: x.group()[1].upper(), self._convert_to_str())
149 | return self
150 |
151 | @ChepyDecorators.call_stack
152 | def to_kebab_case(self) -> CodeTidyT:
153 | """Convert string to kebab case
154 |
155 | Converts the input string to kebab case. Kebab case is all lower case
156 | with dashes as word boundaries. e.g. this-is-kebab-case.
157 |
158 | Returns:
159 | Chepy: The Chepy object.
160 |
161 | Examples:
162 | >>> Chepy("Some data_test").to_kebab_case().o
163 | "some-data-test"
164 | """
165 | self.state = pydash.kebab_case(self._convert_to_str())
166 | return self
167 |
168 | @ChepyDecorators.call_stack
169 | def swap_case(self) -> CodeTidyT:
170 | """Swap case in a string
171 |
172 | Returns:
173 | Chepy: The Chepy object.
174 |
175 | Examples:
176 | >>> Chepy("SoMe TeXt").swap_case().o
177 | "sOmE tExT"
178 | """
179 | self.state = pydash.swap_case(self._convert_to_str())
180 | return self
181 |
182 | @ChepyDecorators.call_stack
183 | def to_leetspeak(self, special_chars: bool = True) -> CodeTidyT:
184 | """Convert string to l33t speak
185 |
186 | Args:
187 | special_chars (bool, optional): Use special chars in conversion. Defaults to True.
188 |
189 | Returns:
190 | Chepy: The Chepy object
191 |
192 | Examples:
193 | >>> Chepy("somexValue").to_leetspeak().o
194 | "50m3%V@1u3"
195 | """
196 | chars = {"B": "8", "E": "3", "L": "1", "O": "0", "S": "5", "T": "7", "Z": "2"}
197 | special = {"A": "@", "C": "(", "I": "!", "X": "%"}
198 | if special_chars:
199 | chars = {**chars, **special}
200 | hold = ""
201 | for char in list(self._convert_to_str()):
202 | upper = char.upper()
203 | char_to_append = chars.get(upper)
204 | if char_to_append:
205 | hold += char_to_append
206 | else:
207 | hold += char
208 | self.state = hold
209 | return self
210 |
211 | @ChepyDecorators.call_stack
212 | def random_case(self) -> CodeTidyT:
213 | """Randomly change the case
214 |
215 | Returns:
216 | Chepy: The Chepy object.
217 | """
218 | string = self._convert_to_str()
219 | string_length = len(string)
220 |
221 | random_indices = random.sample(range(string_length), string_length)
222 | random_chars = []
223 | for i in random_indices:
224 | if random.choice([True, False]):
225 | random_chars.append(string[i].upper())
226 | else:
227 | random_chars.append(string[i].lower())
228 |
229 | string_list = list(string)
230 | for index, char in zip(random_indices, random_chars):
231 | if 0 <= index < len(string_list):
232 | string_list[index] = char
233 | self.state = "".join(string_list)
234 | return self
235 |
--------------------------------------------------------------------------------
/chepy/modules/codetidy.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar, Literal
3 |
4 | pydash: Any
5 | CodeTidyT = TypeVar('CodeTidyT', bound='CodeTidy')
6 |
7 | class CodeTidy(ChepyCore):
8 | def __init__(self, *data: Any) -> None: ...
9 | state: Any = ...
10 | def minify_json(self: CodeTidyT) -> CodeTidyT: ...
11 | def beautify_json(self: CodeTidyT, indent: int=...) -> CodeTidyT: ...
12 | def to_upper_case(self: CodeTidyT, by: Literal['all', 'word', 'sentence']=...) -> CodeTidyT: ...
13 | def to_lower_case(self: CodeTidyT) -> CodeTidyT: ...
14 | def to_snake_case(self: CodeTidyT) -> CodeTidyT: ...
15 | def to_camel_case(self: CodeTidyT, ignore_space: bool=...) -> CodeTidyT: ...
16 | def to_kebab_case(self: CodeTidyT) -> CodeTidyT: ...
17 | def swap_case(self: CodeTidyT) -> CodeTidyT: ...
18 | def to_leetspeak(self: CodeTidyT, special_chars: bool=...) -> CodeTidyT: ...
19 | def random_case(self) -> CodeTidyT: ...
20 |
--------------------------------------------------------------------------------
/chepy/modules/compression.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar, Literal
3 |
4 | CompressionT = TypeVar('CompressionT', bound='Compression')
5 |
6 | class Compression(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def fix_zip_header(self: CompressionT) -> CompressionT: ...
10 | def zip_info(self: CompressionT) -> CompressionT: ...
11 | def zip_list_files(self: CompressionT) -> CompressionT: ...
12 | def unzip_one(self: CompressionT, file: str, password: str=...) -> CompressionT: ...
13 | def unzip_all(self: CompressionT, password: str=...) -> CompressionT: ...
14 | def create_zip_file(self: CompressionT, file_name: str) -> CompressionT: ...
15 | def zip_compress(self: CompressionT, file_name: str) -> CompressionT: ...
16 | def zip_compress_symlink(self: CompressionT, file_name: str, target_file: str) -> CompressionT: ...
17 | def tar_list_files(self: CompressionT, mode: Literal["gz", "bz2", "xz", ""]=...) -> CompressionT: ...
18 | def tar_extract_one(self: CompressionT, filename: str, mode: Literal["gz", "bz2", "xz", ""]=...) -> CompressionT: ...
19 | def tar_extract_all(self: CompressionT, mode: Literal["gz", "bz2", "xz", ""]=...) -> CompressionT: ...
20 | def tar_compress(self: CompressionT, filename: str, mode: Literal["gz", "bz2", "xz", ""]=...) -> CompressionT: ...
21 | def gzip_compress(self: CompressionT, file_name: str=...) -> CompressionT: ...
22 | def gzip_decompress(self: CompressionT) -> CompressionT: ...
23 | def bzip_compress(self: CompressionT) -> CompressionT: ...
24 | def bzip_decompress(self: CompressionT) -> CompressionT: ...
25 | def zlib_compress(self: CompressionT, level: int=...) -> CompressionT: ...
26 | def zlib_decompress(self: CompressionT) -> CompressionT: ...
27 | def lzma_compress(self: CompressionT) -> CompressionT: ...
28 | def lzma_decompress(self: CompressionT) -> CompressionT: ...
29 | def raw_inflate(self: CompressionT) -> CompressionT: ...
30 | def raw_deflate(self: CompressionT) -> CompressionT: ...
31 | def lz4_compress(self: CompressionT) -> CompressionT: ...
32 | def lz4_decompress(self: CompressionT) -> CompressionT: ...
33 | def lz77_compress(self: CompressionT, window_size: int = 13, lookahead_buffer_size: int = 6) -> CompressionT: ...
34 | def lz77_decompress(self: CompressionT, window_size: int = 13, lookahead_buffer_size: int = 6) -> CompressionT: ...
35 |
--------------------------------------------------------------------------------
/chepy/modules/datetimemodule.py:
--------------------------------------------------------------------------------
1 | import time
2 | from datetime import datetime
3 | from typing import TypeVar
4 |
5 | from ..core import ChepyCore, ChepyDecorators
6 |
7 | DateTimeT = TypeVar("DateTimeT", bound="DateTime")
8 |
9 |
10 | class DateTime(ChepyCore):
11 | def __init__(self, *data):
12 | super().__init__(*data)
13 |
14 | @ChepyDecorators.call_stack
15 | def from_unix_timestamp(self, format: str = "%c", utc: bool = False) -> DateTimeT:
16 | """Convert UNIX timestamp to datetime
17 |
18 | Args:
19 | format: Format to use for datetime.strftime()
20 | utc: Whether to use UTC or local timezone
21 |
22 | Returns:
23 | Chepy: The Chepy object.
24 |
25 | Examples:
26 | >>> Chepy("1573426649").from_unix_timestamp()
27 | "Sun Nov 10 17:57:29 2019"
28 | """
29 | data = self._convert_to_int()
30 | if utc:
31 | self.state = datetime.utcfromtimestamp(data).strftime(format)
32 | else:
33 | self.state = datetime.fromtimestamp(data).strftime(format)
34 | return self
35 |
36 | @ChepyDecorators.call_stack
37 | def to_unix_timestamp(self) -> DateTimeT: # pragma: no cover
38 | """Convert datetime string to unix ts
39 |
40 | The format for the string is %a %b %d %H:%M:%S %Y, which is equivalent to
41 | %c from datatime.
42 |
43 | Returns:
44 | Chepy: The Chepy object.
45 |
46 | Examples:
47 | >>> Chepy("Sun Nov 10 17:57:29 2019").to_unix_timestamp()
48 | "1573426649"
49 | """
50 | self.state = int(
51 | time.mktime(time.strptime(self._convert_to_str(), "%a %b %d %H:%M:%S %Y"))
52 | )
53 | return self
54 |
--------------------------------------------------------------------------------
/chepy/modules/datetimemodule.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar
3 |
4 | DateTimeT = TypeVar("DateTimeT", bound="DateTime")
5 |
6 | class DateTime(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def from_unix_timestamp(self: DateTimeT, format: str = ..., utc: bool = ...) -> DateTimeT: ...
10 | def to_unix_timestamp(self: DateTimeT) -> DateTimeT: ...
11 |
--------------------------------------------------------------------------------
/chepy/modules/exceptions.py:
--------------------------------------------------------------------------------
1 | class StateNotList(Exception): # pragma: no cover
2 | def __init__(self, msg="State is not a list", *args, **kwargs):
3 | super().__init__(msg, *args, **kwargs)
4 |
5 |
6 | class StateNotDict(Exception): # pragma: no cover
7 | def __init__(self, msg="State is not a dict", *args, **kwargs):
8 | super().__init__(msg, *args, **kwargs)
9 |
--------------------------------------------------------------------------------
/chepy/modules/exceptions.pyi:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | class StateNotList(Exception):
4 | def __init__(self, msg: str = ..., *args: Any, **kwargs: Any) -> None: ...
5 |
6 | class StateNotDict(Exception):
7 | def __init__(self, msg: str = ..., *args: Any, **kwargs: Any) -> None: ...
8 |
--------------------------------------------------------------------------------
/chepy/modules/extractors.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar, Union, List
3 |
4 | parsel: Any
5 |
6 | ExtractorsT = TypeVar('ExtractorsT', bound='Extractors')
7 |
8 | class Extractors(ChepyCore):
9 | def __init__(self, *data: Any) -> None: ...
10 | state: Any = ...
11 | def extract_hashes(self: ExtractorsT) -> ExtractorsT: ...
12 | def extract_strings(self: ExtractorsT, length: int=..., join_by: str=...) -> ExtractorsT: ...
13 | def extract_ips(self: ExtractorsT, is_binary: bool=...) -> ExtractorsT: ...
14 | def extract_email(self: ExtractorsT, is_binary: bool=...) -> ExtractorsT: ...
15 | def extract_mac_address(self: ExtractorsT, is_binary: bool=...) -> ExtractorsT: ...
16 | def extract_urls(self: ExtractorsT, is_binary: bool=...) -> ExtractorsT: ...
17 | def extract_domains(self: ExtractorsT, is_binary: bool=...) -> ExtractorsT: ...
18 | def javascript_comments(self: ExtractorsT) -> ExtractorsT: ...
19 | def extract_google_api(self: ExtractorsT) -> ExtractorsT: ...
20 | def extract_google_captcha(self: ExtractorsT) -> ExtractorsT: ...
21 | def extract_google_oauth(self: ExtractorsT) -> ExtractorsT: ...
22 | def extract_aws_keyid(self: ExtractorsT) -> ExtractorsT: ...
23 | def extract_aws_s3_url(self: ExtractorsT) -> ExtractorsT: ...
24 | def extract_facebook_access_token(self: ExtractorsT) -> ExtractorsT: ...
25 | def extract_auth_basic(self: ExtractorsT) -> ExtractorsT: ...
26 | def extract_auth_bearer(self: ExtractorsT) -> ExtractorsT: ...
27 | def extract_mailgun_api(self: ExtractorsT) -> ExtractorsT: ...
28 | def extract_twilio_api(self: ExtractorsT) -> ExtractorsT: ...
29 | def extract_twilio_sid(self: ExtractorsT) -> ExtractorsT: ...
30 | def extract_paypal_bt(self: ExtractorsT) -> ExtractorsT: ...
31 | def extract_square_oauth(self: ExtractorsT) -> ExtractorsT: ...
32 | def extract_square_access(self: ExtractorsT) -> ExtractorsT: ...
33 | def extract_stripe_api(self: ExtractorsT) -> ExtractorsT: ...
34 | def extract_github(self: ExtractorsT) -> ExtractorsT: ...
35 | def extract_rsa_private(self: ExtractorsT) -> ExtractorsT: ...
36 | def extract_dsa_private(self: ExtractorsT) -> ExtractorsT: ...
37 | def extract_jwt_token(self: ExtractorsT) -> ExtractorsT: ...
38 | def extract_base64(self: ExtractorsT, min: int=...) -> ExtractorsT: ...
39 | def find_continuous_patterns(self: ExtractorsT, str2: Union[str, bytes], min_value: int=...) -> ExtractorsT: ...
40 | def find_longest_continious_pattern(self: ExtractorsT, str2: Union[str, bytes]) -> ExtractorsT: ...
41 | def extract_zero_width_chars_tags(self: ExtractorsT) -> ExtractorsT: ...
42 | def decode_zero_width(self: ExtractorsT, chars: str=...) -> ExtractorsT: ...
43 | def xpath_selector(self: ExtractorsT, query: str, index:int=None, namespaces: str=None) -> ExtractorsT: ...
44 | def css_selector(self: ExtractorsT, query: str) -> ExtractorsT: ...
45 | def extract_html_comments(self: ExtractorsT) -> ExtractorsT: ...
46 | def extract_html_tags(self: ExtractorsT, tag: List[str]) -> ExtractorsT: ...
47 | def aws_account_id_from_access_key(self: ExtractorsT) -> ExtractorsT: ...
48 |
--------------------------------------------------------------------------------
/chepy/modules/hashing.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar, Union
3 | from typing_extensions import Literal as Literal
4 |
5 | type_password_hashes = Literal[
6 | "apr_md5_crypt",
7 | "argon2",
8 | "atlassian_pbkdf2_sha1",
9 | "bcrypt",
10 | "bcrypt_sha256",
11 | "bigcrypt",
12 | "bsd_nthash",
13 | "bsdi_crypt",
14 | "cisco_asa",
15 | "cisco_pix",
16 | "cisco_type7",
17 | "crypt16",
18 | "cta_pbkdf2_sha1",
19 | "des_crypt",
20 | "django_digest",
21 | "dlitz_pbkdf2_sha1",
22 | "fshp",
23 | "grub_pbkdf2_sha512",
24 | "hex_digest",
25 | "ldap_crypt",
26 | "ldap_hex_md5",
27 | "ldap_hex_sha1",
28 | "ldap_md5",
29 | "ldap_pbkdf2_digest",
30 | "ldap_plaintext",
31 | "ldap_salted_md5",
32 | "ldap_salted_sha1",
33 | "ldap_salted_sha256",
34 | "ldap_salted_sha512",
35 | "ldap_sha1",
36 | "lmhash",
37 | "md5_crypt",
38 | "msdcc",
39 | "msdcc2",
40 | "mssql2000",
41 | "mssql2005",
42 | "mysql323",
43 | "mysql41",
44 | "nthash",
45 | "oracle10",
46 | "oracle11",
47 | "pbkdf2_digest",
48 | "phpass",
49 | "postgres_md5",
50 | "roundup_plaintext",
51 | "scram",
52 | "scrypt",
53 | "sha1_crypt",
54 | "sha256_crypt",
55 | "sha512_crypt",
56 | "sun_md5_crypt",
57 | "unix_disabled",
58 | ]
59 |
60 | HashingT = TypeVar('HashingT', bound='Hashing')
61 | hmac: Any
62 | MD2: Any
63 | MD4: Any
64 | MD5: Any
65 | SHA512: Any
66 | SHA1: Any
67 | SHA256: Any
68 | keccak: Any
69 | SHAKE128: Any
70 | SHAKE256: Any
71 | RIPEMD: Any
72 | BLAKE2s: Any
73 | BLAKE2b: Any
74 | KDF: Any
75 |
76 | class Hashing(ChepyCore):
77 | def __init__(self, *data: Any) -> None: ...
78 | state: Any = ...
79 | def sha1(self: HashingT) -> HashingT: ...
80 | def sha2_256(self: HashingT) -> HashingT: ...
81 | def sha2_512(self: HashingT) -> HashingT: ...
82 | def sha2_512_truncate(self: HashingT, truncate: Literal[256, 224]=...) -> HashingT: ...
83 | def sha2_384(self: HashingT) -> HashingT: ...
84 | def sha2_224(self: HashingT) -> HashingT: ...
85 | def sha3_512(self: HashingT) -> HashingT: ...
86 | def sha3_256(self: HashingT) -> HashingT: ...
87 | def sha3_384(self: HashingT) -> HashingT: ...
88 | def sha3_224(self: HashingT) -> HashingT: ...
89 | def md2(self: HashingT) -> HashingT: ...
90 | def md4(self: HashingT) -> HashingT: ...
91 | def md5(self: HashingT) -> HashingT: ...
92 | def keccak_512(self: HashingT) -> HashingT: ...
93 | def keccak_384(self: HashingT) -> HashingT: ...
94 | def keccak_256(self: HashingT) -> HashingT: ...
95 | def keccak_224(self: HashingT) -> HashingT: ...
96 | def shake_256(self: HashingT, size: int=...) -> HashingT: ...
97 | def shake_128(self: HashingT, size: int=...) -> HashingT: ...
98 | def ripemd_160(self: HashingT) -> HashingT: ...
99 | def blake_2b(self: HashingT, bits: Literal[512, 384, 256, 160, 128]=..., key: bytes=...) -> HashingT: ...
100 | def blake_2s(self: HashingT, bits: Literal[256, 160, 128]=..., key: bytes=...) -> HashingT: ...
101 | def crc8_checksum(self: HashingT) -> HashingT: ...
102 | def crc16_checksum(self: HashingT) -> HashingT: ...
103 | def crc32_checksum(self: HashingT) -> HashingT: ...
104 | def hmac_hash(self: HashingT, key: bytes=..., digest: Literal['md5', 'sha1', 'sha256', 'sha512']=...) -> HashingT: ...
105 | def derive_pbkdf2_key(self: HashingT, password: Union[str, bytes], salt: Union[str, bytes], key_size: int=..., iterations: int=..., hash_type: Literal['md5', 'sha1', 'sha256', 'sha512']=..., hex_salt: bool=..., show_full_key: bool=...) -> Any: ...
106 | def bcrypt_hash(self: HashingT, rounds: int=...) -> HashingT: ...
107 | def bcrypt_compare(self: HashingT, hash: str) -> HashingT: ...
108 | def scrypt_hash(self: HashingT, salt: str=..., key_length: int=..., N: int=..., r: int=..., p: int=...) -> HashingT: ...
109 | def password_hashing(self: HashingT, format: type_password_hashes, **kwargs) -> HashingT: ...
110 |
--------------------------------------------------------------------------------
/chepy/modules/internal/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/chepy/modules/internal/__init__.py
--------------------------------------------------------------------------------
/chepy/modules/internal/__init__.pyi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/chepy/modules/internal/__init__.pyi
--------------------------------------------------------------------------------
/chepy/modules/internal/cli.pyi:
--------------------------------------------------------------------------------
1 | from prompt_toolkit.completion import Completer
2 | from typing import Any
3 |
4 | module: Any
5 | options: Any
6 | config: Any
7 |
8 | class CliCompleter(Completer):
9 | def get_completions(self, document: Any, complete_event: Any) -> None: ...
10 |
11 | def functions_cli(): ...
12 | def get_doc(method: str) -> Any: ...
13 | def cli_edit_state(fire: object, args: list) -> Any: ...
14 | def cli_highlight(fire: object, highlight: str) -> Any: ...
15 | def get_cli_options(): ...
16 | def print_in_colors(out: Any) -> None: ...
17 | def cli_state_type(fire: object) -> Any: ...
18 | def cli_get_state(fire: object, index: int) -> Any: ...
19 | def cli_show_length(fire: object) -> Any: ...
20 | def cli_show_dict_keys(fire: object, pretty: bool=...) -> Any: ...
21 | def cli_show_states(fire: object, pretty: bool=...) -> Any: ...
22 | def cli_show_buffers(fire: object, pretty: bool=...) -> Any: ...
23 | def cli_get_attr(fire: object, attr: str) -> Any: ...
24 | def cli_pretty_print(fire: object) -> Any: ...
25 | def cli_plugin_path(config: Any) -> None: ...
26 | def cli_show_errors(errors: Any) -> None: ...
27 | def cli_go_back() -> None: ...
28 | def cli_delete_history() -> None: ...
29 | def cli_exit(fire: object) -> Any: ...
30 |
--------------------------------------------------------------------------------
/chepy/modules/internal/colors.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from colorama import Fore, Back
3 |
4 |
5 | def yellow_background(s: str) -> str: # pragma: no cover
6 | """Yellow color string if tty
7 |
8 | Args:
9 | s (str): String to color
10 |
11 | Returns:
12 | str: Colored string
13 | """
14 | if sys.stdout.isatty():
15 | return Back.YELLOW + Fore.BLACK + s + Fore.RESET + Back.RESET
16 | else:
17 | return s
18 |
19 |
20 | def red(s: str) -> str: # pragma: no cover
21 | """Red color string if tty
22 |
23 | Args:
24 | s (str): String to color
25 |
26 | Returns:
27 | str: Colored string
28 |
29 | Examples:
30 | >>> from chepy.modules.internal.colors import red
31 | >>> print(RED("some string"))
32 | """
33 | if sys.stdout.isatty():
34 | return Fore.RED + s + Fore.RESET
35 | else:
36 | return s
37 |
38 |
39 | def blue(s: str) -> str: # pragma: no cover
40 | """Blue color string if tty
41 |
42 | Args:
43 | s (str): String to color
44 |
45 | Returns:
46 | str: Colored string
47 |
48 | Examples:
49 | >>> from chepy.modules.internal.colors import blue
50 | >>> print(BLUE("some string"))
51 | """
52 | if sys.stdout.isatty():
53 | return Fore.BLUE + s + Fore.RESET
54 | else:
55 | return s
56 |
57 |
58 | def cyan(s: str) -> str: # pragma: no cover
59 | """Cyan color string if tty
60 |
61 | Args:
62 | s (str): String to color
63 |
64 | Returns:
65 | str: Colored string
66 |
67 | Examples:
68 | >>> from chepy.modules.internal.colors import cyan
69 | >>> print(CYAN("some string"))
70 | """
71 | if sys.stdout.isatty():
72 | return Fore.CYAN + s + Fore.RESET
73 | else:
74 | return s
75 |
76 |
77 | def green(s: str) -> str: # pragma: no cover
78 | """Green color string if tty
79 |
80 | Args:
81 | s (str): String to color
82 |
83 | Returns:
84 | str: Colored string
85 |
86 | Examples:
87 | >>> from chepy.modules.internal.colors import green
88 | >>> print(GREEN("some string"))
89 | """
90 | if sys.stdout.isatty():
91 | return Fore.GREEN + s + Fore.RESET
92 | else:
93 | return s
94 |
95 |
96 | def yellow(s: str) -> str: # pragma: no cover
97 | """Yellow color string if tty
98 |
99 | Args:
100 | s (str): String to color
101 |
102 | Returns:
103 | str: Colored string
104 |
105 | Examples:
106 | >>> from chepy.modules.internal.colors import yellow
107 | >>> print(YELLOW("some string"))
108 | """
109 | if sys.stdout.isatty():
110 | return Fore.YELLOW + s + Fore.RESET
111 | else:
112 | return s
113 |
114 |
115 | def magenta(s: str) -> str: # pragma: no cover
116 | """Magenta color string if tty
117 |
118 | Args:
119 | s (str): String to color
120 |
121 | Returns:
122 | str: Colored string
123 |
124 | Examples:
125 | >>> from chepy.modules.internal.colors import magenta
126 | >>> print(MAGENTA("some string"))
127 | """
128 | if sys.stdout.isatty():
129 | return Fore.MAGENTA + s + Fore.RESET
130 | else:
131 | return s
132 |
--------------------------------------------------------------------------------
/chepy/modules/internal/colors.pyi:
--------------------------------------------------------------------------------
1 | def yellow_background(s: str) -> str: ...
2 | def red(s: str) -> str: ...
3 | def blue(s: str) -> str: ...
4 | def cyan(s: str) -> str: ...
5 | def green(s: str) -> str: ...
6 | def yellow(s: str) -> str: ...
7 | def magenta(s: str) -> str: ...
8 |
--------------------------------------------------------------------------------
/chepy/modules/internal/constants.pyi:
--------------------------------------------------------------------------------
1 | from typing import Any, Dict, List
2 |
3 | class Encoding:
4 | py_encodings: Any = ...
5 | py_text_encodings: Any = ...
6 | asciichars: Any = ...
7 | brailles: Any = ...
8 | wingdings: dict = ...
9 | NATO_CONSTANTS_DICT: Dict[str, str] = ...
10 | LEETCODE: List[List[str]] = ...
11 | BASE91_ALPHABET: List[str] = ...
12 |
13 | class EncryptionConsts:
14 | MORSE_CODE_DICT: Any = ...
15 |
16 | class PcapUSB:
17 | qwerty_map: Any = ...
18 | qwerty_modifier: Any = ...
19 | dvorak: Any = ...
20 | dvorak_modifier: Any = ...
21 |
--------------------------------------------------------------------------------
/chepy/modules/internal/ls47.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | #
4 | # This software is hereby released into public domain. Use it wisely.
5 | #
6 | # Originally written by Mirek Kratochvil (2017)
7 | # Python3 port by Bernhard Esslinger (Feb 2018)
8 |
9 | import random
10 |
11 | letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()"
12 | tiles = list(zip(letters, map(lambda x: (x // 7, x % 7), range(7 * 7))))
13 |
14 |
15 | def check_key(key): # pragma: no cover
16 | if len(key) != len(letters):
17 | raise ValueError("Wrong key size")
18 | cnts = {}
19 | for c in letters:
20 | cnts[c] = 0
21 | for c in key:
22 | if not c in cnts:
23 | raise ValueError("Letter " + c + " not in LS47!")
24 | cnts[c] += 1
25 | if cnts[c] > 1:
26 | raise ValueError("Letter " + c + " duplicated in key!")
27 |
28 |
29 | def find_ix(letter): # pragma: no cover
30 | m = [l for l in tiles if l[0] == letter]
31 | if len(m) != 1:
32 | raise ValueError("Letter " + letter + " not in LS47!")
33 | for (l, pos) in m:
34 | return pos
35 |
36 |
37 | def find_pos(key, letter): # pragma: no cover
38 | p = key.find(letter)
39 | if p >= 0 and p < 7 * 7:
40 | return (p // 7, p % 7)
41 | raise ValueError("Letter " + letter + " not in key?!")
42 |
43 |
44 | def add_pos(a, b): # pragma: no cover
45 | return ((a[0] + b[0]) % 7, (a[1] + b[1]) % 7)
46 |
47 |
48 | def sub_pos(a, b):
49 | return ((a[0] - b[0]) % 7, (a[1] - b[1]) % 7)
50 |
51 |
52 | def find_at_pos(key, coord): # pragma: no cover
53 | return key[coord[1] + coord[0] * 7]
54 |
55 |
56 | def rotate_right(key, row, n): # pragma: no cover
57 | mid = key[7 * row : 7 * (row + 1)]
58 | n = (7 - n % 7) % 7
59 | return key[: 7 * row] + mid[n:] + mid[:n] + key[7 * (row + 1) :]
60 |
61 |
62 | def rotate_down(key, col, n): # pragma: no cover
63 | lines = [key[i * 7 : (i + 1) * 7] for i in range(7)]
64 | lefts = [l[:col] for l in lines]
65 | mids = [l[col] for l in lines]
66 | rights = [l[col + 1 :] for l in lines]
67 | n = (7 - n % 7) % 7
68 | mids = mids[n:] + mids[:n]
69 | return "".join(lefts[i] + mids[i] + rights[i] for i in range(7))
70 |
71 |
72 | def rotate_marker_right(m, row, n): # pragma: no cover
73 | if m[0] != row:
74 | return (m[0], m[1])
75 | else:
76 | return (m[0], (m[1] + n) % 7)
77 |
78 |
79 | def rotate_marker_down(m, col, n): # pragma: no cover
80 | if m[1] != col:
81 | return (m[0], m[1])
82 | else:
83 | return ((m[0] + n) % 7, m[1])
84 |
85 |
86 | def derive_key(password): # pragma: no cover
87 | i = 0
88 | k = letters
89 | for c in password:
90 | (row, col) = find_ix(c)
91 | k = rotate_down(rotate_right(k, i, col), i, row)
92 | i = (i + 1) % 7
93 | return k
94 |
95 |
96 | def encrypt(key, plaintext): # pragma: no cover
97 | check_key(key)
98 | mp = (0, 0)
99 | ciphertext = ""
100 | for p in plaintext:
101 | pp = find_pos(key, p)
102 | mix = find_ix(find_at_pos(key, mp))
103 | cp = add_pos(pp, mix)
104 | c = find_at_pos(key, cp)
105 | ciphertext += c
106 |
107 | key = rotate_right(key, pp[0], 1)
108 | cp = find_pos(key, c)
109 | key = rotate_down(key, cp[1], 1)
110 | mp = add_pos(mp, find_ix(c))
111 | return ciphertext
112 |
113 |
114 | def decrypt(key, ciphertext): # pragma: no cover
115 | check_key(key)
116 | mp = (0, 0)
117 | plaintext = ""
118 | for c in ciphertext:
119 | cp = find_pos(key, c)
120 | mix = find_ix(find_at_pos(key, mp))
121 | pp = sub_pos(cp, mix)
122 | p = find_at_pos(key, pp)
123 | plaintext += p
124 |
125 | key = rotate_right(key, pp[0], 1)
126 | cp = find_pos(key, c)
127 | key = rotate_down(key, cp[1], 1)
128 | mp = add_pos(mp, find_ix(c))
129 | return plaintext
130 |
131 |
132 | def encrypt_pad(key, plaintext, signature, padding_size): # pragma: no cover
133 |
134 | # TODO it would also be great to randomize the message length.
135 |
136 | check_key(key)
137 | padding = "".join(
138 | map(lambda x: letters[random.randint(0, len(letters) - 1)], range(padding_size))
139 | )
140 |
141 | return encrypt(key, padding + plaintext + "---" + signature)
142 |
143 |
144 | def decrypt_pad(key, padding_size, ciphertext): # pragma: no cover
145 | check_key(key)
146 | return decrypt(key, ciphertext)[padding_size:]
147 |
--------------------------------------------------------------------------------
/chepy/modules/language.py:
--------------------------------------------------------------------------------
1 | import unicodedata
2 | from typing import TypeVar
3 |
4 | import emoji
5 | import regex as re
6 |
7 | from ..core import ChepyCore, ChepyDecorators
8 |
9 | LanguageT = TypeVar("LanguageT", bound="Language")
10 |
11 |
12 | class Language(ChepyCore):
13 | def __init__(self, *data):
14 | super().__init__(*data)
15 |
16 | @ChepyDecorators.call_stack
17 | def search_perl_unicode_props(self, lang: str) -> LanguageT:
18 | """Search using perl unicode properties.
19 | https://perldoc.perl.org/perluniprops#(%5Cd+)-in-the-info-column-gives-the-number-of-Unicode-code-points-matched-by-this-property.
20 |
21 | Args:
22 | lang (str): Required. A string value identifying the language.
23 |
24 | Returns:
25 | Chepy: The Chepy object.
26 | """
27 | self.state = re.findall(r"\p{" + lang + "}", self._convert_to_str())
28 | return self
29 |
30 | @ChepyDecorators.call_stack
31 | def find_emojis(self) -> LanguageT:
32 | """Find emojis, symbols, pictographs, map symbols and flags
33 |
34 | Returns:
35 | Chepy: The Chepy object.
36 | """
37 | self.state = [e.get("emoji") for e in emoji.emoji_list(self._convert_to_str())]
38 | return self
39 |
40 | @ChepyDecorators.call_stack
41 | def encode(self, encoding: str, errors: str = "backslashreplace") -> LanguageT:
42 | """Encode the string using the given encoding.
43 |
44 | Args:
45 | encoding (str): Encoding to use.
46 | errors (str, optional): How to handle errors when encoding. Defaults to 'backslashreplace'.
47 |
48 | Returns:
49 | Chepy: The Chepy object.
50 | """
51 | self.state = self._convert_to_str().encode(encoding, errors=errors)
52 | return self
53 |
54 | @ChepyDecorators.call_stack
55 | def encode_us_ascii_7_bit(self) -> LanguageT:
56 | """Encode state using US ascii 7 bit
57 |
58 | Returns:
59 | Chepy: The Chepy object.
60 | """
61 | data = self._convert_to_str()
62 | self.state = "".join(chr(ord(c) & 127) for c in data)
63 | return self
64 |
65 | @ChepyDecorators.call_stack
66 | def decode(self, encoding: str, errors: str = "backslashreplace") -> LanguageT:
67 | """Decode the string using the given encoding.
68 |
69 | Args:
70 | encoding (str): Encoding to use.
71 | errors (str, optional): How to handle errors when decoding. Defaults to 'backslashreplace'.
72 |
73 | Returns:
74 | Chepy: The Chepy object.
75 | """
76 | self.state = self._convert_to_bytes().decode(encoding, errors=errors)
77 | return self
78 |
79 | @ChepyDecorators.call_stack
80 | def remove_diacritics(self) -> LanguageT:
81 | """Replaces accented characters latin character equivalent.
82 |
83 | Returns:
84 | Chepy: The Chepy object.
85 | """
86 | self.state = unicodedata.normalize("NFKD", self._convert_to_str()).encode(
87 | "ascii", errors="ignore"
88 | )
89 | return self
90 |
91 | @ChepyDecorators.call_stack
92 | def unicode_to_str(self, as_bytes=False) -> LanguageT:
93 | """Escape any \\u characters to its proper unicode representation
94 |
95 | Args:
96 | as_bytes (bool): Treat state as bytes. This does not handle %u or U+ encodings
97 |
98 | Returns:
99 | Chepy: The Chepy object.
100 | """
101 | if as_bytes:
102 | self.state = self._convert_to_bytes().decode(
103 | "unicode-escape", errors="backslashreplace"
104 | )
105 | else:
106 | data = self._convert_to_str()
107 | cleaned_string = re.sub(r"(\\u|%u|U\+)", r"\\u", data)
108 | self.state = bytes(cleaned_string, "utf-8").decode(
109 | "unicode-escape", errors="backslashreplace"
110 | )
111 | return self
112 |
113 | @ChepyDecorators.call_stack
114 | def str_to_unicode(self, prefix: str = "\\u", all_chars: bool = False) -> LanguageT:
115 | """Convert unicode to str
116 |
117 | Args:
118 | prefix (str): Prefix character.
119 | all_chars (bool): Force convert all chars to unicode.
120 |
121 | Returns:
122 | Chepy: The Chepy object.
123 | """
124 | data = self._convert_to_str()
125 | if all_chars:
126 | hold = []
127 | for d in data:
128 | hold.append("{}{:04x}".format(prefix, ord(d)))
129 | self.state = "".join(hold)
130 | return self
131 | self.state = data.encode("unicode_escape")
132 | return self
133 |
--------------------------------------------------------------------------------
/chepy/modules/language.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, Literal, TypeVar
3 |
4 | LanguageT = TypeVar("LanguageT", bound="Language")
5 |
6 | ENCODINGS = Literal[
7 | "utf_16_le",
8 | "utf_16_be",
9 | "utf_7",
10 | "utf_8",
11 | "cp500",
12 | "cp037",
13 | "cp874",
14 | "cp932",
15 | "gbk",
16 | "gb2312",
17 | "cp949",
18 | "cp950",
19 | "cp1250",
20 | "cp1251",
21 | "cp1252",
22 | "cp1253",
23 | "cp1254",
24 | "cp1255",
25 | "cp1256",
26 | "cp1257",
27 | "cp1258",
28 | "iso8859_2",
29 | "iso8859_3",
30 | "iso8859_4",
31 | "iso8859_5",
32 | "iso8859_6",
33 | "iso8859_7",
34 | "iso8859_8",
35 | "iso8859_9",
36 | "iso8859_10",
37 | "iso8859_11",
38 | "iso8859_13",
39 | "iso8859_14",
40 | "iso8859_15",
41 | "ascii",
42 | "unicode-escape",
43 | ]
44 |
45 | class Language(ChepyCore):
46 | def __init__(self, *data: Any) -> None: ...
47 | state: Any = ...
48 | def search_perl_unicode_props(self: LanguageT, lang: str) -> LanguageT: ...
49 | def find_emojis(self: LanguageT) -> LanguageT: ...
50 | def encode(self: LanguageT, encoding: ENCODINGS, errors: Literal['ignore', 'replace', 'backslashreplace']=...) -> LanguageT: ...
51 | def encode_us_ascii_7_bit(self: LanguageT) -> LanguageT: ...
52 | def decode(self: LanguageT, encoding: ENCODINGS, errors: Literal['ignore', 'replace', 'backslashreplace']=...) -> LanguageT: ...
53 | def remove_diacritics(self: LanguageT) -> LanguageT: ...
54 | def unicode_to_str(self: LanguageT, as_bytes: bool=False) -> LanguageT: ...
55 | def str_to_unicode(self: LanguageT, prefix: Literal['\\u', '%u', 'U+']='\\u', all_chars: bool=False) -> LanguageT: ...
56 |
--------------------------------------------------------------------------------
/chepy/modules/links.py:
--------------------------------------------------------------------------------
1 | import base64
2 | from typing import TypeVar
3 |
4 | import regex as re
5 |
6 | from ..core import ChepyCore, ChepyDecorators
7 |
8 | LinksT = TypeVar("LinksT", bound="Links")
9 |
10 |
11 | class Links(ChepyCore):
12 | def __init__(self, *data):
13 | super().__init__(*data)
14 |
15 | @ChepyDecorators.call_stack
16 | def pastebin_to_raw(self) -> LinksT:
17 | """Convert a pastebin link to raw pastebin link
18 |
19 | Returns:
20 | Chepy: The Chepy object.
21 |
22 | Examples:
23 | >>> Chepy("https://pastebin.com/abCD").pastebin_to_raw()
24 | 'https://pastebin.com/raw/abCD'
25 | """
26 | self.state = re.sub(r"(pastebin\.com)(/)", r"\1/raw\2", self._convert_to_str())
27 | return self
28 |
29 | @ChepyDecorators.call_stack
30 | def github_to_raw(self) -> LinksT:
31 | """Convert a github link to raw github link
32 |
33 | Returns:
34 | Chepy: The Chepy object.
35 |
36 | Examples:
37 | >>> Chepy("https://github.com/securisec/chepy/blob/master/README.md").github_to_raw()
38 | 'https://raw.githubusercontent.com/securisec/chepy/master/README.md'
39 | """
40 | self.state = re.sub(
41 | "/blob",
42 | "",
43 | re.sub(
44 | r"(github\.com)(/)",
45 | r"raw.githubusercontent.com\2",
46 | self._convert_to_str(),
47 | ),
48 | )
49 | return self
50 |
51 | @ChepyDecorators.call_stack
52 | def google_search_ei_to_epoch(self) -> LinksT:
53 | """Convert a google search ei query param to epoch
54 |
55 | Returns:
56 | Chepy: The Chepy object.
57 |
58 | Examples:
59 | >>> Chepy("Bh8hYqykHc64mAXkkoTgCg==").google_search_ei_to_epoch()
60 | 1646337798
61 | """
62 | decoded = base64.urlsafe_b64decode(self._convert_to_str())
63 | timestamp = ord(chr(decoded[0]))
64 | timestamp += ord(chr(decoded[1])) * 256
65 | timestamp += ord(chr(decoded[2])) * 256**2
66 | timestamp += ord(chr(decoded[3])) * 256**3
67 | self.state = timestamp
68 | return self
69 |
--------------------------------------------------------------------------------
/chepy/modules/links.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar
3 |
4 | LinksT = TypeVar('LinksT', bound='Links')
5 |
6 | class Links(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def pastebin_to_raw(self: LinksT) -> LinksT: ...
10 | def github_to_raw(self: LinksT) -> LinksT: ...
11 | def google_search_ei_to_epoch(self: LinksT) -> LinksT: ...
12 |
--------------------------------------------------------------------------------
/chepy/modules/networking.py:
--------------------------------------------------------------------------------
1 | import collections
2 | import ipaddress
3 | import socket
4 | import ssl
5 | import urllib.parse as _py_urlparse
6 | from typing import TypeVar
7 |
8 | import regex as re
9 |
10 | from ..core import ChepyCore, ChepyDecorators
11 |
12 | NetworkingT = TypeVar("NetworkingT", bound="Networking")
13 |
14 |
15 | class Networking(ChepyCore):
16 | def __init__(self, *data):
17 | super().__init__(*data)
18 |
19 | @ChepyDecorators.call_stack
20 | def defang_url(self) -> NetworkingT:
21 | """Make a URL harmless
22 |
23 | Takes a Universal Resource Locator (URL) and 'Defangs' it;
24 | meaning the URL becomes invalid, neutralising the risk of accidentally
25 | clicking on a malicious link. This is often used when dealing with
26 | malicious links or IOCs.
27 |
28 | Returns:
29 | Chepy: The Chepy object.
30 |
31 | Examples:
32 | >>> Chepy("https://app.google.com/?lol=some data&a=1").defang_url().o
33 | "hxxps://app[.]google[.]com/?lol=some data&a=1"
34 | """
35 | self.state = re.sub(r"(^htt)", "hxx", self._convert_to_str())
36 | self.state = re.sub(r"\.", "[.]", self._convert_to_str())
37 | return self
38 |
39 | @ChepyDecorators.call_stack
40 | def refang_url(self) -> NetworkingT:
41 | """Refangs a URL so that it is clickable
42 |
43 | Returns:
44 | Chepy: The Chepy object.
45 |
46 | Examples:
47 | >>> Chepy("hxxps://app[.]google[.]com/?lol=some data&a=1").refang_url().o
48 | "https://app.google.com/?lol=some data&a=1"
49 | """
50 | self.state = re.sub(r"(^hxx)", "htt", self._convert_to_str())
51 | self.state = re.sub(r"\[\.\]", ".", self._convert_to_str())
52 | return self
53 |
54 | @ChepyDecorators.call_stack
55 | def defang_ip(self) -> NetworkingT:
56 | """Make an IP address harmless
57 |
58 | Takes a IPv4 or IPv6 address and 'Defangs' it, meaning the
59 | IP becomes invalid, removing the risk of accidentally utilising
60 | it as an IP address.
61 |
62 | Returns:
63 | Chepy: The Chepy object.
64 |
65 | Examples:
66 | >>> Chepy("2001:4860:4860::8844").defang_ip().o
67 | "2001[:]4860[:]4860[:][:]8844"
68 |
69 | >>> Chepy("127.0.0.1").defang_ip().o
70 | "127[.]0[.]0[.]1"
71 | """
72 | if ":" in self._convert_to_str():
73 | self.state = re.sub(r":", "[:]", self._convert_to_str())
74 | else:
75 | self.state = re.sub(r"\.|:", "[.]", self._convert_to_str())
76 | return self
77 |
78 | @ChepyDecorators.call_stack
79 | def refang_ip(self) -> NetworkingT:
80 | """Refangs an IP address
81 |
82 | Returns:
83 | Chepy: The Chepy object.
84 |
85 | Examples:
86 | >>> Chepy("127[.]0[.]0[.]1").refang_ip().o
87 | "127.0.0.1"
88 | """
89 | self.state = re.sub(r"\[\.\]|\[\:\]", ".", self._convert_to_str())
90 | return self
91 |
92 | @ChepyDecorators.call_stack
93 | def parse_uri(self) -> NetworkingT:
94 | """Parse a URI
95 |
96 | Returns:
97 | Chepy: The Chepy object.
98 |
99 | Examples:
100 | >>> Chepy("http://example.com/resource?foo=bar#fragment").parse_uri().o
101 | {
102 | "scheme": "http",
103 | "location": "example.com",
104 | "path": "/resource",
105 | "params": "",
106 | "query": {"foo": ["bar"]},
107 | "fragment": "fragment",
108 | }
109 | """
110 | parsed = _py_urlparse.urlparse(self._convert_to_str())
111 | self.state = {
112 | "scheme": parsed.scheme,
113 | "location": parsed.netloc,
114 | "path": parsed.path,
115 | "params": parsed.params,
116 | "query": _py_urlparse.parse_qs(parsed.query),
117 | "fragment": parsed.fragment,
118 | }
119 | return self
120 |
121 | @ChepyDecorators.call_stack
122 | def parse_ip_range(self) -> NetworkingT:
123 | """Enumerate IP address in a CIDR range
124 |
125 | Returns:
126 | Chepy: The Chepy object.
127 |
128 | Examples:
129 | >>> Chepy("10.10.10.1/24").parse_ip_range().o
130 | [
131 | "10.10.10.1",
132 | "10.10.10.2,
133 | ...
134 | "10.10.10.254"
135 | ]
136 | """
137 | self.state = [
138 | str(i)
139 | for i in ipaddress.ip_network(self._convert_to_str(), strict=False).hosts()
140 | ]
141 | return self
142 |
143 | @ChepyDecorators.call_stack
144 | def parse_ipv6(self) -> NetworkingT:
145 | """Get longhand and shorthand of IPv6
146 |
147 | Returns:
148 | Chepy: The Chepy object.
149 |
150 | Examples:
151 | >>> Chepy("2001:4860:4860::8888").parse_ipv6().o
152 | {
153 | "long": "2001:4860:4860:0000:0000:0000:0000:8888",
154 | "short": "2001:4860:4860::8888",
155 | }
156 | """
157 | ip = ipaddress.ip_address(self._convert_to_str())
158 | self.state = {"long": ip.exploded, "short": ip.compressed}
159 | return self
160 |
161 | @ChepyDecorators.call_stack
162 | def get_ssl_cert(self, port: int = 443) -> NetworkingT:
163 | """Get the server side SSL certificate for a domain
164 |
165 | Args:
166 | port (int, optional): Server port. Defaults to 443.
167 |
168 | Returns:
169 | Chepy: The Chepy object
170 |
171 | Examples:
172 | >>> Chepy('google.com').get_ssl_cert().o
173 | {
174 | 'subject': {
175 | 'commonName': '*.google.com',
176 | 'organizationName': 'Google LLC',
177 | ...
178 | 'caIssuers': ('http://pki.goog/gsr2/GTS1O1.crt',),
179 | 'crlDistributionPoints': ('http://crl.pki.goog/GTS1O1.crl',)
180 | }
181 | """
182 | domain = re.sub(r"^\w+://", "", self._convert_to_str())
183 | with socket.create_connection((domain, port)) as sock:
184 | context = ssl.create_default_context()
185 | context.check_hostname = False
186 | with context.wrap_socket(sock, server_hostname=domain) as sslsock:
187 | cert = sslsock.getpeercert()
188 | final = {}
189 | for key in cert.keys():
190 | if key == "subject" or key == "issuer":
191 | final[key] = dict(
192 | collections.ChainMap(*list(map(dict, cert[key])))
193 | )
194 | elif key == "subjectAltName":
195 | final[key] = list(
196 | map(lambda x: dict([x]), cert["subjectAltName"])
197 | )
198 | else:
199 | final[key] = cert[key]
200 | self.state = final
201 | return self
202 |
203 | @ChepyDecorators.call_stack
204 | def int_to_ip(self) -> NetworkingT:
205 | """Convert an integer to an IP address
206 |
207 | Returns:
208 | Chepy: The Chepy object.
209 |
210 | Examples:
211 | >>> Chepy(3232235777).int_to_ip().o
212 | """
213 | self.state = str(ipaddress.ip_address(self._convert_to_int()))
214 | return self
215 |
216 | @ChepyDecorators.call_stack
217 | def ip_to_int(self) -> NetworkingT:
218 | """Convert an integer to an IP address
219 |
220 | Returns:
221 | Chepy: The Chepy object.
222 |
223 | Examples:
224 | >>> Chepy(3232235777).int_to_ip().o
225 | """
226 | self.state = int(ipaddress.ip_address(self._convert_to_str()))
227 | return self
228 |
--------------------------------------------------------------------------------
/chepy/modules/networking.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar
3 |
4 | NetworkingT = TypeVar('NetworkingT', bound='Networking')
5 |
6 | class Networking(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def defang_url(self: NetworkingT) -> NetworkingT: ...
10 | def refang_url(self: NetworkingT) -> NetworkingT: ...
11 | def defang_ip(self: NetworkingT) -> NetworkingT: ...
12 | def refang_ip(self: NetworkingT) -> NetworkingT: ...
13 | def parse_uri(self: NetworkingT) -> NetworkingT: ...
14 | def parse_ip_range(self: NetworkingT) -> NetworkingT: ...
15 | def parse_ipv6(self: NetworkingT) -> NetworkingT: ...
16 | def int_to_ip(self: NetworkingT) -> NetworkingT: ...
17 | def ip_to_int(self: NetworkingT) -> NetworkingT: ...
18 | def get_ssl_cert(self: NetworkingT, port: int=...) -> NetworkingT: ...
19 |
--------------------------------------------------------------------------------
/chepy/modules/other.py:
--------------------------------------------------------------------------------
1 | from typing import TypeVar
2 | from uuid import uuid4
3 |
4 | from ..core import ChepyCore, ChepyDecorators
5 |
6 | OtherT = TypeVar("OtherT", bound="Other")
7 |
8 |
9 | class Other(ChepyCore):
10 | def __init__(self, *data):
11 | super().__init__(*data)
12 |
13 | @ChepyDecorators.call_stack
14 | def generate_uuid(self) -> OtherT:
15 | """Generate v4 UUID
16 |
17 | Generates an RFC 4122 version 4 compliant Universally Unique Identifier
18 | (UUID), also known as a Globally Unique Identifier (GUID). A version 4
19 | UUID relies on random numbers
20 |
21 | Returns:
22 | str: A random UUID
23 |
24 | Examples:
25 | >>> Chepy('').generate_uuid()
26 | 92644a99-632a-47c1-b169-5a141172924b
27 | """
28 | self.state = str(uuid4())
29 | return self
30 |
--------------------------------------------------------------------------------
/chepy/modules/other.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar
3 |
4 | OtherT = TypeVar('OtherT', bound='Other')
5 |
6 | class Other(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def generate_uuid(self: OtherT) -> OtherT: ...
10 |
--------------------------------------------------------------------------------
/chepy/modules/publickey.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, Literal, TypeVar, Union
3 |
4 | RSA: Any
5 | OpenSSL: Any
6 | PublickeyT = TypeVar('PublickeyT', bound='Publickey')
7 |
8 | class Publickey(ChepyCore):
9 | def __init__(self, *data: Any) -> None: ...
10 | state: Any = ...
11 | def parse_x509_pem(self: PublickeyT) -> PublickeyT: ...
12 | def parse_x509_der_hex(self: PublickeyT) -> PublickeyT: ...
13 | def public_from_x509(self: PublickeyT) -> PublickeyT: ...
14 | def pem_to_der_hex(self: PublickeyT) -> PublickeyT: ...
15 | def der_hex_to_pem(self: PublickeyT) -> PublickeyT: ...
16 | def parse_public_pem(self: PublickeyT) -> PublickeyT: ...
17 | def parse_private_pem(self: PublickeyT) -> PublickeyT: ...
18 | def dump_pkcs12_cert(self: PublickeyT, password: Union[str, bytes]) -> PublickeyT: ...
19 | def generate_rsa_keypair(self: PublickeyT, bits:int=..., format:str=..., passphrase:str=...) -> PublickeyT: ...
20 | def generate_ecc_keypair(self: PublickeyT, curve:Literal['p256', 'p384', 'p521']='p256', format:Literal['PEM', 'DER']='PEM') -> PublickeyT: ...
21 |
--------------------------------------------------------------------------------
/chepy/modules/search.py:
--------------------------------------------------------------------------------
1 | from typing import TypeVar, Union
2 |
3 | import regex as re
4 |
5 | from ..core import ChepyCore, ChepyDecorators
6 |
7 | SearchT = TypeVar("SearchT", bound="Search")
8 |
9 |
10 | class Search(ChepyCore):
11 | def __init__(self, *data):
12 | super().__init__(*data)
13 |
14 | """Class that is geared towards regex searches of secrets
15 |
16 | `Reference `__
17 | """
18 |
19 | @ChepyDecorators.call_stack
20 | def search(self, pattern: Union[str, bytes]) -> SearchT:
21 | """Search. Group matches are returned as tuples.
22 |
23 | Args:
24 | pattern (Union[str, bytes]): Bytes pattern to search
25 |
26 | Returns:
27 | Chepy: The Chepy object.
28 |
29 | Examples:
30 | >>> Chepy("abcdefg123 and again abcdefg123").search("abc(de)fg(12)(3)").o
31 | [('abcdefg123', 'de', '12', '3'), ('abcdefg123', 'de', '12', '3')]
32 | """
33 | pattern = self._str_to_bytes(pattern)
34 | self.state = re.findall(pattern, self._convert_to_bytes())
35 | return self
36 |
37 | @ChepyDecorators.call_stack
38 | def search_list(self, pattern: Union[str, bytes]) -> SearchT:
39 | """Search all items in a list. List items are coerced into bytes first.
40 | Group matches are returned as tuples.
41 |
42 | Args:
43 | pattern (Union[str, bytes]): Bytes pattern to search
44 |
45 | Returns:
46 | Chepy: The Chepy object.
47 | """
48 | assert isinstance(self.state, list), "State is not a list"
49 |
50 | converted = [self._to_bytes(s) for s in self.state]
51 | pattern = self._str_to_bytes(pattern)
52 | pc = re.compile(pattern)
53 |
54 | hold = []
55 | for search in converted:
56 | matches = pc.findall(search)
57 | if len(matches) > 0:
58 | hold.append(matches)
59 |
60 | self.state = hold
61 | return self
62 |
63 | @ChepyDecorators.call_stack
64 | def search_ctf_flags(self, prefix: str, postfix: str = ".+?\\{*\\}") -> SearchT:
65 | """Search CTF style flags.
66 |
67 | This by default assumes that the flag format is similar
68 | to something like picoCTF{some_flag} as an example.
69 |
70 | Args:
71 | prefix (str): Prefix of the flag. Like `picoCTF`
72 | postfix (str, optional): Regex for the remainder of the flag.
73 | Defaults to '.+\\{.+\\}'.
74 |
75 | Returns:
76 | Chepy: The Chepy object.
77 |
78 | Examples:
79 | >>> Chepy("tests/files/flags").read_file().search_ctf_flags("pico").get_by_index(0)
80 | picoCTF{r3source_pag3_f1ag}
81 | """
82 | self.state = re.findall(prefix + postfix, self._convert_to_str(), re.IGNORECASE)
83 | return self
84 |
85 | @ChepyDecorators.call_stack
86 | def search_slack_tokens(self) -> SearchT:
87 | """Search slack tokens
88 |
89 | Returns:
90 | Chepy: The Chepy object.
91 |
92 | Examples:
93 | >>> Chepy("tests/files/flags").read_file().search_slack_tokens().get_by_index(0)
94 | xoxp...859
95 | """
96 | self.state = re.findall(
97 | "(xox[p|b|o|a]-[0-9]{12}-[0-9]{12}-[0-9]{12}-[a-z0-9]{32})",
98 | self._convert_to_str(),
99 | )
100 | return self
101 |
102 | @ChepyDecorators.call_stack
103 | def search_slack_webhook(self) -> SearchT:
104 | """Search slack webhook
105 |
106 | Returns:
107 | Chepy: The Chepy object.
108 | """
109 | self.state = re.findall(
110 | r"https://hooks\.slack\.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}",
111 | self._convert_to_str(),
112 | )
113 | return self
114 |
115 | @ChepyDecorators.call_stack
116 | def search_private_key(self) -> SearchT:
117 | """Search varios private key headers
118 |
119 | Returns:
120 | Chepy: The Chepy object.
121 | """
122 | self.state = re.findall(
123 | "-----BEGIN (RSA|OPENSSH|DSA|EC) PRIVATE KEY-----", self._convert_to_str()
124 | )
125 | return self
126 |
127 | @ChepyDecorators.call_stack
128 | def search_twilio_key(self) -> SearchT:
129 | """Search for Twilio api key
130 |
131 | Returns:
132 | Chepy: The Chepy object.
133 | """
134 | self.state = re.findall("SK[a-z0-9]{32}", self._convert_to_str())
135 | return self
136 |
137 | @ChepyDecorators.call_stack
138 | def search_aws_key(self) -> SearchT:
139 | """Search for AWS key id
140 |
141 | Returns:
142 | Chepy: The Chepy object.
143 | """
144 | self.state = re.findall("AKIA[0-9A-Z]{16}", self._convert_to_str())
145 | return self
146 |
--------------------------------------------------------------------------------
/chepy/modules/search.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, TypeVar, Union
3 |
4 | SearchT = TypeVar('SearchT', bound='Search')
5 |
6 | class Search(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def search(self: SearchT, pattern: Union[str, bytes]) -> SearchT: ...
10 | def search_list(self: SearchT, pattern: Union[str, bytes]) -> SearchT: ...
11 | def search_ctf_flags(self: SearchT, prefix: str, postfix: str=...) -> SearchT: ...
12 | def search_slack_tokens(self: SearchT) -> SearchT: ...
13 | def search_slack_webhook(self: SearchT) -> SearchT: ...
14 | def search_private_key(self: SearchT) -> SearchT: ...
15 | def search_twilio_key(self: SearchT) -> SearchT: ...
16 | def search_aws_key(self: SearchT) -> SearchT: ...
17 |
--------------------------------------------------------------------------------
/chepy/modules/utils.pyi:
--------------------------------------------------------------------------------
1 | from ..core import ChepyCore
2 | from typing import Any, Literal, TypeVar, Union
3 |
4 | UtilsT = TypeVar('UtilsT', bound='Utils')
5 |
6 | class Utils(ChepyCore):
7 | def __init__(self, *data: Any) -> None: ...
8 | state: Any = ...
9 | def reverse(self: UtilsT, count: int=...) -> UtilsT: ...
10 | def count_occurances(self: UtilsT, regex: str, case_sensitive: bool=...) -> UtilsT: ...
11 | def remove_whitespace(self: UtilsT, spaces: bool=..., carriage_return: bool=..., line_feeds: bool=..., tabs: bool=..., form_feeds: bool=...) -> UtilsT: ...
12 | def remove_nullbytes(self: UtilsT) -> UtilsT: ...
13 | def regex_search(self: UtilsT, pattern: str, is_bytes: bool=False, ignore_case: bool=False, multiline: bool=False, dotall: bool=False, unicode: bool=False, extended: bool=False) -> UtilsT: ...
14 | def split_by_char(self: UtilsT, delimiter: str=...) -> UtilsT: ...
15 | def split_by_regex(self: UtilsT, pattern: str=..., trim: Any=...) -> UtilsT: ...
16 | def split_by_n(self: UtilsT, n: int) -> UtilsT: ...
17 | def split_lines(self: UtilsT) -> UtilsT: ...
18 | def split_chunks(self: UtilsT, chunk_size: int) -> UtilsT: ...
19 | def select_every_n(self: UtilsT, n: int, start: int=...) -> UtilsT: ...
20 | def unique(self: UtilsT) -> UtilsT: ...
21 | def sort_list(self: UtilsT, reverse: bool=...) -> UtilsT: ...
22 | def sort_dict_key(self: UtilsT, reverse: bool=...) -> UtilsT: ...
23 | def sort_dict_value(self: UtilsT, reverse: Any=...) -> UtilsT: ...
24 | def filter_list(self: UtilsT, by: Union[str, dict], regex: bool=...) -> UtilsT: ...
25 | def filter_list_by_length(self: UtilsT, length: int, exact: bool=...) -> UtilsT: ...
26 | def filter_dict_key(self: UtilsT, by: str) -> UtilsT: ...
27 | def filter_dict_value(self: UtilsT, by: str) -> UtilsT: ...
28 | def slice(self: UtilsT, start: int=..., end: int=...) -> UtilsT: ...
29 | def strip_ansi(self: UtilsT) -> UtilsT: ...
30 | def strip(self: UtilsT, pattern: str, ignore_case: bool=...) -> UtilsT: ...
31 | def strip_non_printable(self: UtilsT) -> UtilsT: ...
32 | def find_replace(self: UtilsT, pattern: Union[bytes, str], repl: Union[bytes, str], ignore_case: bool=...) -> UtilsT: ...
33 | def escape_string(self: UtilsT) -> UtilsT: ...
34 | def unescape_string(self: UtilsT) -> UtilsT: ...
35 | def color_hex_to_rgb(self: UtilsT) -> UtilsT: ...
36 | def diff(self: UtilsT, state: int=..., buffer: int=..., colors: bool=False, swap: bool=False, only_changes: bool=False) -> UtilsT: ...
37 | def pad(self: UtilsT, width: int, direction: Literal['left', 'right']=..., char: str=...) -> UtilsT: ...
38 | def count(self: UtilsT) -> UtilsT: ...
39 | def set(self: UtilsT) -> UtilsT: ...
40 | def regex_to_str(self: UtilsT, all_combo: bool=...) -> UtilsT: ...
41 | def shuffle(self: UtilsT) -> UtilsT: ...
42 | def drop_bytes(self: UtilsT, start: int, length: int) -> UtilsT: ...
43 | def without(self: UtilsT, *values: Any) -> UtilsT: ...
44 | def pick(self: UtilsT, *values: Any) -> UtilsT: ...
45 | def expand_alpha_range(self: UtilsT, join_by: Union[str, None]=None) -> UtilsT: ...
46 | def split_and_count(self: UtilsT, pattern: Union[str, bytes], threshold: int=None) -> UtilsT: ...
47 |
--------------------------------------------------------------------------------
/cli.py:
--------------------------------------------------------------------------------
1 | from chepy.__main__ import main
2 |
3 | if __name__ == "__main__":
4 | main()
5 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/assets/cc_encoding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/docs/assets/cc_encoding.png
--------------------------------------------------------------------------------
/docs/assets/clicolors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/docs/assets/clicolors.png
--------------------------------------------------------------------------------
/docs/assets/ctf.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/docs/assets/ctf.gif
--------------------------------------------------------------------------------
/docs/assets/hmac_hash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/docs/assets/hmac_hash.png
--------------------------------------------------------------------------------
/docs/assets/plugin.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/docs/assets/plugin.gif
--------------------------------------------------------------------------------
/docs/chepy.md:
--------------------------------------------------------------------------------
1 | # Chepy Class
2 |
3 | The **Chepy** class in the main class for Chepy, and includes all the methods from all the different classes under modules. This class takes ***args** as its argument, and each argument that is passed to it becomes its own state.
4 |
5 | ```python
6 | >>> from chepy import Chepy
7 | >>> c = Chepy("some data", "/some/path/file")
8 | >>> c.states
9 | {0: "some data", 1: "/some/path/file"}
10 | ```
11 |
12 | ```eval_rst
13 | .. automodule:: chepy
14 | :members:
15 | :inherited-members:
16 | ```
--------------------------------------------------------------------------------
/docs/cli.md:
--------------------------------------------------------------------------------
1 | # Chepy CLI
2 |
3 | Chepy CLI is a fully dynamically generated cli that combines the power for python-fire and prompt_toolkit to create its cli. The cli is used very similar to how the main `Chepy` class is used as it allows for method chaining. We know from the docs that some of the methods in the `Chepy` class takes optional or required arguments. In the cli, these are passed as flags. Refer to the [examples](./examples.md) for use cases.
4 |
5 | ## Cli options
6 | ```bash
7 | usage: chepy [-h] [-v] [-r RECIPE] [data [data ...]]
8 |
9 | positional arguments:
10 | data
11 |
12 | optional arguments:
13 | -h, --help show this help message and exit
14 | -v, --version show program's version number and exit
15 | -r RECIPE, --recipe RECIPE
16 | ```
17 |
18 | ## Cli magic markers
19 | There are three special characters in the cli.
20 |
21 | - `!` If a line begins with `!` it is interpreted as a shell command. For example: `! ls -la`
22 | - `#` If a line begins with `#` it is interpreted as a comment. For example: `# hello`
23 | - `?` If a line begins with `?` it provides help for the provided Chepy method. For example: `? to_hex`
24 |
25 | ### Cli Recipes
26 | The cli can be run in a non interactive mode using the `-r` flag. This flag will load the recipe that is supplied and run it on the arguments that is provided.
27 |
28 | ```bash
29 | # Example
30 | chepy -r test.recipe a.png
31 | ```
32 |
33 | ### Using builtins
34 |
35 | One of the more advanced functions of the cli allows the user to use arbitrary builtin methods when the state does not contain a Chepy object.
36 |
37 | Consider this example in code. We will parse a User agent string in this case:
38 | ```python
39 | >>> ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
40 | >>> c = Chepy(ua).parse_user_agent()
41 | {'user_agent': {'family': 'Other', 'major': None, 'minor': None, 'patch': None}, 'os': {'family': 'Other', 'major': None, 'minor': None, 'patch': None, 'patch_minor': None}, 'device': {'family': 'Other', 'brand': None, 'model': None}, 'string': 'ua'}
42 | # The state type currently is Chepy
43 | >>> c.o
44 | # The state type now is a dict
45 | >>> c.get("user_agent").get("family")
46 | "Chrome"
47 | # we are using the dict builtin method get to pull the values based on keys
48 | ```
49 |
50 | This same behavior is replicated in the Chepy cli.
51 |
52 | [](https://asciinema.org/a/BTBg3PLFeiN21UBcpjYxWWLnc)
53 |
54 | ### Cli only methods
55 | For completeness sake everything is document here, but the only functions that are callable from the CLI are functions that start with `cli_`.
56 |
57 | ### Cli shell commands
58 | It is possible to run shell commands from the cli py starting the command with a `!`.
59 |
60 | ```bash
61 | >>> !ls -la | grep py
62 | ```
63 | This will run the following command inside the Chepy cli
64 |
65 | ```eval_rst
66 | .. automodule:: chepy.modules.internal.cli
67 | :members:
68 | ```
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | import os
14 | import sys
15 | from recommonmark.transform import AutoStructify
16 |
17 | sys.path.insert(0, os.path.abspath("."))
18 |
19 |
20 | def setup(app):
21 | app.add_config_value(
22 | "recommonmark_config",
23 | {
24 | "enable_eval_rst": True,
25 | },
26 | True,
27 | )
28 | app.add_transform(AutoStructify)
29 |
30 |
31 | # -- Project information -----------------------------------------------------
32 |
33 | project = "Chepy"
34 | copyright = "2025, @securisec"
35 | author = "@securisec"
36 |
37 | master_doc = "index"
38 |
39 |
40 | # -- General configuration ---------------------------------------------------
41 |
42 | # Add any Sphinx extension module names here, as strings. They can be
43 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
44 | # ones.
45 | extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon", "recommonmark"]
46 |
47 | # Add any paths that contain templates here, relative to this directory.
48 | templates_path = ["_templates"]
49 |
50 | # List of patterns, relative to source directory, that match files and
51 | # directories to ignore when looking for source files.
52 | # This pattern also affects html_static_path and html_extra_path.
53 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
54 |
55 |
56 | # -- Options for HTML output -------------------------------------------------
57 |
58 | # The theme to use for HTML and HTML Help pages. See the documentation for
59 | # a list of builtin themes.
60 | #
61 | html_theme = "alabaster"
62 | html_logo = "../logo.png"
63 |
64 | html_theme_options = {"fixed_sidebar": False}
65 |
66 | # Add any paths that contain custom static files (such as style sheets) here,
67 | # relative to this directory. They are copied after the builtin static files,
68 | # so a file named "default.css" will overwrite the builtin "default.css".
69 | html_static_path = ["_static"]
70 |
71 | autodoc_member_order = "groupwise"
72 |
73 | source_suffix = {
74 | ".rst": "restructuredtext",
75 | ".txt": "markdown",
76 | ".md": "markdown",
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/docs/config.md:
--------------------------------------------------------------------------------
1 | # Config
2 |
3 | Chepy is set to look at the present working directory for a a folder called **.chepy** for config files. By default, Chepy config files are stored in a folder called **.chepy** in the users home directory. There are two files in it.
4 |
5 | If any of the config options are missing, Chepy will automatically assign default values to it. If **.chepy** folder is detected, but config options have been set, then Chepy will automatically create a set of default config options.
6 |
7 | ## chepy.conf
8 | ### Plugin.enableplugins
9 | This should be set to either `true` or `false` to control if plugins should be loaded by Chepy. This can be optionally controlled via the `CHEPY_PLUGINS` environment variable. Valid values are `true` and `false`.
10 | ### Plugin.pluginpath
11 | This path controls where chepy will look for plugins and extensions. For more information, see [plugins](/plugins)
12 |
13 | ### Cli.history_path
14 | Path where the chepy cli history is stored. Defaults to *USERHOME/.chepy/chepy_history*
15 | ### Cli.prompt_colors
16 | Controls the colors of **>>>** in chepy prompt. Should be space seperated 3 hex color codes. Defaults to *#00ffff #ff0000 #ffd700*
17 | ### Cli.show_rprompt
18 | Controls visibility of the right prompt. Value should be *true* or *false*. Defaults to *false*.
19 | ### Cli.prompt_rprompt
20 | Controls the colors of of the right prompt. Defaults to *#00ff48*
21 | ### Cli.prompt_bottom_toolbar
22 | Controls the color of the bottom toolbar. Defaults to *#000000*
23 | ### Cli.prompt_toolbar_version
24 | Controls the color of the version in the toolbar. Defaults to *#00ff48*
25 | ### Cli.prompt_toolbar_states
26 | Controls the color of the states in the toolbar. Defaults to *#60cdd5*
27 | ### Cli.prompt_toolbar_buffers
28 | Controls the color of the buffers in the toolbar. Defaults to *#ff00ff*
29 | ### Cli.prompt_toolbar_type
30 | Controls the color of the current state type in the toolbar. Defaults to *#ffd700*
31 | ### Cli.prompt_toolbar_errors
32 | Controls the color of the errors in the toolbar. Defaults to *#ff0000*
33 | ### Cli.prompt_cli_method
34 | Controls the color of the cli methods. Defaults to *#00d700*
35 | ### Cli.prompt_plugin_method
36 | Controls the color of the plugin methods. Defaults to *#30d8ff*
37 | ### Cli.cli_info_color
38 | Controls the color of the output from `cli_*` methods. Defaults to *#ffb4ad*
39 | ### Cli.prompt_search_background
40 | Background background color for cli selection. Defaults to *#00aaaa #000000*
41 | ### Cli.prompt_search_fuzzy
42 | Background background color for cli fuzzy match. Defaults to *#00aaaa*
43 |
44 |
45 | ### chepy_history
46 | This file saves the history of all the commands in that have been run in the chepy cli.
47 |
48 | ### Valid chepy.conf file contents
49 | ```
50 | [Plugins]
51 | enableplugins = false
52 | pluginpath = /path/to/chepy_install/chepy/chepy/chepy_plugins
53 |
54 | [Cli]
55 | history_path = /path/to/home/.chepy/chepy_history
56 | prompt_char = >
57 | prompt_colors = #00ffff #ff0000 #ffd700
58 | show_rprompt = false
59 | prompt_rprompt = #00ff48
60 | prompt_bottom_toolbar = #000000
61 | prompt_toolbar_version = #00ff48
62 | prompt_toolbar_states = #60cdd5
63 | prompt_toolbar_buffers = #ff00ff
64 | prompt_toolbar_type = #ffd700
65 | prompt_toolbar_errors = #ff0000
66 | ```
67 |
--------------------------------------------------------------------------------
/docs/core.md:
--------------------------------------------------------------------------------
1 | # ChepyCore class
2 |
3 | The `ChepyCore` class for Chepy is primarily used as an interface for all the current modules/classes in Chepy, or for plugin development. The `ChepyCore` class is what provides the various attributes like **states**, **buffers**, etc and is required to use and extend Chepy.
4 |
5 | The most important `ChepyCore` attributes and methods are:
6 | - **state** The state is where all objects are always stored when modified by any methods.
7 | - **\_convert_to_*** methods These are helper methods that ensures data is being accessed and put in the state in the correct manner. For example, `binasii.unhexlify` requires a bytes like object. We can use
8 | ```
9 | self.state = binasii.unhexlify(self._convert_to_bytes())
10 | ```
11 | This will ensure that the correct data type is being used at all times.
12 |
13 | ```eval_rst
14 | .. automodule:: chepy.core
15 | :members:
16 | :undoc-members:
17 | :private-members:
18 | ```
19 |
--------------------------------------------------------------------------------
/docs/extras.rst:
--------------------------------------------------------------------------------
1 | Extras
2 | ======
3 |
4 | Bruteforce
5 | """"""""""
6 | .. automodule:: chepy.extras.bruteforce
7 | :members:
8 |
9 | Combinations
10 | """"""""""""
11 | .. automodule:: chepy.extras.combinatons
12 | :members:
13 |
14 | Crypto
15 | """"""
16 | .. automodule:: chepy.extras.crypto_extras
17 | :members:
18 |
19 | Misc
20 | """"
21 | .. automodule:: chepy.extras.misc
22 | :members:
--------------------------------------------------------------------------------
/docs/faq.md:
--------------------------------------------------------------------------------
1 | # FAQ
2 |
3 | ## Chepy is failing to load due to a config issue.
4 | Chepy is in constant development, and in future versions, it is quite possible that new options are included for the chepy.conf file. If you are facing an issue with config keys failing to load, delete the `$HOME/.chepy/chepy.conf` file. On next load, Chepy will set a valid working conf file.
5 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ../README.md
--------------------------------------------------------------------------------
/docs/internal.rst:
--------------------------------------------------------------------------------
1 | Chepy Internal
2 | ==============
3 |
4 | Colors
5 | """"""
6 | .. automodule:: chepy.modules.internal.colors
7 | :members:
8 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/modules.rst:
--------------------------------------------------------------------------------
1 | Modules
2 | =======
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Contents:
7 |
8 | modules/aritmeticlogic.rst
9 | modules/codetidy.rst
10 | modules/compression.rst
11 | modules/dataformat.rst
12 | modules/datetimemodule.rst
13 | modules/encryptionencoding.rst
14 | modules/extractors.rst
15 | modules/hashing.rst
16 | modules/language.rst
17 | modules/links.rst
18 | modules/multimedia.rst
19 | modules/networking.rst
20 | modules/other.rst
21 | modules/publickey.rst
22 | modules/utils.rst
23 | internal.rst
24 |
25 |
26 | Exceptions
27 | """"""""""
28 | .. automodule:: chepy.modules.exceptions
29 | :members:
30 |
--------------------------------------------------------------------------------
/docs/modules/aritmeticlogic.rst:
--------------------------------------------------------------------------------
1 | AritmeticLogic
2 | """"""""""""""
3 | .. autoclass:: chepy.modules.aritmeticlogic.AritmeticLogic
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/codetidy.rst:
--------------------------------------------------------------------------------
1 | CodeTidy
2 | """"""""
3 | .. autoclass:: chepy.modules.codetidy.CodeTidy
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/compression.rst:
--------------------------------------------------------------------------------
1 | Compression
2 | """""""""""
3 | .. autoclass:: chepy.modules.compression.Compression
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/dataformat.rst:
--------------------------------------------------------------------------------
1 | DataFormat
2 | """"""""""
3 | .. autoclass:: chepy.modules.dataformat.DataFormat
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/datetimemodule.rst:
--------------------------------------------------------------------------------
1 | DateTime
2 | """"""""
3 | .. autoclass:: chepy.modules.datetimemodule.DateTime
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/encryptionencoding.rst:
--------------------------------------------------------------------------------
1 |
2 | EncryptionEncoding
3 | """"""""""""""""""
4 | .. autoclass:: chepy.modules.encryptionencoding.EncryptionEncoding
5 | :members:
--------------------------------------------------------------------------------
/docs/modules/extractors.rst:
--------------------------------------------------------------------------------
1 | Extractors
2 | """"""""""
3 | .. autoclass:: chepy.modules.extractors.Extractors
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/hashing.rst:
--------------------------------------------------------------------------------
1 | Hashing
2 | """""""
3 | .. autoclass:: chepy.modules.hashing.Hashing
4 | :members:
5 |
--------------------------------------------------------------------------------
/docs/modules/language.rst:
--------------------------------------------------------------------------------
1 | Language
2 | """"""""
3 | .. autoclass:: chepy.modules.language.Language
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/links.rst:
--------------------------------------------------------------------------------
1 | Links
2 | """"""""""""""
3 | .. autoclass:: chepy.modules.links.Links
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/multimedia.rst:
--------------------------------------------------------------------------------
1 | Multimedia
2 | """"""""""
3 | .. autoclass:: chepy.modules.multimedia.Multimedia
4 | :members:
--------------------------------------------------------------------------------
/docs/modules/networking.rst:
--------------------------------------------------------------------------------
1 |
2 | Networking
3 | """"""""""
4 | .. autoclass:: chepy.modules.networking.Networking
5 | :members:
6 |
--------------------------------------------------------------------------------
/docs/modules/other.rst:
--------------------------------------------------------------------------------
1 |
2 | Other
3 | """""
4 | .. autoclass:: chepy.modules.other.Other
5 | :members:
6 |
--------------------------------------------------------------------------------
/docs/modules/publickey.rst:
--------------------------------------------------------------------------------
1 |
2 | Publickey
3 | """""""""
4 | .. autoclass:: chepy.modules.publickey.Publickey
5 | :members:
6 |
--------------------------------------------------------------------------------
/docs/modules/utils.rst:
--------------------------------------------------------------------------------
1 |
2 | Utils
3 | """""
4 | .. autoclass:: chepy.modules.utils.Utils
5 | :members:
--------------------------------------------------------------------------------
/docs/plugins.md:
--------------------------------------------------------------------------------
1 | # Chepy Plugins
2 |
3 | Chepy allows users to extend Chepy and add plugins to it. This documentation describes how to create or load plugins in Chepy. For current official Chepy plugins, [refer to this docs](https://chepy-plugins.readthedocs.io/en/latest/), or [this repo](https://github.com/securisec/chepy_plugins). These plugins are disabled by default, but can be enabled using the config file. If an import requirement fails for any of the built in plugins, it will show a message showing which one failed.
4 |
5 | To use the existing plugin path directory, use `cli_plugin_path` from the cli to identify the plugin path, or refer to the chepy.conf file.
6 |
7 | ## chepy.conf file
8 | The chepy.conf file is what controls various aspects of how chepy runs. This file can be located in the users home directory. Plugins can be enabled or disabled with `Plugins.enableplugins` in the **chepy.conf** file.
9 |
10 | The default Chepy conf file on setup looks like this:
11 |
12 | ```bash
13 | [Plugins]
14 | enableplugins = true
15 | pluginpath = None
16 | # this needs to be an absolute path. Plugins are loaded from this directory
17 |
18 | [Cli]
19 | historypath = /home/hapsida/.chepy/chepy_history
20 | # controls where the Chepy cli history is saved. This path will be set to
21 | # the users home dir automatically on setup.
22 | ```
23 |
24 | ## Plugins folder location
25 | The location of the plugins folder can be found in the `chepy.conf` file. To use custom plugins, set the value of `pluginpath` in this file.
26 |
27 | ```bash
28 | [Plugin]
29 | pluginpath = /some/dir/
30 | ```
31 |
32 | Chepy will attempt to read the plugins folder (if one is set) to resolve any plugins from it.
33 |
34 | ## Creating plugins
35 | ### Naming plugins
36 | Because Chepy utilizes name spaces to load its plugins, all plugin files needs to be named as **chepy_some_plugin.py**. This ensures that there are no namespace conflicts.
37 |
38 | Plugin files should be placed in the directory that is specified by the `pluginpath` in chepy.conf
39 | https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html
40 | ### Plugin module
41 | All Chepy plugins have to follow a specific format for best results.
42 |
43 | - ChepyCore needs to be inherited in the plugin class
44 | - Methods must have [google style docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html).
45 | - Methods should preferably be prefixed with something that distinguishes them. For example `myplugin_somemethod`. This avoids namespace conflicts.
46 |
47 | ### Sample plugin
48 | 
49 | [Asciinema](https://asciinema.org/a/apIR9AWO3EZpHrfKYfagVZk06)
50 |
51 | This is a bare bones example of how a Chepy plugin works. In this case, `myplugin_method` will be available in both Chepy cli (with auto completion) and the Chepy library.
52 |
53 | The only thing this plugin at the moment will do is take whatever value is in the state, and multiply it with 20. All methods in Chepy plugins should set the value of `self.state` and should return `self`. This allows chaining with other methods that are available.
54 |
55 | ```python
56 | import chepy.core
57 |
58 | class MyPlugin(chepy.core.ChepyCore):
59 |
60 | @chepy.core.ChepyDecorators.call_stack
61 | def myplugin_method(self):
62 | """another method
63 |
64 | Returns:
65 | ChepyPlugin: The chepy object
66 | """
67 | self.state = self.state * 20
68 | return self
69 | ```
70 |
71 | Lets breakdown this sample plugin.
72 |
73 | #### Importing ChepyCore
74 |
75 | ```python
76 | import chepy.core
77 |
78 | class MyPlugin(chepy.core.ChepyCore):
79 |
80 | @chepy.core.ChepyDecorators.call_stack
81 | def myplugin_method(self):
82 | ```
83 | All Chepy plugins needs to inherit the **ChepyCore** class. This ensures that all the core attributes and methods from ChepyCore are available to the plugin.
84 |
85 | The **ChepyDecorators** class offers stack methods to decorate plugin methods with. In this example, the `call_stack` decorator is being applied to the `myplugin_method` method. Although using the decorator is not required, it is recommended. This decorator ensures that that external plugins are also able to use the recipe feature.
86 |
87 | #### Docstrings
88 | ```python
89 | """another method
90 |
91 | Returns:
92 | Chepy: The chepy object
93 | """
94 | ```
95 |
96 | This is an example of Google style docstrings in python. Chepy cli parses these doc strings to show the help message and command completion dynamically. Although this can be omitted, it is strong recommended to have them to leverage the best capabilities of Chepy. The return type of `ChepyPlugin` is important for both autocompletion, and also highlighting the method as a plugin method.
97 |
98 | #### Method body
99 | This could be any code that the method is trying to accomplish
100 |
101 | #### Returns
102 | ```python
103 | self.state = self.state * 20
104 | return self
105 | ```
106 | ```eval_rst
107 | .. important::
108 | These two lines are very important. Both Chepy cli and library allows the user to chain various methods with each other.
109 | ```
110 |
111 | - `self.state = ...` This line ensures that the value being produced by the method can be accessed by other methods in Chepy.
112 | - `return self` This line ensures that methods can be changed together. Example,
113 |
114 | In the example gif and asciinema, we can see how we first load the hello string to chepy, then call our myplugin_method, and then modify the output with to_hex followed by base64_encode.
115 |
116 | #### Using plugins in script
117 | As all plugins found in the directory is loaded automatically by Chepy at init, using plugins in script is super simple.
118 |
119 | This code is equivalent to what is happening in the gif and asciinema.
120 |
121 | ```python
122 | from chepy import Chepy
123 |
124 | c = Chepy("hello").myplugin_method().to_hex().base64_encode()
125 | print(c)
126 | ```
127 |
128 | ```eval_rst
129 | .. tip::
130 | If you do create a plugin that is helpful, feel free to share it, or make a pull request!
131 | ```
132 |
--------------------------------------------------------------------------------
/docs/pullrequest.md:
--------------------------------------------------------------------------------
1 | # Pull requests
2 |
3 | Pull requests for Chepy are very welcome, but the following guidelines needs to be followed.
4 |
5 | ## Code Style
6 | Chepy uses [python black](https://github.com/psf/black) for its code style and formatting. All pull requests should have proper formatting applied.
7 |
8 | ## Commit messages
9 | Commit messages should always have proper flair indicating the changes. The first line of the commit message should include the emojis of what was changed followed by multiline description of what was added.
10 |
11 | ### Example commit message
12 | ```
13 | ✅🔅ℹ️🧨📚
14 |
15 | 🔅 added new ability
16 | 🧨 refactored something
17 | ℹ️ updated something
18 | ℹ️ fixed something
19 | ✅ added a new method
20 | ✅ added another new method
21 | 📚 added new docs
22 | ```
23 |
24 | ### The current flairs in use are:
25 |
26 | - 🔅 A new feature has been added. This could be tests files, new arguments etc.
27 | - ℹ️ An update has been made to an existing feature
28 | - 🧨 A major refactor has taken place. This could be anything in the Cli or ChepyCore classes.
29 | - 🐍 A new python dependency has been added
30 | - ✅ New method has been added
31 | - 📚 Added new documentation
32 |
33 | ## Tests
34 | Chepy maintains a 100% Codecov coverage, and all pull requests are required to submit complimentary tests. The tests should include all paths, including coverage for optional arguments, if loops etc. Failing the 100% coverage will automatically fail the configured Github Actions.
35 |
36 | Tests requires the following dev dependencies:
37 | - pytest
38 | - pytest-cov
39 | - sphinx
40 | - recommonmark
41 | - bandit
42 |
43 | To run tests for coverage and pytest, use:
44 | ```bash
45 | pytest --disable-pytest-warnings --cov-report=xml --cov=chepy --cov-config=.coveragerc tests/
46 | ```
47 |
48 | For bandit tests, use:
49 | ```bash
50 | bandit --recursive chepy/ --ignore-nosec --skip B101,B413,B303,B310,B112,B304,B320,B410
51 | ```
52 |
53 | Finally for docs tests, use:
54 | ```bash
55 | make -C docs/ clean html
56 | ```
57 |
58 | The most convenient way to run all the tests are via the handy `all_tests.sh` from the root directory.
59 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | recommonmark
2 | sphinx==5.0
3 | docutils==0.16
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/logo.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | base58
2 | colorama
3 | crccheck
4 | decorator
5 | docstring-parser
6 | emoji==2.0.0
7 | exrex
8 | fire==0.6.0
9 | hexdump
10 | jmespath==1.0.1
11 | jsonpickle
12 | lazy-import
13 | lz4==4.3.2
14 | msgpack==1.0.4
15 | parsel==1.9.1
16 | passlib==1.7.4
17 | PGPy==0.6.0
18 | pretty-errors==1.2.25
19 | prompt_toolkit>=2.0.8
20 | pycipher
21 | pycryptodome
22 | pydash
23 | pyjwt==1.7.1
24 | pyOpenSSL==23.2.0
25 | pyperclip
26 | PyYAML
27 | regex
28 | setuptools
29 | typing_extensions
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | description-file = README.md
3 |
4 | [tool:pytest]
5 | testpaths = tests tests_plugins
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=undefined-variable
2 | from setuptools import setup, find_packages
3 | from os import path
4 |
5 | # get version and author information
6 | with open("chepy/__version__.py", "r") as f:
7 | exec(f.read())
8 |
9 |
10 | def read_requirements():
11 | with open("requirements.txt") as f:
12 | return f.read().splitlines()
13 |
14 |
15 | requirements = read_requirements()
16 | # if sys.platform == "linux":
17 | # requirements.append("python-magic")
18 | # else:
19 | # requirements.append("python-magic-bin==0.4.14")
20 |
21 | this_directory = path.abspath(path.dirname(__file__))
22 | with open(path.join(this_directory, "README.md"), "r", encoding='utf8') as f:
23 | long_description = f.read()
24 |
25 | core_extra_deps = ["requests"]
26 |
27 | plugin_deps = [
28 | "scapy",
29 | "Markdown",
30 | "chepy",
31 | "pefile",
32 | "pyelftools",
33 | "ua-parser==0.8.0",
34 | "pydriller",
35 | "pyexiftool",
36 | ]
37 |
38 | setup(
39 | long_description=long_description,
40 | long_description_content_type="text/markdown",
41 | name="chepy",
42 | license="GPL",
43 | version=__version__,
44 | author=__author__,
45 | url="https://github.com/securisec/chepy",
46 | project_urls={
47 | "Documentation": "https://chepy.readthedocs.io/en/latest/",
48 | "Source Code": "https://github.com/securisec/chepy",
49 | },
50 | extras_require={"extras": core_extra_deps + plugin_deps},
51 | packages=find_packages(exclude=(["tests", "docs"])),
52 | install_requires=requirements,
53 | classifiers=[
54 | "Programming Language :: Python :: 3.12",
55 | ],
56 | python_requires="<3.13",
57 | entry_points={"console_scripts": ["chepy = chepy.__main__:main"]},
58 | )
59 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/__init__.py
--------------------------------------------------------------------------------
/tests/files/elf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/elf
--------------------------------------------------------------------------------
/tests/files/encoding:
--------------------------------------------------------------------------------
1 | =0GDAqREMS0EEWHGOEHJWWRAZqGDHAyHDSxDWyHImRHEEcIGOAyZMqHDPyHFScIDUSyDASREMS0EYS0AWEyJMyRARyHDQWGGUSxJAqREEy1EIWHFOAIDXqHHP1HDRyIDUSyHQySFPImEGW0AOAHHWqHIPy0GHcIDSAyJAS0DEEmEGWHGOEHJOqHHP1HIOMwDVIREFySFESHEMcIGOAxZMqHDP5HFRSIDSIyHASREMS0EEWHGOExEEOSJn5HGSMwDSSxJBqREEEmEHWHFAExZOIHDX1HERyIDUSyDASREMyxD0DxJUE0DFOIDPyHFRAGDSEyJAS0DlR1EOWHFYIIJOqHHP1HDRyIDUgHD3ZSEP50E0DHFOASAAqHDF1HFRSIGUEyDWS0DPM0EEWHGOEHJOqHHFAHJLAyDVIyD3R0DEI1EKWHFEEyJOIHIn1HDQSIDVWyDASREMS0EEWHGISxAnyxHP9HJVSIDSqyDBS0HM10EOW0GUEHHOIxIX1HDRyIDUSyDASRETSSHFWyGUIxAPIHDX10ERSIJUEyDWqRElRHEOWIGQEHJOqHHP1HDRyIFPEQGFq0EQWSHOWHFYExZOIRIF5HDQWGHUSxDW1HEMS0EEWHGOEHJOq0FOqGIHcIHCEQEWS0HO50EOcIGUEHHEqRJPyHDGWxDUSyDASREMS0EEW1DMuSJP9RIQqGDQSIJWqyDWSRImRHEHcxGOAHHSuHHP1HDRyIDUSyDAIID24RHUAxIMuHHOI0Dl4HDQAGHUSxDBgREESHEKWHGOEHJOqHHP1HDRMHHDE0FmHRF2VHEOcIGWEHHEy0IPyHEHAGDSSxJASREMS0EEWHGOEHJWWRAmZGFLcxHDSxDW1HEmRHEIcyGOAyJIqHDPyHDRyIDUSyDASREMS0E
--------------------------------------------------------------------------------
/tests/files/fake_secrets.txt:
--------------------------------------------------------------------------------
1 | google_api 'AIzalYn6W299E9kH-aHZSB3aKTYAgHxXwfzZg4q'
2 | google_captcha '6Lrjv_b_jgnybWRwKSn2P6lop58PGZ_NfewZWnRT'
3 | google_oauth 'ya29.L1dpWwGJlKJSxV'
4 | amazon_aws_access_key_id 'AKIAFKOE7IY2PL5ETITY'
5 | amazon_mws_auth_toke 'amzn.mws.f90f3ce6-9b5a-26a7-9a87-4ff8052be2ec'
6 | amazon_aws_url 'uknEsH.s3.amazonawsscom'
7 | facebook_access_token 'EAACEdEose0cBAlAQcZw0'
8 | authorization_basic 'Basic YWRtaW46cGFzcw=='
9 | authorization_bearer 'Bearer AbCdEf123456'
10 | authorization_api 'api\ry\r\t|\x0c\x0c\nyy\t\t e\x0b *wV'
11 | mailgun_api_key 'key-LPxoYCANGEFkAMHBur4jTjbZ69ngpdbI'
12 | twilio_api_key 'SK5d1d319A6Acf7EC9BDeDb8CCe4D76BA8'
13 | twilio_account_sid 'ACXvJ0lkU-BhvkmBkZPUWAxExvPSF6s5En'
14 | twilio_app_sid 'APNLX3uzXotXDUKvurSeS95o8O3RpYuuy6'
15 | paypal_braintree_access_token 'access_token$production$x0lb8affpzmmnufd$3ea7cb281754b7da7eca131ef9642324'
16 | square_oauth_secret 'sq0csp-2WvLIfSstr6_FWefA3c p_oeTw0RtICeBsIlUTShsRo'
17 | square_access_token 'sqOatp-TDt6aBq8Z_Oup1JezKC1cK'
18 | stripe_standard_api 'sk_live_2ZNCghgpavpDMUO3EhdQAael'
19 | stripe_restricted_api 'rk_live_z59MoCJoFc114PpJlP1OnB1O'
20 | github_access_token 'XAmHSVQTebqE8dtcr-:AbSbAztZPEZu@github.commm'
21 | rsa_private_key '-----BEGIN RSA PRIVATE KEY-----'
22 | ssh_dsa_private_key '-----BEGIN DSA PRIVATE KEY-----'
23 | ssh_dc_private_key '-----BEGIN EC PRIVATE KEY-----'
24 | pgp_private_block '-----BEGIN PGP PRIVATE KEY BLOCK-----'
25 | json_web_token 'eyj6be8n6rBOO4Z.0g4Jh3nPB0V4a'
--------------------------------------------------------------------------------
/tests/files/ff.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/ff.exe
--------------------------------------------------------------------------------
/tests/files/flags:
--------------------------------------------------------------------------------
1 | picoCTF{r3source_pag3_f1ag}
2 | xoxb-808882645436-350102357778-949755564313-1v9kucs6pv4o208oj4zh9sxqt76a5859
3 | -----BEGIN RSA PRIVATE KEY-----
4 | https://hooks.slack.com/services/TcVcxBEKs/BA0jbQKMR/z3VwrVaDmA9SHtThW4CF5x2C
5 | SKombv8u2t28ved9jt3xiyelsrbcij86mq
6 | AKIAIYVSTL2JD4XQORJ8
7 |
--------------------------------------------------------------------------------
/tests/files/hello:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/hello
--------------------------------------------------------------------------------
/tests/files/keyboard.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/keyboard.pcap
--------------------------------------------------------------------------------
/tests/files/lsb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/lsb.png
--------------------------------------------------------------------------------
/tests/files/msb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/msb.png
--------------------------------------------------------------------------------
/tests/files/pbuf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/pbuf
--------------------------------------------------------------------------------
/tests/files/pkcs12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/pkcs12
--------------------------------------------------------------------------------
/tests/files/private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICWwIBAAKBgQDDhjb/e1alLSQk+2UmXjuYmJ1CuYHRWkfmKdf5MhNell2PhrTM
3 | tT4ljNb7PTi+n8WcwihAxHVNfKvgSQt6q/yuVPj5t51159XJHov+ySANFsTUxsUw
4 | YzHUJ5yeeHbbcWgNwehHMPGSdDuZ/XnXH3VIk50FIRNjzrrMpHuQso58ewIDAQAB
5 | AoGAczd000n//efC49QMf/aJkdtk2Dvuhsp3kebYcO0UQunCimArzHGFBKWgzX3/
6 | IT2POlejVr8uDJJJyinhDNGqXJw9ZEs33f89B7JBGjViS83d9qWypHOg2/OfAt6S
7 | LNICmpPSmKSSJtenFx7XjV0LdG/+b8rENpNy+8TafThnYekCQQDv8oRfMnur8lLq
8 | oG2Fg8RJvq6OA8UOcE4Duo0uPba0uec48kfhBvLsCVhW/vDBDU14o5nUoFKn1sBa
9 | 7jU7Mb0fAkEA0JrhtcBNgUd93tp0jSC6T/qNUOVcJjFZWjamB/X4fPesiNw/azV5
10 | OaGpn9wp7swX56DCcLdIR57T9oRw5DX5JQJAWH4Oh7VsmuuR3Ooxui3wdGoYolON
11 | l1efzgw9CTLFcT2mov/ntnwDlz2TEPKRBAHN8pITp7FBCplO87oqc5xSbQJAfpT9
12 | UaSXY1NWddxpzRmG9PE8v1HuUN6xMaTnqvz/BBXmhEXh1dRk8yu+GlsmttjxyIQs
13 | eOk+2vbt+DD1sAVwYQJAF3kq/lbmROIyAOekpXYFCIWU11mHfxSVuxmYjUYLVRGZ
14 | bmwesS2DFBX5scKK27uMng7nBB9QukZ5kitK4cKelA==
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/tests/files/public.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDhjb/e1alLSQk+2UmXjuYmJ1C
3 | uYHRWkfmKdf5MhNell2PhrTMtT4ljNb7PTi+n8WcwihAxHVNfKvgSQt6q/yuVPj5
4 | t51159XJHov+ySANFsTUxsUwYzHUJ5yeeHbbcWgNwehHMPGSdDuZ/XnXH3VIk50F
5 | IRNjzrrMpHuQso58ewIDAQAB
6 | -----END PUBLIC KEY-----
7 |
--------------------------------------------------------------------------------
/tests/files/qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/qr.png
--------------------------------------------------------------------------------
/tests/files/qr/aztec.qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/qr/aztec.qr.png
--------------------------------------------------------------------------------
/tests/files/qr/basic.qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/qr/basic.qr.png
--------------------------------------------------------------------------------
/tests/files/script.py:
--------------------------------------------------------------------------------
1 | def cpy_script(s):
2 | return s * 2
--------------------------------------------------------------------------------
/tests/files/test.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/test.db
--------------------------------------------------------------------------------
/tests/files/test.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/test.der
--------------------------------------------------------------------------------
/tests/files/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Example Domain
5 |
6 |
7 |
8 |
9 |
36 |
37 |
38 |
39 |
40 |
Example Domain
41 |
This domain is for use in illustrative examples in documents. You may use this
42 | domain in literature without prior coordination or asking for permission.
43 |
More information...
44 |
45 |
46 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/tests/files/test.js:
--------------------------------------------------------------------------------
1 | // comment
2 |
3 | function namedFunction(argument1, argument2) {
4 | return
5 | }
6 |
7 | var es6function = (vars) => {
8 | /* some
9 | * comment
10 | */
11 | }
12 |
13 | /**
14 | * another multline
15 | * comment
16 | */
--------------------------------------------------------------------------------
/tests/files/test.pcapng:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/test.pcapng
--------------------------------------------------------------------------------
/tests/files/test.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANS+nHld7b5B7TBy
3 | ObzsK/nI1vx9MiDYfT2B8vgkvTJq19dqXv5tRS2qTFLuR4EGQCq7ZXXHG91ohkDa
4 | a7P1nHtYPIZrw9KQF334o0Pr47x1VN5frqdaHC+iD6ca0Fc9G86UOLDEStAnWYI3
5 | +MuBy9fPKjDYGBjmQYLbRV8aM+NVAgMBAAECgYAl5v/Br7ZXmy9C3lbjDcCX8+w5
6 | d6SirW9CshAznXgHr3lc65qZAaa9iAWpEMK0fgSYmGJvJVYVkDW7AC8IFM4X6GQm
7 | UffWlbZiYCng/iYF4f6oM1YwFHnP+WiM/Q9HtjFGyd9vl4n3bzlalH0s1NeTN1hS
8 | aWkFnVKVkIslpFrSgQJBAPAH8AqhXfWYLtuWSLFYko0lxQ7Av90bZ6VeSjmYVSpq
9 | d8OgJR9Gfd2qW43wt893YeG1nqQhD2ZAw8KTGJ9ywMkCQQDi5fKYQFl4RcZrRlAJ
10 | A5Osn3vZQJ6M1eKqVG9C//M4HpfoZt/cPAjEn8OFdypd89AFO4bZ/vOcaey4YoHG
11 | yAAtAkEA0tvmPzBqvikmYLiwuzq3407ewYsKAU7lyhv+0IHFrzFAbJXuhn8CawwQ
12 | yaxBjPuu/Pzzk/OG96jFT9SwuMGyIQJABDFRkUSnIpTPfM34zqHVSbxMspACHgIZ
13 | xSH4SFmoaeIO1omIG260jsWQ/FdeXgwSTPZzoHWYlMxURnfzg/PQJQJBAOGzpygC
14 | Ku+m5Ua+kOFZ03GYjK5eXjNDdrpfdsfEsp6CBXtWH4JacDiXZSKFoN/WjWuSxsTb
15 | z8I+Uc4jeVU4tzk=
16 | -----END PRIVATE KEY-----
17 | -----BEGIN CERTIFICATE-----
18 | MIICeTCCAeICCQDi5dgCpKMeHTANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMC
19 | VVMxDDAKBgNVBAgMA2xvbDEMMAoGA1UEBwwDbnljMRIwEAYDVQQKDAlzZWN1cmlz
20 | ZWMxDjAMBgNVBAsMBWNvZGVyMRIwEAYDVQQDDAlzZWN1cmlzZWMxHTAbBgkqhkiG
21 | 9w0BCQEWDm5vbmVAZW1haWwuY29tMB4XDTE5MTEwMjE1MjUwOFoXDTIwMTEwMTE1
22 | MjUwOFowgYAxCzAJBgNVBAYTAlVTMQwwCgYDVQQIDANsb2wxDDAKBgNVBAcMA255
23 | YzESMBAGA1UECgwJc2VjdXJpc2VjMQ4wDAYDVQQLDAVjb2RlcjESMBAGA1UEAwwJ
24 | c2VjdXJpc2VjMR0wGwYJKoZIhvcNAQkBFg5ub25lQGVtYWlsLmNvbTCBnzANBgkq
25 | hkiG9w0BAQEFAAOBjQAwgYkCgYEA1L6ceV3tvkHtMHI5vOwr+cjW/H0yINh9PYHy
26 | +CS9MmrX12pe/m1FLapMUu5HgQZAKrtldccb3WiGQNprs/Wce1g8hmvD0pAXffij
27 | Q+vjvHVU3l+up1ocL6IPpxrQVz0bzpQ4sMRK0CdZgjf4y4HL188qMNgYGOZBgttF
28 | Xxoz41UCAwEAATANBgkqhkiG9w0BAQsFAAOBgQChhviBdift0P/j00TYxnPPNS58
29 | wQSFm54UNQ/vjM12yZ+C5c3268Vo8jSP7mI5R3wn6XztjUSXkDg5/3IL3kojti/h
30 | nyhBHx2QCVke7BxWw3HWkbZ/1BKl0HnCGyd5HDTuOtlBmTS+QrJoNpdsn0zq4fvc
31 | igbV1IJdKTBAiZzaOQ==
32 | -----END CERTIFICATE-----
33 |
--------------------------------------------------------------------------------
/tests/files/test.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/test.tar.gz
--------------------------------------------------------------------------------
/tests/files/test.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/files/test.zip
--------------------------------------------------------------------------------
/tests/files/vuln_code:
--------------------------------------------------------------------------------
1 | {"body":"r\"\"\"\nDjango settings for tag project.\nGenerated by 'django-admin startproject' using Django 1.9.7.\nFor more information on this file, see\nhttps:\/\/docs.djangoproject.com\/en\/1.9\/topics\/settings\/\nFor the full list of settings and their values, see\nhttps:\/\/docs.djangoproject.com\/en\/1.9\/ref\/settings\/\n\"\"\"\n\nimport os\nimport environ\n\nenv = environ.Env()\n\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n# Quick-start development settings - unsuitable for production\n# See https:\/\/docs.djangoproject.com\/en\/1.9\/howto\/deployment\/checklist\/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = env('DJANGO_SECRET_KEY', default='osx*hq-(zkj=&&o!d%u&e-=^1%6y0gvsu9d)-#39k$i1(1+5&$')\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = env.bool('DJANGO_DEBUG', default=True)\n\nALLOWED_HOSTS = ['*']\n\nLOGIN_REDIRECT_URL = '\/profile'\n\n# Application definition\n\nINSTALLED_APPS = [\n 'django.contrib.admin',\n 'django.contrib.auth',\n 'django.contrib.contenttypes',\n 'django.contrib.sessions',\n 'django.contrib.messages',\n 'django.contrib.staticfiles',\n 'debug_toolbar',\n 'tags',\n 'crispy_forms',\n 'storages'\n\n]\nCRISPY_TEMPLATE_PACK = 'bootstrap3'\n\nMIDDLEWARE_CLASSES = [\n 'django.middleware.security.SecurityMiddleware',\n 'django.contrib.sessions.middleware.SessionMiddleware',\n 'django.middleware.common.CommonMiddleware',\n 'django.middleware.csrf.CsrfViewMiddleware',\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\n 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',\n 'django.contrib.messages.middleware.MessageMiddleware',\n 'django.middleware.clickjacking.XFrameOptionsMiddleware',\n 'debug_toolbar.middleware.DebugToolbarMiddleware',\n]\n\nROOT_URLCONF = 'tag.urls'\n\nTEMPLATES = [\n {\n 'BACKEND': 'django.template.backends.django.DjangoTemplates',\n 'DIRS': ['templates'],\n 'APP_DIRS': True,\n 'OPTIONS': {\n 'context_processors': [\n 'django.template.context_processors.debug',\n 'django.template.context_processors.request',\n 'django.contrib.auth.context_processors.auth',\n 'django.contrib.messages.context_processors.messages',\n ],\n },\n },\n]\n\nWSGI_APPLICATION = 'tag.wsgi.application'\n\n\n# Database\n# https:\/\/docs.djangoproject.com\/en\/1.9\/ref\/settings\/#databases\n\n\nDATABASES = {\n 'default': {\n 'ENGINE': 'django.db.backends.sqlite3',\n 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),\n }\n}\n\n# Password validation\n# https:\/\/docs.djangoproject.com\/en\/1.9\/ref\/settings\/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n {\n 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',\n },\n {\n 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',\n },\n {\n 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',\n },\n {\n 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',\n },\n]\n\n\n# Internationalization\n# https:\/\/docs.djangoproject.com\/en\/1.9\/topics\/i18n\/\n\nLANGUAGE_CODE = 'en-us'\n\nTIME_ZONE = 'UTC'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https:\/\/docs.djangoproject.com\/en\/1.9\/howto\/static-files\/\n\nPROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))\n\nSTATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')\nSTATIC_URL = '\/static\/'\n\n# Extra places for collectstatic to find static files.\nSTATICFILES_DIRS = (\n os.path.join(PROJECT_ROOT, 'static'),\n)\nMEDIA_ROOT = os.path.join(BASE_DIR, 'tags\/images')\n# MEDIA_ROOT = \"\/Users\/adamsiwiec\/Desktop\/Tag\/tag\/tags\/images\/\"\n# MEDIA_URL = \"\/images\/\"\n\n# Update database configuration with $DATABASE_URL.\nimport dj_database_url\ndb_from_env = dj_database_url.config(conn_max_age=500)\nDATABASES['default'].update(db_from_env)\n\n\n# Simplified static file serving.\n# https:\/\/warehouse.python.org\/project\/whitenoise\/\n\n# STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'\n\nAWS_HEADERS = { # see http:\/\/developer.yahoo.com\/performance\/rules.html#expires\n 'Expires': 'Thu, 31 Dec 2099 20:00:00 GMT',\n 'Cache-Control': 'max-age=94608000',\n }\n\nAWS_STORAGE_BUCKET_NAME = env('S3_BUCKET', default='tagyourit')\nAWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID', default='AKIAIDO23IONYN4UVTDQ')\nAWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY', default='NXekk3ZVc55rQ06RkEXhmUWNvPw5X\/AZt5FrdNXr')\n\n# Tell django-storages that when coming up with the URL for an item in S3 storage, keep\n# it simple - just use this domain plus the path. (If this isn't set, things get complicated).\n# This controls how the `static` template tag from `staticfiles` gets expanded, if you're using it.\n# We also use it in the next setting.\nAWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME\n\n# This is used by the `static` template tag from `static`, if you're using that. Or if anything else\n# refers directly to STATIC_URL. So it's safest to always set it.\nSTATIC_URL = \"https:\/\/%s\/\" % AWS_S3_CUSTOM_DOMAIN\n\n# Tell the staticfiles app to use S3Boto storage when writing the collected static files (when\n# you run `collectstatic`).\n# STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'\n\nSTATICFILES_LOCATION = 'static'\nMEDIAFILES_LOCATION = 'media'\nimport tag.custom_storages\nSTATICFILES_STORAGE = 'tag.custom_storages.StaticStorage'\nSTATIC_URL = \"https:\/\/%s\/%s\/\" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)\n\n\nMEDIA_URL = \"https:\/\/%s\/%s\/\" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)\nDEFAULT_FILE_STORAGE = 'tag.custom_storages.MediaStorage'\n\n\nBROKER_URL = os.getenv('REDIS_URL', 'redis:\/\/localhost:6379')\nCELERY_RESULT_BACKEND = os.getenv('REDIS_URL', 'redis:\/\/localhost:6379')\nCELERY_ACCEPT_CONTENT = ['json']\nCELERY_TASK_SERIALIZER = 'json'\nCELERY_RESULT_SERIALIZER = 'json'\nCELERY_TIMEZONE = 'UTC'\n","status":200,"headers":["Content-Security-Policy","Strict-Transport-Security","X-Content-Type-Options","X-Frame-Options","X-XSS-Protection","ETag","Content-Type","Cache-Control","X-Geo-Block-List","X-GitHub-Request-Id","Content-Encoding","Content-Length","Accept-Ranges","Date","Via","Connection","X-Served-By","X-Cache","X-Cache-Hits","X-Timer","Vary","Access-Control-Allow-Origin","X-Fastly-Request-ID","Expires","Source-Age"]}
--------------------------------------------------------------------------------
/tests/files/wordlist.txt:
--------------------------------------------------------------------------------
1 | password
2 | secret
3 | super
--------------------------------------------------------------------------------
/tests/test_aritmeticlogic.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_add():
5 | assert Chepy("40").add(1).to_int().o == 51
6 | assert Chepy("hello").add("ff").o == b"gdkkn"
7 | assert Chepy(9).add("01").o == b":"
8 |
9 |
10 | def test_multiply():
11 | assert Chepy("0x40").multiply(2).o == 128
12 |
13 |
14 | def test_divide():
15 | assert Chepy("0x40").divide(2).o == 32
16 |
17 |
18 | def test_divide_float():
19 | assert Chepy("179").divide(178).to_hex().o == b"17b8803f"
20 |
21 |
22 | def test_power():
23 | assert Chepy("0x02").power(2).o == 4
24 |
25 |
26 | def test_sum():
27 | assert Chepy(["0x40", 10]).sum().o == 74
28 |
29 |
30 | def test_mean():
31 | assert Chepy(["0x40", 10]).mean().o == 37
32 |
33 |
34 | def test_median():
35 | assert Chepy(["0x40", 10, 20]).median().o == 20
36 |
37 |
38 | def test_sub():
39 | assert Chepy("40").sub(1).o == b"3/"
40 | assert Chepy("hello").sub("10").o == b"XU\\\\_"
41 | assert Chepy("hello").sub(10).o == b"^[bbe"
42 | # assert Chepy(9).add('01').o == b':'
43 |
44 |
45 | def test_subtract():
46 | assert Chepy("10 9 x").subtract().o == 1
47 |
48 |
49 | def test_addition():
50 | assert Chepy("10 9 x").addition().o == 19
51 |
52 |
53 | def test_int_to_base():
54 | assert Chepy("067165").int_to_base(8).o == 28277
55 |
56 |
57 | def test_bitwise_operations():
58 | assert Chepy("A").bit_shift_right(3).o == b"\x08"
59 | assert Chepy(b"414243").bit_shift_right().o == b"\x1a\x18\x1a\x19\x1a\x19"
60 | assert Chepy("A").bit_shift_left().o == b"\x82"
61 | assert Chepy("414243").from_hex().bit_shift_left(7).o == b"\x80\x00\x80"
62 |
--------------------------------------------------------------------------------
/tests/test_cli.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import inspect
3 | import fire
4 | from docstring_parser import parse as _parse_doc
5 | from chepy import Chepy
6 | from chepy.modules.internal.cli import get_cli_options
7 |
8 | chepy = dir(Chepy)
9 |
10 |
11 | def test_options():
12 | options = dict()
13 | for method in chepy:
14 | try:
15 | attributes = getattr(Chepy, method)
16 | if not method.startswith("_") and not isinstance(attributes, property):
17 | args = inspect.getfullargspec(attributes).args
18 | parsed_doc = _parse_doc(attributes.__doc__)
19 | if len(args) == 1:
20 | options[method] = {
21 | "options": list(
22 | map(lambda d: {"flag": d, "meta": ""}, args[1:])
23 | ),
24 | "meta": parsed_doc.short_description,
25 | "returns": parsed_doc.returns.type_name,
26 | }
27 | else:
28 | options[method] = {
29 | "options": list(
30 | map(
31 | lambda d: {
32 | "flag": d[1],
33 | "meta": parsed_doc.params[d[0]].description,
34 | },
35 | enumerate(args[1:]),
36 | )
37 | ),
38 | "meta": parsed_doc.short_description,
39 | "returns": parsed_doc.returns.type_name,
40 | }
41 | except:
42 | print("Error in method", method)
43 | raise
44 | return options
45 |
46 |
47 | def test_cli_options():
48 | get_cli_options()
49 |
50 |
51 | def test_fire1():
52 | assert fire.Fire(Chepy, command=["A", "-", "to_hex"]).o == b"41"
53 |
54 |
55 | def test_fire2():
56 | assert (
57 | fire.Fire(Chepy, command=["abc", "-", "hmac_hash", "--digest", "md5"]).o
58 | == b"dd2701993d29fdd0b032c233cec63403"
59 | )
60 |
61 |
62 | def test_fire3():
63 | fire_obj = fire.Fire(Chepy, command=["abc", "-", "hmac_hash", "--digest", "md5"])
64 | assert type(fire_obj) == Chepy
65 |
--------------------------------------------------------------------------------
/tests/test_codetidy.py:
--------------------------------------------------------------------------------
1 | import string
2 | from chepy import Chepy
3 |
4 |
5 | def test_minify_json():
6 | assert len(Chepy("tests/files/test.json").load_file().minify_json().o) == 5648
7 |
8 |
9 | def test_beautify_json():
10 | assert (
11 | len(Chepy("tests/files/test.json").load_file().minify_json().beautify_json().o)
12 | > 6000
13 | )
14 |
15 |
16 | def test_to_uppercase():
17 | assert Chepy("some String").to_upper_case(by="word").o == b"Some String"
18 | assert Chepy("some String").to_upper_case(by="sentence").o == b"Some string"
19 | assert Chepy("some String").to_upper_case(by="all").o == b"SOME STRING"
20 |
21 |
22 | def test_to_snake_case():
23 | assert Chepy("helloWorld").to_snake_case().o == b"hello_world"
24 |
25 |
26 | def test_to_camel_case():
27 | assert Chepy("some Data_test").to_camel_case().o == b"someDataTest"
28 | assert (
29 | Chepy("some Data_test").to_camel_case(ignore_space=True).o == b"some DataTest"
30 | )
31 |
32 |
33 | def test_to_kebab_case():
34 | assert Chepy("Some data_test").to_kebab_case().o == b"some-data-test"
35 |
36 |
37 | def test_remove_whitespace():
38 | assert (
39 | Chepy("some long space\n\ttab space\flol").remove_whitespace().o
40 | == b"somelongspacetabspacelol"
41 | )
42 |
43 |
44 | def test_swap_case():
45 | assert Chepy("SoMe TeXt").swap_case().o == b"sOmE tExT"
46 |
47 |
48 | def test_lower_case():
49 | assert Chepy("HelLo WorLd").to_lower_case().o == b"hello world"
50 |
51 |
52 | def test_leet_speak():
53 | assert Chepy("somexValue").to_leetspeak().o == b"50m3%V@1u3"
54 | assert Chepy("somexValue").to_leetspeak(False).o == b"50m3xVa1u3"
55 |
56 |
57 | def test_random_case():
58 | data = string.ascii_letters * 5
59 | assert Chepy(data).random_case().o != data
60 |
--------------------------------------------------------------------------------
/tests/test_compression.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 | import re
3 |
4 |
5 | def test_fix_zip_header():
6 | assert (
7 | Chepy(
8 | "4834434b1400000008003a9d7f502a0ae5b6230000002a00000008001c00666c61672e747874555409000340d5835e40d5835e75780b000104e803000004e8030000f3f109ae2e294a4ccf4c8ecf2bcd4d4a2d8acfcd2f4a8dcfc9cc4e8dcf4512aee50200504b01021e031400000008003a9d7f502a0ae5b6230000002a000000080018000000000001000000808100000000666c61672e747874555405000340d5835e75780b000104e803000004e8030000504b050600000000010001004e000000650000000000"
9 | )
10 | .from_hex()
11 | .fix_zip_header()
12 | .unzip_one("flag.txt")
13 | .trim()
14 | .o
15 | == b"LLS{tragic_number_more_like_magic_number}"
16 | )
17 |
18 |
19 | def test_zip_info():
20 | assert (
21 | Chepy("tests/files/test.zip")
22 | .read_file()
23 | .zip_info()
24 | .get_by_index(0)
25 | .get_by_key("encrypted")
26 | .o
27 | == True
28 | )
29 |
30 |
31 | def test_zip_extract_one():
32 | assert (
33 | Chepy("tests/files/test.zip").read_file().unzip_one("lol.txt", "password").o
34 | == b"lol\n"
35 | )
36 |
37 |
38 | def test_zip_list_files():
39 | assert len(Chepy("tests/files/test.zip").load_file().zip_list_files().o) == 2
40 |
41 |
42 | def test_zip_extract_all():
43 | assert (
44 | Chepy("tests/files/test.zip")
45 | .load_file()
46 | .unzip_all("password")
47 | .get_by_index(1)
48 | .o
49 | == b"StormCTF{Misc2:B73dba52ceDA4dDccb31Ec1b1cDa24Ff}"
50 | )
51 |
52 |
53 | def test_create_zip():
54 | assert (
55 | Chepy("A").to_hex().create_zip_file("some.txt").to_hex().slice(0, 8).o
56 | == b"504b0304"
57 | )
58 |
59 |
60 | def test_zip_compress():
61 | c = Chepy("some data").zip_compress("file").o
62 | assert c[:2] == b"PK"
63 | assert b"some data" in c
64 |
65 |
66 | def test_zip_compress_symlink():
67 | c = Chepy("some data").zip_compress_symlink("file", "target").o
68 | assert c[:2] == b"PK"
69 | assert b"target" in c
70 |
71 |
72 | def test_gzip_compress():
73 | assert Chepy("A").to_hex().gzip_compress().to_hex().slice(0, 6).o == b"1f8b08"
74 |
75 |
76 | def test_gzip_decompress():
77 | assert Chepy("A").to_hex().gzip_compress().gzip_decompress().o == b"41"
78 |
79 |
80 | def test_bzip():
81 | c = Chepy("some data").bzip_compress()
82 | assert (
83 | c.state
84 | == b'BZh91AY&SY\x9f\xe2\xaa\x9d\x00\x00\x03\x91\x80@\x00&\x02\x8c\x00 \x00"\x1ahz\x10\xc0\x86k\xef\n\x82\xeeH\xa7\n\x12\x13\xfcUS\xa0'
85 | )
86 | assert c.bzip_decompress().o == b"some data"
87 |
88 |
89 | def test_zlib_compress():
90 | assert (
91 | Chepy("some text").zlib_compress().to_hex().o
92 | == b"78da2bcecf4d552849ad28010011e8039a"
93 | )
94 |
95 |
96 | def test_zlib_decompress():
97 | assert (
98 | Chepy("789c0580a10d000008c35ee1b9ca05c104e737b761ca5711e8039a")
99 | .hex_to_bytes()
100 | .zlib_decompress()
101 | .o
102 | == b"some text"
103 | )
104 |
105 |
106 | def test_lzma_compress():
107 | assert (
108 | Chepy("some data").lzma_compress().to_hex().o
109 | == b"fd377a585a000004e6d6b4460200210116000000742fe5a3010008736f6d65206461746100000000bb22facdd6fa557b000121096c18c5d51fb6f37d010000000004595a"
110 | )
111 |
112 |
113 | def test_lzma_decompress():
114 | assert (
115 | Chepy(
116 | "fd377a585a000004e6d6b4460200210116000000742fe5a3010008736f6d65206461746100000000bb22facdd6fa557b000121096c18c5d51fb6f37d010000000004595a"
117 | )
118 | .from_hex()
119 | .lzma_decompress()
120 | .o
121 | == b"some data"
122 | )
123 |
124 |
125 | def test_tar_list_files():
126 | assert Chepy("tests/files/test.tar.gz").read_file().tar_list_files().o == [
127 | "test.js",
128 | "test.json",
129 | ]
130 | assert Chepy("tests/files/test.tar.gz").read_file().tar_list_files(mode="gz").o == [
131 | "test.js",
132 | "test.json",
133 | ]
134 |
135 |
136 | def test_tar_extract_one():
137 | assert (
138 | b"comment"
139 | in Chepy("tests/files/test.tar.gz").read_file().tar_extract_one("test.js").o
140 | )
141 | assert (
142 | b"comment"
143 | in Chepy("tests/files/test.tar.gz")
144 | .read_file()
145 | .tar_extract_one("test.js", mode="gz")
146 | .o
147 | )
148 |
149 |
150 | def test_tar_extract_all():
151 | assert len(Chepy("tests/files/test.tar.gz").read_file().tar_extract_all().o) == 2
152 | assert (
153 | len(Chepy("tests/files/test.tar.gz").read_file().tar_extract_all(mode="gz").o)
154 | == 2
155 | )
156 |
157 |
158 | def test_tar_compress():
159 | assert len(Chepy("logo.png").read_file().tar_compress("some.png").o) > 50000
160 | assert (
161 | len(Chepy("logo.png").read_file().tar_compress("some.png", mode="").o) > 50000
162 | )
163 |
164 |
165 | def test_raw_deflate_inflate():
166 | assert Chepy("securisec").raw_deflate().raw_inflate().o == b"securisec"
167 |
168 |
169 | def test_lz4_compress():
170 | assert (
171 | Chepy("data").lz4_compress().to_hex().o
172 | == b"04224d1868400400000000000000cd040000806461746100000000"
173 | )
174 |
175 |
176 | def test_lz4_decompress():
177 | assert (
178 | Chepy("04224d1868400400000000000000cd040000806461746100000000")
179 | .from_hex()
180 | .lz4_decompress()
181 | .o
182 | == b"data"
183 | )
184 |
185 | def test_lz77():
186 | input_str = "(0,0,O)(0,0,M)(0,0,G)(1,1,G)(3,3, )(0,0,Y)(10,1,U)(4,1,A)(0,0,R)(0,0,E)(4,1,C)(0,0,L)(9,1,S)(6,2,T)(5,1, )(3,1,H)(7,2,F)(13,1,A)(1,1,A)(2,2,G)(36,7,C)(28,5,C)(6,5,W)(3,1,L)(1,1, )(0,0,N)(10,1,W)(40,3,I)(15,1, )(3,3,T)(48,6,G)(5,1,E)(0,0,K)(22,1,{)(25,1,I)(38,1,E)(1,1,E)(3,3,E)(7,7,E)(15,15,_)(38,3,O)(2,2,O)(5,5,O)(11,11,O)(3,3,_)(63,23,})"
187 | array_of_arrays = []
188 | regex = r"\((\d+),(\d+),([A-Z\s_{}]+)\)"
189 | matches = re.findall(regex, input_str)
190 |
191 | for match in matches:
192 | param1, param2, param3 = match
193 | array_of_arrays.append([int(param1), int(param2), param3])
194 |
195 | assert b'EKO{' in Chepy(array_of_arrays).lz77_decompress().o
196 |
197 | assert Chepy('OMGGGGGG').lz77_compress(1).o[1] == [0, 0, 'M']
--------------------------------------------------------------------------------
/tests/test_conf.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | from chepy.config import ChepyConfig
3 |
4 |
5 | def test_config():
6 | config = ChepyConfig()
7 | config_dir = Path.home() / ".chepy"
8 | assert config.history_path == str(config_dir / "chepy_history")
9 | assert str(config.chepy_conf) == str(config_dir / "chepy.conf")
10 | assert Path(config.chepy_conf).exists()
11 | assert Path(config.history_path).exists()
12 | assert config.prompt_bottom_toolbar.startswith("#")
13 | assert config.prompt_rprompt.startswith("#")
14 | assert config.prompt_toolbar_buffers.startswith("#")
15 | assert config.prompt_toolbar_errors.startswith("#")
16 | assert config.prompt_toolbar_states.startswith("#")
17 | assert config.prompt_toolbar_type.startswith("#")
18 | assert config.prompt_toolbar_version.startswith("#")
19 | assert config.prompt_char is not None
20 | assert len(config.prompt_colors.split()) == 3
21 |
--------------------------------------------------------------------------------
/tests/test_ctf.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 | """
4 | general tests for CTF solvers
5 | """
6 |
7 |
8 | def test_csaw_23_breakthevault():
9 | assert (
10 | Chepy(
11 | "5346815611816381158830026000575759913046890410767282609674124748425112753245783703275530777684185849448083"
12 | )
13 | .to_base(16)
14 | .from_hex()
15 | .rotate_right(4)
16 | .from_base64()
17 | .o
18 | == b"csawctf{w@11_ST_1s_n0t_n3ce$$@ry}"
19 | )
20 |
21 |
22 | def test_hero_v5_heap():
23 | key = "c45c60232c9847e2"
24 | payload = "kSDIsBFTYa3+aLqEpVLXtspdLse8WclEhbqGLiqvM6k="
25 |
26 | c = (
27 | Chepy(payload)
28 | .from_base64()
29 | .aes_decrypt(key=key, key_format="utf-8", mode="ECB")
30 | )
31 | assert c.o == b"Hero{D1G_1NT0_J4V4_H34P}"
32 |
33 |
34 | def test_africe_23_own_reality():
35 | k = ".__..._..__...._.___._...___._...__.__...__.._._._....__._._._..._...__..____.__._._._._.__.___..__._.__.__.___..__.____.___.___.__.___.._._____.__..._..__._.._.___._...___..__._._____..__..__..___.....__._...__.._._.__.._._.__...._..__._....___.._.__..._...__._....__..._..__.___.__.._._.__.._._..__.._..__..__..__..__...__._._.__...._..__..._..__..__.__..__..__..._..__.._...__...__.__...__.__...._..__.__..__..__...__..__..__.._...__.___._____._"
36 | c = Chepy(k).find_replace("\\.", "0").find_replace("_", "1").from_binary()
37 | assert c.o == b"battleCTF{Unknown_bits_384eea49b417ee2ff5a13fbdcca6f327}"
38 |
39 |
40 | def test_springforward_23_hours_behind():
41 | c = Chepy("vqkk{0vtg_b1um_e1tt_b3tt}")
42 | c.rotate_bruteforce().dict_get_items().filter_list("nicc")
43 | assert c.o == b"nicc{0nly_t1me_w1ll_t3ll}"
44 |
45 |
46 | def test_bsides_c5():
47 | c = (
48 | Chepy(
49 | "BtC8EzBDHPOhKvzY6zyWRuy4lFMQNxDk9zLIG93n50uD83gxB9vg5jq7ZQJ50xpHMrUCwk4dRwtA0yGRSIDTFZ"
50 | )
51 | .from_base62()
52 | .reverse()
53 | .from_octal()
54 | .o
55 | == b"th3_cak3_is_a_li3"
56 | )
57 |
58 | c = (
59 | Chepy("MjBfcDAweF9ycm1hdV9ta3ozdmsza2ZqM19tcHlpX3B5aTN2")
60 | .from_base64()
61 | .vigenere_decode("key")
62 | .o
63 | == b"20_f00t_thick_imp3rm3abl3_clay_lay3r"
64 | )
65 |
66 | c = (
67 | Chepy(
68 | "ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnpkV0lpT2lJeE1qTTBOVFkzT0Rrd0lpd2libUZ0WlNJNklscHFSbnBoUmpsNllVZEdkMDB5VW1aWk0wcG9XVEp6ZW1OcVZTSXNJbWxoZENJNk1UVXhOakl6T1RBeU1uMC5QUkFfMlVfUHVZWEZHb1BWdGxEc2JnaHhvWDA1czNnTGVoVFJEdC1VeUgw"
69 | )
70 | .from_base64()
71 | .jwt_decode()
72 | .get_by_key("payload")
73 | .get_by_key("name")
74 | .from_base64()
75 | .o
76 | == b"f1sh_shap3d_crack3r5"
77 | )
78 |
79 | assert (
80 | Chepy(
81 | "e6 96 37 33 27 f5 27 33 47 37 56 97 c6 f6 07 f5 46 33 47 16 27 57 47 16 37 e6 57"
82 | )
83 | .reverse()
84 | .remove_whitespace()
85 | .from_hex()
86 | .o
87 | == b"unsaturat3d_polyest3r_r3sin"
88 | )
89 |
--------------------------------------------------------------------------------
/tests/test_datetime.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_from_unix_timestamp():
5 | assert Chepy("1573426649").from_unix_timestamp().o[-4:] == b"2019"
6 | assert Chepy("1546573919").from_unix_timestamp(utc=True).o[-4:] == b"2019"
7 |
8 |
9 | # def test_to_unix_timestamp():
10 | # assert Chepy("Sun Nov 10 17:57:29 2019").to_unix_timestamp().o == 1573426649
11 |
--------------------------------------------------------------------------------
/tests/test_extras/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/securisec/chepy/94da185ee9b1700f32da75028b2909fc83a1aeb9/tests/test_extras/__init__.py
--------------------------------------------------------------------------------
/tests/test_extras/test_bruteforce.py:
--------------------------------------------------------------------------------
1 | from chepy.extras.bruteforce import *
2 |
3 |
4 | def test_zip_brute():
5 | assert (
6 | zip_password_bruteforce("tests/files/test.zip", "tests/files/wordlist.txt")
7 | == b"password"
8 | )
9 |
10 |
--------------------------------------------------------------------------------
/tests/test_extras/test_characters.py:
--------------------------------------------------------------------------------
1 | from chepy.extras.characters import base64_char_sets
2 |
3 |
4 | def test_base64_chars():
5 | assert base64_char_sets() == {
6 | "standard": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
7 | "url_safe": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
8 | "filename_safe": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\\-=",
9 | "itoa64": "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=",
10 | "xml": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.",
11 | "y64": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-",
12 | "z64": "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/=",
13 | "radix64": "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/=",
14 | "uuencoding": " -_",
15 | "xxencoding": "+\\-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
16 | "unix_crypt": "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/tests/test_extras/test_combinations.py:
--------------------------------------------------------------------------------
1 | from chepy.extras.combinatons import *
2 |
3 |
4 | def test_all_combinations():
5 | combo = generate_combo(["a", 1, "\x10"])
6 | assert type(next(combo)) == tuple
7 | assert len([x for x in combo]) == 15
8 | assert len(list(generate_combo(['a', 'b', 'c'], 2, 3))) == 12
9 | assert len(list(generate_combo(['a', 'b', 'c'], max_length=2))) == 6
10 |
11 | def test_all_hex():
12 | assert len(hex_chars()) == 256
13 |
--------------------------------------------------------------------------------
/tests/test_extras/test_crypto_extras.py:
--------------------------------------------------------------------------------
1 | from chepy.extras.crypto import one_time_pad_crib
2 |
3 |
4 | def test_one_time_pad_crib():
5 | assert (
6 | one_time_pad_crib(
7 | "51060328ac104b70881b267fb254d7914948e697aff2ce1c07c91c51b4ff2a172b6477c7e006",
8 | "560b032eb6481826df19237ce403d7c34c4db194fff59a4f559a4d09b6fa72157a642797e31a",
9 | b"a" * 38,
10 | )[0]
11 | == "flag{9276cdb76a3dd6b1f523209cd9c0a11b}"
12 | )
13 |
--------------------------------------------------------------------------------
/tests/test_extras/test_misc.py:
--------------------------------------------------------------------------------
1 | from chepy.extras.misc import *
2 |
3 |
4 | def test_shannon_entropy():
5 | assert shannon_entropy("some text") == 2.725480556997868
6 | assert shannon_entropy("some text", unit="hartley") == 0.8204514002553331
7 | assert shannon_entropy("some text", unit="natural") == 1.8891591637540215
8 |
9 |
10 | def test_IC():
11 | with open("tests/files/hello", "rb") as f:
12 | data = f.read()
13 | assert index_of_coincidence(data) == 0
14 |
--------------------------------------------------------------------------------
/tests/test_file_encoding.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | from chepy import Chepy
3 |
4 | path = str(Path().absolute() / "tests/files/encoding")
5 |
6 |
7 | def test_read_file():
8 | c = Chepy(path).load_file()
9 | assert c.out[0:10] == b"=0GDAqREMS"
10 |
11 |
12 | def test_rot_13():
13 | c = Chepy(path).load_file()
14 | assert c.rot_13().out[:10] == b"=0TQNdERZF"
15 |
16 |
17 | def test_reverse():
18 | c = Chepy(path).load_file()
19 | assert c.reverse().out[0:10] == b"E0SMERSADy"
20 |
21 |
22 | def test_flag():
23 | c = Chepy(path).load_file()
24 | assert (
25 | c.reverse().rot_13().from_base64().from_base32().str_from_hexdump().out
26 | == b"StormCTF{Spot3:DcEC6181F48e3B9D3dF77Dd827BF34e0}"
27 | )
28 |
--------------------------------------------------------------------------------
/tests/test_hashing.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_sha1():
5 | assert Chepy("A").sha1().out == b"6dcd4ce23d88e2ee9568ba546c007c63d9131c1b"
6 |
7 |
8 | def test_sha2_256():
9 | assert (
10 | Chepy("A").sha2_256().out
11 | == b"559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd"
12 | )
13 |
14 |
15 | def test_sha2_512():
16 | assert (
17 | Chepy("A").sha2_512().out
18 | == b"21b4f4bd9e64ed355c3eb676a28ebedaf6d8f17bdc365995b319097153044080516bd083bfcce66121a3072646994c8430cc382b8dc543e84880183bf856cff5"
19 | )
20 |
21 |
22 | def test_sha2_384():
23 | assert (
24 | Chepy("A").sha2_384().out
25 | == b"ad14aaf25020bef2fd4e3eb5ec0c50272cdfd66074b0ed037c9a11254321aac0729985374beeaa5b80a504d048be1864"
26 | )
27 |
28 |
29 | def test_sha2_224():
30 | assert (
31 | Chepy("A").sha2_224().out
32 | == b"5cfe2cddbb9940fb4d8505e25ea77e763a0077693dbb01b1a6aa94f2"
33 | )
34 |
35 |
36 | def test_sha2_512_truncate():
37 | assert (
38 | Chepy("abc").sha2_512_truncate().out
39 | == b"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"
40 | )
41 |
42 |
43 | def test_sha3_512():
44 | assert (
45 | Chepy("A").sha3_512().out
46 | == b"f5f0eaa9ca3fd0c4e0d72a3471e4b71edaabe2d01c4b25e16715004ed91e663a1750707cc9f04430f19b995f4aba21b0ec878fc5c4eb838a18df5bf9fdc949df"
47 | )
48 |
49 |
50 | def test_sha3_256():
51 | assert (
52 | Chepy("A").sha3_256().out
53 | == b"1c9ebd6caf02840a5b2b7f0fc870ec1db154886ae9fe621b822b14fd0bf513d6"
54 | )
55 |
56 |
57 | def test_sha3_384():
58 | assert (
59 | Chepy("A").sha3_384().out
60 | == b"15000d20f59aa483b5eac0a1f33abe8e09dea1054d173d3e7443c68035b99240b50f7abdb9553baf220320384c6b1cd6"
61 | )
62 |
63 |
64 | def test_sha3_224():
65 | assert (
66 | Chepy("A").sha3_224().out
67 | == b"97e2f98c0938943ab1a18a1721a04dff922ecc1ad14d4bbf905c02ca"
68 | )
69 |
70 |
71 | def test_md2():
72 | assert Chepy("A").md2().out == b"08e2a3810d8426443ecacaf47aeedd17"
73 |
74 |
75 | def test_md4():
76 | assert Chepy("A").md4().out == b"d5ef20eeb3f75679f86cf57f93ed0ffe"
77 |
78 |
79 | def test_md5():
80 | assert Chepy("A").md5().out == b"7fc56270e7a70fa81a5935b72eacbe29"
81 |
82 |
83 | def test_keccak_384():
84 | assert (
85 | Chepy("A").keccak_384().out
86 | == b"5c744cf4b4e3fb8967189e9744261a74f0ef31cdd8850554c737803585ac109039b73c22c50ea866c94debf1061f37a4"
87 | )
88 |
89 |
90 | def test_keccak_256():
91 | assert (
92 | Chepy("A").keccak_256().out
93 | == b"03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760"
94 | )
95 |
96 |
97 | def test_keccak_224():
98 | assert (
99 | Chepy("A").keccak_224().out
100 | == b"ef40b16ff375c834e91412489889f36538748c5454f4b02ba750b65e"
101 | )
102 |
103 |
104 | def test_keccak_512():
105 | assert (
106 | Chepy("A").keccak_512().out
107 | == b"421a35a60054e5f383b6137e43d44e998f496748cc77258240ccfaa8730b51f40cf47c1bc09c728a8cd4f096731298d51463f15af89543fed478053346260c38"
108 | )
109 |
110 |
111 | def test_shake_256():
112 | assert (
113 | Chepy("A").shake_256().out
114 | == b"5e6812c0bbaaee6440dcc8b81ca6809645f7512e06cf5acb57bd16dc3a2bfc57dc2bf9e6d8941950594bef5191d8394691f86edffcad6c5ebad9365f282f37a8"
115 | )
116 |
117 |
118 | def test_shake_128():
119 | assert (
120 | Chepy("A").shake_128(128).out
121 | == b"a5ba3aeee1525b4ae5439e54cd711f14850251e02c5999a53f61374c0ae089ef905a30c6abe132988c3eb233aaa2a79737fd245f87eda8b635a53720865a8604512a7ca47defb8993adae051e8390881d86968edf631d97f00b4ebef58ad183dc49d97dacc1e6bf1f38a99784dcfe517e4aa3b22401a9b35fd184c19626b8b53"
122 | )
123 |
124 |
125 | def test_ripemd_160():
126 | assert Chepy("A").ripemd_160().out == b"ddadef707ba62c166051b9e3cd0294c27515f2bc"
127 |
128 |
129 | def test_blake_2b():
130 | assert (
131 | Chepy("A").blake_2b(bits=128, key="key").out
132 | == b"6d2e4cba3bc564e02d1a76f585a6795d"
133 | )
134 |
135 |
136 | def test_blake_2s():
137 | assert (
138 | Chepy("A").blake_2s(bits=128, key="key").out
139 | == b"4e33cc702e9d08c28a5e9691f23bc66a"
140 | )
141 |
142 |
143 | def test_crc8_checksum():
144 | assert Chepy("abc").crc8_checksum().out == b"5f"
145 |
146 |
147 | def test_crc16_checksum():
148 | assert Chepy("a").crc16_checksum().out == b"e8c1"
149 |
150 |
151 | def test_crc32_checksum():
152 | assert Chepy("a").crc32_checksum().out == b"e8b7be43"
153 |
154 |
155 | def test_hmac_hash():
156 | assert Chepy("abc").hmac_hash("", "md5").out == b"dd2701993d29fdd0b032c233cec63403"
157 | assert (
158 | Chepy("abc").hmac_hash("", "sha1").out
159 | == b"9b4a918f398d74d3e367970aba3cbe54e4d2b5d9"
160 | )
161 | assert (
162 | Chepy("abc").hmac_hash("", "sha256").out
163 | == b"fd7adb152c05ef80dccf50a1fa4c05d5a3ec6da95575fc312ae7c5d091836351"
164 | )
165 | assert (
166 | Chepy("abc").hmac_hash("", "sha512").out
167 | == b"29689f6b79a8dd686068c2eeae97fd8769ad3ba65cb5381f838358a8045a358ee3ba1739c689c7805e31734fb6072f87261d1256995370d55725cba00d10bdd0"
168 | )
169 |
170 |
171 | def test_bcrypt_hash():
172 | assert Chepy("abc").bcrypt_hash().out.decode().startswith("$2a$10")
173 |
174 |
175 | def test_bcrypt_compare():
176 | assert Chepy("abc").bcrypt_compare(
177 | "$2a$10$SpXMRnrQ4IQqC710xMHfAu0BBr4nJkuPqDvzhiAACnykgn87iE2S2"
178 | )
179 |
180 |
181 | def test_scrypt_hash():
182 | assert (
183 | Chepy("abc").scrypt_hash(salt="", key_length=16).out
184 | == b"f352f3374cf4e344dde4108b96985248"
185 | )
186 |
187 |
188 | def test_derive_pbkdf2_key():
189 | assert (
190 | Chepy(".")
191 | .derive_pbkdf2_key(
192 | "mR3m", "d9016d44c374f5fb62604683f4d61578", show_full_key=True
193 | )
194 | .o[:10]
195 | == b"7c8898f222"
196 | )
197 | assert (
198 | Chepy(".").derive_pbkdf2_key("mR3m", "d9016d44c374f5fb62604683f4d61578").o
199 | == b"7c8898f22239ce49aad28e6d16266b8dc1d681f86d2a56c76ebad5cfac1b0dd6"
200 | )
201 | assert (
202 | Chepy(".")
203 | .derive_pbkdf2_key("mR3m", "d9016d44c374f5fb62604683f4d61578", hash_type="md5")
204 | .o[:10]
205 | == b"f7918edc04"
206 | )
207 | assert (
208 | Chepy(".")
209 | .derive_pbkdf2_key(
210 | "mR3m", "d9016d44c374f5fb62604683f4d61578", hash_type="sha256"
211 | )
212 | .o[:10]
213 | == b"16b0a769cb"
214 | )
215 | assert (
216 | Chepy(".")
217 | .derive_pbkdf2_key(
218 | "mR3m", "d9016d44c374f5fb62604683f4d61578", hash_type="sha512"
219 | )
220 | .o[:10]
221 | == b"6d2a9c4b24"
222 | )
223 |
224 |
225 | def test_password_hashing():
226 | password = "lol"
227 | assert (
228 | Chepy(password).password_hashing("lmhash").o
229 | == b"7d0fbaebf878e771aad3b435b51404ee"
230 | )
231 | assert (
232 | Chepy(password).password_hashing("msdcc", user="lol").o
233 | == b"5a487b0cda9a56e7e25464d81da162a2"
234 | )
235 |
--------------------------------------------------------------------------------
/tests/test_links.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_pastebin_to_raw():
5 | assert (
6 | Chepy("https://pastebin.com/abCD").pastebin_to_raw().o
7 | == b"https://pastebin.com/raw/abCD"
8 | )
9 |
10 |
11 | def test_github_to_raw():
12 | assert (
13 | Chepy("https://github.com/securisec/chepy/blob/master/README.md")
14 | .github_to_raw()
15 | .o
16 | == b"https://raw.githubusercontent.com/securisec/chepy/master/README.md"
17 | )
18 |
19 |
20 | def test_google_search_ei_to_epoch():
21 | assert Chepy("Bh8hYqykHc64mAXkkoTgCg==").google_search_ei_to_epoch().o == 1646337798
22 |
23 |
24 | # def test_to_unix_timestamp():
25 | # assert Chepy("Sun Nov 10 17:57:29 2019").to_unix_timestamp().o == 1573426649
26 |
--------------------------------------------------------------------------------
/tests/test_networking.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_defang_url():
5 | assert (
6 | Chepy("https://app.google.com/?lol=some data&a=1").defang_url().o
7 | == b"hxxps://app[.]google[.]com/?lol=some data&a=1"
8 | )
9 |
10 |
11 | def test_refang_url():
12 | assert (
13 | Chepy("hxxps://app[.]google[.]com/?lol=some data&a=1").refang_url().o
14 | == b"https://app.google.com/?lol=some data&a=1"
15 | )
16 |
17 |
18 | def test_defang_ip():
19 | assert (
20 | Chepy("2001:4860:4860::8844").defang_ip().o == b"2001[:]4860[:]4860[:][:]8844"
21 | )
22 | assert Chepy("127.0.0.1").defang_ip().o == b"127[.]0[.]0[.]1"
23 |
24 |
25 | def test_refang_ip():
26 | assert Chepy("127[.]0[.]0[.]1").refang_ip().o == b"127.0.0.1"
27 |
28 |
29 | def test_parse_uri():
30 | assert Chepy("http://example.com/resource?foo=bar#fragment").parse_uri().o == {
31 | "scheme": "http",
32 | "location": "example.com",
33 | "path": "/resource",
34 | "params": "",
35 | "query": {"foo": ["bar"]},
36 | "fragment": "fragment",
37 | }
38 |
39 |
40 | def test_parse_ip_range():
41 | assert len(Chepy("10.10.10.1/24").parse_ip_range().o) == 254
42 |
43 |
44 | def test_parse_ipv6():
45 | assert Chepy("2001:4860:4860::8888").parse_ipv6().o == {
46 | "long": "2001:4860:4860:0000:0000:0000:0000:8888",
47 | "short": "2001:4860:4860::8888",
48 | }
49 |
50 |
51 | def test_get_cert():
52 | assert Chepy("google.com").get_ssl_cert().o["subject"]["commonName"] != ""
53 |
54 |
55 | def test_int_to_ip():
56 | assert Chepy("2130706433").int_to_ip().o == b"127.0.0.1"
57 | assert Chepy("127.0.0.1").ip_to_int().o == 2130706433
58 |
--------------------------------------------------------------------------------
/tests/test_other.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_uuid():
5 | assert len(Chepy('').generate_uuid().o) == 36
6 |
7 |
--------------------------------------------------------------------------------
/tests/test_publickey.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | from chepy import Chepy
3 |
4 | path = str(Path().absolute() / "tests/files/test.pem")
5 |
6 |
7 | def test_parse_x509_pem():
8 | assert Chepy(path).load_file().parse_x509_pem().o == {
9 | "version": 0,
10 | "serial": 16349711528102141469,
11 | "algo": b"sha256WithRSAEncryption",
12 | "before": b"20191102152508Z",
13 | "after": b"20201101152508Z",
14 | "issuer": {
15 | "C": "US",
16 | "ST": "lol",
17 | "L": "nyc",
18 | "O": "securisec",
19 | "OU": "coder",
20 | "CN": "securisec",
21 | "email": "none@email.com",
22 | },
23 | "subject": {
24 | "C": "US",
25 | "ST": "lol",
26 | "L": "nyc",
27 | "O": "securisec",
28 | "OU": "coder",
29 | "CN": "securisec",
30 | "email": "none@email.com",
31 | },
32 | "pubkey": {"bits": 1024},
33 | }
34 |
35 |
36 | def test_parse_x509_der_hex():
37 | assert Chepy(
38 | str(Path().absolute() / "tests/files/test.der")
39 | ).load_file().parse_x509_der_hex().o == {
40 | "version": 0,
41 | "serial": 16349711528102141469,
42 | "algo": b"sha256WithRSAEncryption",
43 | "before": b"20191102152508Z",
44 | "after": b"20201101152508Z",
45 | "issuer": {
46 | "C": "US",
47 | "ST": "lol",
48 | "L": "nyc",
49 | "O": "securisec",
50 | "OU": "coder",
51 | "CN": "securisec",
52 | "email": "none@email.com",
53 | },
54 | "subject": {
55 | "C": "US",
56 | "ST": "lol",
57 | "L": "nyc",
58 | "O": "securisec",
59 | "OU": "coder",
60 | "CN": "securisec",
61 | "email": "none@email.com",
62 | },
63 | "pubkey": {"bits": 1024},
64 | }
65 |
66 |
67 | def test_pem_to_der():
68 | assert Chepy(path).load_file().pem_to_der_hex().to_hex().o.decode()[0:6] == "308202"
69 |
70 |
71 | def test_der_hex_to_pem():
72 | assert (
73 | Chepy(str(Path().absolute() / "tests/files/test.der"))
74 | .load_file()
75 | .der_hex_to_pem()
76 | .o.decode()
77 | == """-----BEGIN CERTIFICATE-----
78 | MIICeTCCAeICCQDi5dgCpKMeHTANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMC
79 | VVMxDDAKBgNVBAgMA2xvbDEMMAoGA1UEBwwDbnljMRIwEAYDVQQKDAlzZWN1cmlz
80 | ZWMxDjAMBgNVBAsMBWNvZGVyMRIwEAYDVQQDDAlzZWN1cmlzZWMxHTAbBgkqhkiG
81 | 9w0BCQEWDm5vbmVAZW1haWwuY29tMB4XDTE5MTEwMjE1MjUwOFoXDTIwMTEwMTE1
82 | MjUwOFowgYAxCzAJBgNVBAYTAlVTMQwwCgYDVQQIDANsb2wxDDAKBgNVBAcMA255
83 | YzESMBAGA1UECgwJc2VjdXJpc2VjMQ4wDAYDVQQLDAVjb2RlcjESMBAGA1UEAwwJ
84 | c2VjdXJpc2VjMR0wGwYJKoZIhvcNAQkBFg5ub25lQGVtYWlsLmNvbTCBnzANBgkq
85 | hkiG9w0BAQEFAAOBjQAwgYkCgYEA1L6ceV3tvkHtMHI5vOwr+cjW/H0yINh9PYHy
86 | +CS9MmrX12pe/m1FLapMUu5HgQZAKrtldccb3WiGQNprs/Wce1g8hmvD0pAXffij
87 | Q+vjvHVU3l+up1ocL6IPpxrQVz0bzpQ4sMRK0CdZgjf4y4HL188qMNgYGOZBgttF
88 | Xxoz41UCAwEAATANBgkqhkiG9w0BAQsFAAOBgQChhviBdift0P/j00TYxnPPNS58
89 | wQSFm54UNQ/vjM12yZ+C5c3268Vo8jSP7mI5R3wn6XztjUSXkDg5/3IL3kojti/h
90 | nyhBHx2QCVke7BxWw3HWkbZ/1BKl0HnCGyd5HDTuOtlBmTS+QrJoNpdsn0zq4fvc
91 | igbV1IJdKTBAiZzaOQ==
92 | -----END CERTIFICATE-----
93 | """
94 | )
95 |
96 |
97 | def test_pkcs12():
98 | assert (
99 | "-----BEGIN PRIVATE KEY-----"
100 | in Chepy("tests/files/pkcs12")
101 | .read_file()
102 | .dump_pkcs12_cert("mimikatz")
103 | .get_by_key("private")
104 | .o.decode()
105 | )
106 |
107 |
108 | def test_parse_public():
109 | assert (
110 | Chepy("tests/files/public.pem").load_file().parse_public_pem().get_by_key("e").o
111 | == 65537
112 | )
113 |
114 |
115 | def test_parse_private():
116 | assert (
117 | Chepy("tests/files/private.pem")
118 | .load_file()
119 | .parse_private_pem()
120 | .get_by_key("p")
121 | .o
122 | == 12567061504848007717323266435513666403545525206525105210732583342352560503165028238964437465562703567713719610893680829859726382850796095548144718531640607
123 | )
124 |
125 |
126 | def test_public_from_x509():
127 | assert (
128 | Chepy("tests/files/test.pem").load_file().public_from_x509().o
129 | == b"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUvpx5Xe2+Qe0wcjm87Cv5yNb8\nfTIg2H09gfL4JL0yatfXal7+bUUtqkxS7keBBkAqu2V1xxvdaIZA2muz9Zx7WDyG\na8PSkBd9+KND6+O8dVTeX66nWhwvog+nGtBXPRvOlDiwxErQJ1mCN/jLgcvXzyow\n2BgY5kGC20VfGjPjVQIDAQAB\n-----END PUBLIC KEY-----\n"
130 | )
131 |
132 |
133 | def test_generate_rsa_keypair():
134 | k = Chepy("").generate_rsa_keypair().o
135 | assert b"PUBLIC" in k["public"]
136 | assert b"PRIVATE" in k["private"]
137 |
138 |
139 | def test_generate_ecc_keypair():
140 | k = Chepy("").generate_ecc_keypair().o
141 | assert "PUBLIC" in k["public"]
142 | assert "PRIVATE" in k["private"]
143 |
--------------------------------------------------------------------------------
/tests/test_search.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_search():
5 | assert Chepy("abcdefg123 and again abcdefg124").search(r"abc(de)fg(12)(\d)").o == [
6 | (b"de", b"12", b"3"),
7 | (b"de", b"12", b"4"),
8 | ]
9 |
10 |
11 | def test_search_list():
12 | assert Chepy(
13 | ["InfoSeCon2023{1af5856c70878f8566085bc13849ef4d}", True, 123, ["a", "b"]]
14 | ).search_list("Info.+").o == [[b"InfoSeCon2023{1af5856c70878f8566085bc13849ef4d}"]]
15 |
16 |
17 | def test_ctf_flags():
18 | assert (
19 | Chepy("tests/files/flags")
20 | .read_file()
21 | .search_ctf_flags("pico")
22 | .get_by_index(0)
23 | .o
24 | == b"picoCTF{r3source_pag3_f1ag}"
25 | )
26 |
27 |
28 | def test_find_slack_tokenss():
29 | assert (
30 | Chepy("tests/files/flags").read_file().search_slack_tokens().get_by_index(0).o
31 | == b"xoxb-808882645436-350102357778-949755564313-1v9kucs6pv4o208oj4zh9sxqt76a5859"
32 | )
33 |
34 |
35 | def test_search_private():
36 | assert len(Chepy("tests/files/flags").read_file().search_private_key().o) == 1
37 |
38 |
39 | def test_slack_webhook():
40 | assert len(Chepy("tests/files/flags").read_file().search_slack_webhook().o) == 1
41 |
42 |
43 | def test_twilio_key():
44 | assert len(Chepy("tests/files/flags").read_file().search_twilio_key().o) == 1
45 |
46 |
47 | def test_aws_key():
48 | assert len(Chepy("tests/files/flags").read_file().search_aws_key().o) == 1
49 |
--------------------------------------------------------------------------------
/tests_plugins/_test_git.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_git_author():
5 | assert Chepy("chepy/chepy_plugins").git_authors().o.get("securisec")
6 |
7 |
8 | def test_git_code_search():
9 | assert len(Chepy("chepy/chepy_plugins").git_search_code("markdown").o) > 0
10 |
11 |
--------------------------------------------------------------------------------
/tests_plugins/test_additionalextractors.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_jpath():
5 | assert (
6 | Chepy("tests/files/test.json")
7 | .load_file()
8 | .jpath_selector("[*].name.first")
9 | .get_by_index(2)
10 | .o
11 | == b"Long"
12 | )
13 |
14 |
15 | # def test_php_deserialzie():
16 | # assert Chepy(
17 | # 'a:3:{i:1;s:6:"elem 1";i:2;s:6:"elem 2";i:3;s:7:" elem 3";}'
18 | # ).php_deserialize().o == {1: b"elem 1", 2: b"elem 2", 3: b" elem 3"}
19 |
20 |
21 | def test_minify_xml():
22 | assert len(Chepy("tests/files/test.xml").load_file().minify_xml().o) == 6392
23 |
24 |
25 | def test_beautify_xml():
26 | assert (
27 | len(Chepy("tests/files/test.xml").load_file().minify_xml().beautify_xml().o)
28 | == 7690
29 | )
30 |
--------------------------------------------------------------------------------
/tests_plugins/test_binary.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_pe_get_certs():
5 | assert (
6 | Chepy("tests/files/ff.exe")
7 | .read_file()
8 | .pe_get_certificates()
9 | .get_by_index(0)
10 | .get_by_key("serial")
11 | .o
12 | == 17154717934120587862167794914071425081
13 | )
14 |
15 |
16 | def test_pe_imports():
17 | assert (
18 | len(
19 | Chepy("tests/files/ff.exe")
20 | .read_file()
21 | .pe_imports()
22 | .get_by_key(
23 | b"api-ms-win-crt-filesystem-l1-1-0.dll", py_style=True, split_key=None
24 | )
25 | .o
26 | )
27 | == 2
28 | )
29 |
30 |
31 | def test_pe_exports():
32 | assert len(Chepy("tests/files/ff.exe").read_file().pe_exports().o) == 94
33 |
34 |
35 | def test_elf_imports():
36 | assert (
37 | len(
38 | Chepy("tests/files/elf")
39 | .load_file()
40 | .elf_imports()
41 | .get_by_key(".rela.dyn", py_style=True, split_key=None)
42 | .o
43 | )
44 | == 9
45 | )
46 |
--------------------------------------------------------------------------------
/tests_plugins/test_extract_plugin.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_extract_common_secrets():
5 | assert (
6 | len(
7 | Chepy("tests/files/vuln_code")
8 | .load_file()
9 | .extract_common_secrets()
10 | .get_by_key("KEY")
11 | .o
12 | )
13 | == 6
14 | )
15 |
--------------------------------------------------------------------------------
/tests_plugins/test_forensics.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | # def test_file_mime():
5 | # assert Chepy("logo.png").load_file().file_mime().o == "image/png"
6 |
7 |
8 | # def test_file_magic():
9 | # assert (
10 | # Chepy("logo.png").read_file().file_magic().o
11 | # == "PNG image data, 1920 x 1080, 8-bit/color RGBA, non-interlaced"
12 | # )
13 |
14 |
15 | def test_get_metadata():
16 | assert Chepy("logo.png").load_file().get_metadata().o == {
17 | "Bits/pixel": "32",
18 | "Compression": "deflate",
19 | "Compression rate": "138.6x",
20 | "Creation date": "2019-11-30 21:40:30",
21 | "Endianness": "Big endian",
22 | "Image DPI height": "3780 DPI",
23 | "Image DPI width": "3780 DPI",
24 | "Image height": "1080 pixels",
25 | "Image width": "1920 pixels",
26 | "MIME type": "image/png",
27 | "Pixel format": "RGBA",
28 | }
29 |
30 |
31 | def test_embedded():
32 | Chepy("logo.png").load_file().embedded_files()
33 | assert True
34 |
--------------------------------------------------------------------------------
/tests_plugins/test_hash.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 | def test_identify_hash():
4 | assert (
5 | Chepy("6dcd4ce23d88e2ee9568ba546c007c63d9131c1b").identify_hash().o[0]["name"]
6 | == "SHA-1"
7 | )
--------------------------------------------------------------------------------
/tests_plugins/test_ml.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_ml_detect():
5 | assert (
6 | Chepy("https%3A%2F%2Fwww.pennington.com%2Fcategories%2Fwp-content")
7 | .ml_detect()
8 | .o.get("from_url_encode")
9 | != None
10 | )
11 | data = "5ZXN4aSn4N2ZVzGA6Q7NbqCRJa2XBt2CEKAvgDUoQj8x9vBJqcrk5fBKZh5XqdAoKnyXMeNmE21QQAqZcKZPamT8he6s8nYRU1unmSb2eAmnnBv8NWSs9f6BgsJ3DGPpdbPm8b9kDSMDTLfZ1"
12 | assert Chepy(data).ml_detect().o.get("from_base58") != None
13 | assert Chepy(data).from_base58().ml_detect().o.get("from_hex") != None
14 | assert (
15 | Chepy(data).from_base58().from_hex().ml_detect().o.get("lzma_decompress")
16 | != None
17 | )
18 |
19 |
20 | def test_ml_magic():
21 | assert (
22 | Chepy("Ca6wMuk9H4Y3rYb8uMQordMrH6JbvsaWx2Ua7dNQvF1tujWPvi2AEijEKsD6Mpe7Ld37T1y")
23 | .ml_magic()
24 | .o[-1]
25 | == b"hello world"
26 | )
27 |
28 | assert (
29 | Chepy(
30 | "KZWTCNCVGFEXSUTOJJHFM3LIKVMWWZDPKZLFS522I44VOYSHPB5FSVLDGVLGWMKXKNWGYWSNI5UFAVSHPBQWGMKOONREM4COKJWHATKXK52GCWKWLJLVE3SGLBREQQTTLFMHAV2NNRNHCU3KKJMGEVS2JFKWY2DXMFDEU42XNM4VMYSYKIZVMMC2MFJDC4CFKVWXATSSIZNDMV2WKJHWIMLMK5JW4SSUMJDEUV2ZK52EOTJROBCVE3DQNRLFIRS2K5VWI43BI5LHEV3MNBLVEM3IOZKWURTLKIYXARTBIZNGSUSWOBMFOVSSI5SDERSHMEZWIWDCLBJFSVTKIEYVEMKZPFGVIUTIKIYVUMC2KVLGWVRSJJDWGRSSK5QWWWT2KZVEM22XK5DEQYKFGVHGERLQMFLDCWSTKMZEK52NJBUFOYJSKJKFM23EGRKWYWSXKVMGIUCVKQYDS==="
31 | )
32 | .ml_magic(10)
33 | .o[-1]
34 | == b"InfoSeCon2023{1af5856c70878f8566085bc13849ef4d}"
35 | )
36 |
--------------------------------------------------------------------------------
/tests_plugins/test_multimedia.py:
--------------------------------------------------------------------------------
1 | import re
2 | from chepy import Chepy
3 |
4 |
5 | def test_image_resize():
6 | assert len(Chepy("logo.png").read_file().resize_image(128, 128, "png").o) > 0
7 | assert (
8 | len(Chepy("logo.png").read_file().resize_image(128, 128, "png", "hamming").o)
9 | > 0
10 | )
11 | assert (
12 | len(Chepy("logo.png").read_file().resize_image(128, 128, "png", "box").o)
13 | != 4900
14 | )
15 | assert (
16 | len(Chepy("logo.png").read_file().resize_image(128, 128, "png", "bilinear").o)
17 | > 0
18 | )
19 | assert (
20 | len(Chepy("logo.png").read_file().resize_image(128, 128, "png", "antialias").o)
21 | > 0
22 | )
23 |
24 |
25 | def test_split_color_channels():
26 | assert len(Chepy("logo.png").load_file().split_color_channels("png").o) == 3
27 |
28 |
29 | def test_rotate_image():
30 | c1 = Chepy("logo.png").load_file().o
31 | c2 = Chepy("logo.png").load_file().rotate_image(180, "png").o
32 | assert c1 != c2
33 |
34 |
35 | def test_grayscale_image():
36 | c1 = Chepy("logo.png").load_file().o
37 | c2 = Chepy("logo.png").load_file().grayscale_image("png").o
38 | assert c1 != c2
39 |
40 |
41 | def test_blur_image():
42 | c1 = Chepy("logo.png").load_file().o
43 | c2 = Chepy("logo.png").load_file().blur_image("png").o
44 | c3 = Chepy("logo.png").load_file().blur_image(extension="png", gaussian=True).o
45 | assert c1 != c2
46 | assert c1 != c3
47 |
48 |
49 | def test_invert_image():
50 | c1 = Chepy("logo.png").load_file().o
51 | c2 = Chepy("logo.png").load_file().invert_image("png").o
52 | assert c1 != c2
53 |
54 |
55 | def test_image_opacity():
56 | c1 = Chepy("logo.png").load_file().o
57 | c2 = Chepy("logo.png").load_file().image_opacity(10, "png").o
58 | assert c1 != c2
59 |
60 |
61 | def test_image_contrast():
62 | c1 = Chepy("logo.png").load_file().o
63 | c2 = Chepy("logo.png").load_file().image_contrast(10, "png").o
64 | assert c1 != c2
65 |
66 |
67 | def test_image_brightness():
68 | c1 = Chepy("logo.png").load_file().o
69 | c2 = Chepy("logo.png").load_file().image_brightness(10, "png").o
70 | assert c1 != c2
71 |
72 |
73 | def test_image_sharpness():
74 | c1 = Chepy("logo.png").load_file().o
75 | c2 = Chepy("logo.png").load_file().image_sharpness(10, "png").o
76 | assert c1 != c2
77 |
78 |
79 | def test_image_color():
80 | c1 = Chepy("logo.png").load_file().o
81 | c2 = Chepy("logo.png").load_file().image_color(10, "png").o
82 | assert c1 != c2
83 |
84 |
85 | def test_image_add_text():
86 | c1 = Chepy("logo.png").load_file().o
87 | c2 = Chepy("logo.png").load_file().image_add_text("some text").o
88 | assert c1 != c2
89 |
90 |
91 | def test_convert_image():
92 | assert (
93 | Chepy("logo.png").load_file().convert_image("jpeg").to_hex().o[0:6] == b"ffd8ff"
94 | )
95 |
96 |
97 | def test_lsb_by_channel():
98 | assert re.search(
99 | b"4E34B38257200616FB75CD869B8C3CF0",
100 | Chepy("tests/files/lsb.png").read_file().lsb_dump_by_channel().from_binary().o,
101 | )
102 |
103 |
104 | def test_msb_by_channel():
105 | assert re.search(
106 | b"MSB_really_sucks",
107 | Chepy("tests/files/msb.png")
108 | .read_file()
109 | .msb_dump_by_channel("b", True)
110 | .from_binary()
111 | .o,
112 | )
113 |
--------------------------------------------------------------------------------
/tests_plugins/test_pcap.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_pcap_dns():
5 | assert (
6 | len(
7 | Chepy("tests/files/test.pcapng")
8 | .debug(True)
9 | .read_pcap()
10 | .pcap_dns_queries()
11 | .set()
12 | .o
13 | )
14 | == 3
15 | )
16 |
17 |
18 | def test_pcap_http_streams():
19 | assert len(Chepy("tests/files/test.pcapng").read_pcap().pcap_http_streams().o) == 4
20 |
21 |
22 | def test_pcap_payload():
23 | assert Chepy("tests/files/test.pcapng").read_pcap().pcap_payload(
24 | layer="ICMP"
25 | ).o == [b"secret", b"message"]
26 |
27 |
28 | def test_packet_to_dict():
29 | assert (
30 | Chepy("tests/files/test.pcapng").read_pcap().pcap_to_dict().o[0]["IP"]["src"]
31 | == "10.10.10.11"
32 | )
33 |
34 |
35 | def test_pcap_layer_stats():
36 | assert (
37 | Chepy("tests/files/test.pcapng")
38 | .read_pcap()
39 | .pcap_layer_stats()
40 | .get_by_key("DNS")
41 | .o
42 | == 6
43 | )
44 |
45 |
46 | def test_pcap_convo():
47 | assert (
48 | Chepy("tests/files/test.pcapng")
49 | .read_pcap()
50 | .pcap_convos()
51 | .get_by_key("10.10.10.11", split_key="", py_style=True)
52 | .o["ICMP"]
53 | )
54 |
55 |
56 | def test_usb_keyboard():
57 | c = Chepy("tests/files/keyboard.pcap").read_pcap().pcap_usb_keyboard()
58 | assert b"KAIZEN" in c.o
59 |
60 |
61 | def test_raw_payload_offset():
62 | assert Chepy("tests/files/test.pcapng").read_pcap().pcap_payload_offset(
63 | "ICMP", -20
64 | ).o == [b"secret", b"message"]
65 |
--------------------------------------------------------------------------------
/tests_plugins/test_protobuf.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_protobuf_dict():
5 | c = Chepy("tests/files/pbuf").load_file()
6 | assert c.protobuf_decode_dict().o["1"] == 1617862179230365600
7 |
8 |
9 | def test_protobuf_json():
10 | c = Chepy("tests/files/pbuf").load_file()
11 | assert c.protobuf_decode_json(True).json_to_dict().o["1"] == "1617862179230365600"
12 |
--------------------------------------------------------------------------------
/tests_plugins/test_qr.py:
--------------------------------------------------------------------------------
1 | # from chepy import Chepy
2 |
3 | # BASE = "tests/files/qr/{}.qr.png"
4 |
5 |
6 | # def test_qr():
7 | # assert Chepy(BASE.format("basic")).load_file().qr_decode().o == b"hello"
8 |
9 |
10 | # def test_qr_other():
11 | # assert Chepy(BASE.format("aztec")).load_file().qr_decode_other().o == "hello"
12 |
--------------------------------------------------------------------------------
/tests_plugins/test_sqlite.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 | DB_FILE = "tests/files/test.db"
4 |
5 |
6 | def test_sqlite_get_columns():
7 | assert len(Chepy(DB_FILE).sqlite_get_columns("customers").o) == 13
8 |
9 |
10 | def test_sqlite_get_tables():
11 | assert len(Chepy(DB_FILE).sqlite_get_tables().o) == 13
12 |
13 |
14 | def test_sqlite_dump_table():
15 | assert len(Chepy(DB_FILE).sqlite_dump_table("customers").o) == 59
16 |
17 | def test_sqlite_query():
18 | assert len(Chepy(DB_FILE).sqlite_query("select * from customers where company is not null").o) == 10
19 |
--------------------------------------------------------------------------------
/tests_plugins/test_useragent.py:
--------------------------------------------------------------------------------
1 | from chepy import Chepy
2 |
3 |
4 | def test_parse_user_agent():
5 | ua = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.10; rv:62.0) Gecko/20100101 Firefox/62.0"
6 | assert Chepy(ua).parse_user_agent().o == {
7 | "user_agent": {"family": "Firefox", "major": "62", "minor": "0", "patch": None},
8 | "os": {
9 | "family": "Mac OS X",
10 | "major": "10",
11 | "minor": "10",
12 | "patch": None,
13 | "patch_minor": None,
14 | },
15 | "device": {"family": "Other", "brand": None, "model": None},
16 | "string": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.10; rv:62.0) Gecko/20100101 Firefox/62.0",
17 | }
18 |
--------------------------------------------------------------------------------