├── .github
└── workflows
│ └── python-app.yml
├── .gitignore
├── LICENSE
├── README.md
├── analyse_obfuscation
├── __init__.py
├── helpers.py
├── output_results.py
├── run.py
└── test_process_obfuscation.py
├── docs
└── screenshot.png
├── requirements.txt
├── sample
├── .keep
├── inputs
│ ├── file.cs
│ ├── file.sct
│ ├── file.vbs
│ ├── sleep.vbs
│ └── x86.dll
└── sample.jsonl
├── sample_results
├── arp.log
├── at.log
├── bitsadmin.log
├── cacls.log
├── certutil.log
├── cmdkey.log
├── cmstp.log
├── csc.log
├── curl.log
├── findstr.log
├── fltmc.log
├── forfiles.log
├── icacls.log
├── ipconfig.log
├── jsc.log
├── mpcmdrun.log
├── msiexec.log
├── net.log
├── netsh.log
├── netstat.log
├── nslookup.log
├── ping.log
├── powershell.log
├── reg.log
├── regsvr32.log
├── robocopy.log
├── route.log
├── sc.log
├── schtasks.log
├── systeminfo.log
├── takeown.log
├── taskkill.log
├── tasklist.log
├── vbc.log
├── vssadmin.log
├── wevtutil.log
├── winrm.cmd.log
├── winrs.log
└── wmic.log
└── setup.py
/.github/workflows/python-app.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run tests and lint with a single version of Python
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: Python application
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Set up Python 3.9
20 | uses: actions/setup-python@v2
21 | with:
22 | python-version: 3.9
23 | - name: Install dependencies
24 | run: |
25 | python -m pip install --upgrade pip
26 | pip install flake8 pytest
27 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28 | - name: Lint with flake8
29 | run: |
30 | # stop the build if there are Python syntax errors or undefined names
31 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
32 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
33 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | typings/
132 |
133 | .vscode/
134 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Windows Command-Line Obfuscation
2 |
3 | ## Background
4 |
5 | `analyse_obfuscation` is a python3 module for finding common command-line obfuscation techniques for a given program, as described in [this](https://wietze.github.io/blog/windows-command-line-obfuscation) blog post.
6 |
7 | By providing one or more commands, `analyse_obfuscation` will test if the following obfuscation techniques can be applied:
8 |
9 | 1) **Option Char substitution**
10 |
11 | _e.g. `ping -n 1 localhost` == `ping /n 1 localhost`_
12 |
13 | 2) **Character substitution**
14 |
15 | _e.g. `reg eˣport HKCU out.reg` == `reg export HKCU out.reg`_
16 |
17 | 3) **Character insertion**
18 |
19 | _e.g. `wevtutil gࢯli (…)` == `wevtutil gli (…)`_
20 |
21 | 4) **Quotes insertion**
22 |
23 | _e.g. `netsh ad"vfi"rewall show (…)` == `netsh advfirewall show (…)`_
24 |
25 | 5) **Shorthands**
26 |
27 | _e.g. `powershell /encod (…)` == `powershell /encodedcommand (…)`_
28 |
29 | ## Goals
30 |
31 | Note that the goal of this project is to show that a given executable/command line can be obfuscated, not to give a complete list of possible obfuscations for a given command. It should however be possible to derive different obfuscation opportunities from `analyse_obfuscation`'s output.
32 |
33 | Blue teamers 🔵 may want to use this tool, for example, to check if an executable they have written a detection rule is vulnerable to command-line obfuscation, meaning the rule should be improved or additional rules are needed. Note that in some cases this game is unwinnable - please take a look at the recommendations in the [blog post](https://wietze.github.io/blog/windows-command-line-obfuscation) for suggestions on how to tackle this.
34 |
35 | Red teamers 🔴 may want to use this tool to find opportunities for bypassing simple detection rules.
36 |
37 | ## Usage
38 |
39 | ### Run
40 |
41 | The simplest way to use this project is by running it (without installation).
42 |
43 | * **Run script**: clone the entire repository, install all dependencies (`python3 -m pip install -r requirements.txt`) and run via:
44 |
45 | ```bash
46 | python3 -m analyse_obfuscation.run --help
47 | ```
48 |
49 | ### Install
50 |
51 | By installing the project, it will be possible to simply call `analyse_obfuscation` from the command line.
52 |
53 | * **Via PyPI**: install the application via for example pip:
54 |
55 | ```bash
56 | python3 -m pip install analyse_obfuscation
57 | ```
58 |
59 | * **From source**: you can install a local version of the module by cloning the entire repository, followed by these commands:
60 | (note that this requires `setuptools` to be installed)
61 |
62 | ```bash
63 | python3 setup.py sdist bdist_wheel
64 | python3 -m pip install dist/analyse_obfuscation-*-py3-none-any.whl --upgrade
65 | ```
66 |
67 | ## Examples
68 |
69 | 
70 | _Sample execution output of `analyse_obfuscation`_
71 |
72 | Each execution generates a high-level result overview on the stdout, as can be seen in the screenshot. Additionally a .log file providing examples of commands found to be working is created. Sample report files generated by the below commands can be found in the [sample_results/](sample_results/) folder.
73 |
74 | ```bash
75 | # Check simple 'ping' command
76 | analyse_obfuscation --command "ping /n 1 localhost"
77 |
78 | # Check 'net share' command using {random}, which will be replaced by random string for each execution
79 | analyse_obfuscation --command "net share x=c:\ /remark:{random}"
80 |
81 | # Check 'powershell /encodedcommand' command with increased timeout, as executions tend to take long
82 | analyse_obfuscation --command "powershell /encodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==" --timeout 5
83 |
84 | # Check 'systeminfo' command by only looking at the exit code, not the output - since every output will be different due to (changing) timestamps
85 | analyse_obfuscation --command "systeminfo /s localhost" --timeout 5 --exit_code_only
86 |
87 | # Check all commands as specified in sample.json, saving all reports in 'reports/'
88 | analyse_obfuscation --json_file sample/sample.json --report_dir reports/
89 | ```
90 |
91 | **Note** that the results may contain false positives - especially when single-character command-line options are being tested (such as `/n` in `ping /n 1 localhost`). In such cases, character insertion (method 3) may contain whitespace characters, which doesn't really 'count' as insertion character as whitespaces between command-line arguments are usually filtered out anyway. Similarly, character substitution (method 2) may change the entire option: e.g. `ping /s 1 localhost` and `ping /r 1 localhost` are functionally different, but happen to give the same output.
92 |
93 | ## All options
94 |
95 | All command-line options of this project can be requested by using the `--help` option:
96 |
97 | ```
98 | usage: analyse_obfuscation [--threads n] [--verbose] [--quiet] [--report_dir c:\path\to\dir] [--log_file c:\path\to\file.log] [--help] [--command "proc /arg1 /arg2"]
99 | [--range {full,educated,ascii,custom}] [--custom_range 0x??..0x?? [0x??..0x?? ...]] [--char_offset n] [--pre_command process_name]
100 | [--post_command process_name] [--exit_code_only] [--timeout n] [--json_file c:\path\to\file.jsonl]
101 |
102 | Tool for identifying executables that have command-line options that can be obfuscated.
103 |
104 | required arguments (either is required):
105 | --command "proc /arg1 /arg2"
106 | Single command to test
107 | --json_file c:\path\to\file.jsonl
108 | Path to JSON file (JSON Line formatted) containing commands config
109 |
110 | optional --command arguments:
111 | --range {full,educated,ascii,custom}
112 | Character range to scan (default=educated)
113 | --custom_range 0x??..0x?? [0x??..0x?? ...]
114 | Range to scan
115 | --char_offset n Character position used for insertion and replacement
116 | --pre_command process_name
117 | Command to run unconditionally before each attempt, piping the result to the stdin
118 | --post_command process_name
119 | Command to run unconditionally after each attempt (e.g. to clean up)
120 | --exit_code_only Only base success on the exit code (and not the output of the command)
121 | --timeout n Number of seconds per execution before timing out.
122 |
123 | optional arguments:
124 | --threads n Number of threads to use
125 | --verbose Increase output verbosity
126 | --quiet Decrease output verbosity
127 | --report_dir c:\path\to\dir
128 | Path to save report files to
129 | --log_file c:\path\to\file.log
130 | Path to save log to
131 | --help Show this help message and exit
132 | ```
133 |
134 | ## Repository Contents
135 |
136 | Item|Description
137 | -|-
138 | [analyse_obfuscation/](analyse_obfuscation) | Code for python3 module, enabling one to analyse executables for common command-line obfuscation techniques.
139 | [sample/](sample/) | Sample config file to analyse built-in Windows executables, as well as related input files. Used to generate results in the above folder.
140 | [sample_results/](sample_results/) | Report files generated using the JSONL file in the above sample folder.
141 |
--------------------------------------------------------------------------------
/analyse_obfuscation/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wietze/windows-command-line-obfuscation/dd9c29e82ffc8375e97fabb98971c9c19ca01326/analyse_obfuscation/__init__.py
--------------------------------------------------------------------------------
/analyse_obfuscation/helpers.py:
--------------------------------------------------------------------------------
1 | import enum
2 | import itertools
3 | import logging
4 | from typing import List
5 |
6 | import tqdm
7 |
8 |
9 | class SpecialCharOperation(enum.Enum):
10 | INSERT = 1
11 | REPLACE = 2
12 |
13 |
14 | class TqdmHandler(logging.Handler):
15 | def emit(self, record: logging.LogRecord):
16 | try:
17 | msg = self.format(record)
18 | tqdm.tqdm.write(msg)
19 | self.flush()
20 | except (KeyboardInterrupt, SystemExit):
21 | raise
22 | except:
23 | self.handleError(record)
24 |
25 |
26 | def ranges(i: List[int]) -> str:
27 | """Turns a list of integers to a string representation of the contained ranges"""
28 | result = []
29 | for _, b in itertools.groupby(enumerate(i), lambda pair: pair[1] - pair[0]):
30 | b = list(b)
31 | result.append((b[0][1], b[-1][1]))
32 |
33 | return ' '.join(['0x{:0>4X}..0x{:0>4X}'.format(x, y) for x, y in result])
34 |
--------------------------------------------------------------------------------
/analyse_obfuscation/output_results.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import os
3 | import re
4 | from typing import Dict, List, Set, Tuple, Union
5 |
6 | import colorama
7 | import terminaltables
8 |
9 | from .helpers import ranges
10 |
11 | colorama.init()
12 |
13 |
14 | def print_results(results: Dict[str, Dict[str, Union[Set[Tuple[int, str]], str, None]]]) -> None:
15 | """ For a dict with (test, result_dict), prepare a terminaltables AsciiTable and print to stdout """
16 | matrix = [['Process', 'Option Char', 'Char (insert)', 'Char (replace)', 'Quotes (insert)', 'Shorthands']]
17 | for display_name, test_outcomes in results.items():
18 | matrix.append([display_name] + [parse_outcome(test_outcome) for test_outcome in test_outcomes.values()])
19 |
20 | print(terminaltables.AsciiTable(matrix).table)
21 |
22 |
23 | def parse_outcome(value: Union[Set[Tuple[int, str]], str, None]) -> str:
24 | """Prepare a terminal-printable output based on a given test outcome"""
25 |
26 | if value is None: # If value is None, disregard
27 | return 'N/A'
28 | elif value: # If value is positive, return Yes
29 | return_format = str(colorama.Back.GREEN) + '{}' + str(colorama.Style.RESET_ALL)
30 | if isinstance(value, str): # If result is a string, only output Yes
31 | return return_format.format('Yes')
32 | elif isinstance(value, set): # If result is a list, provide a count as well
33 | return return_format.format('Yes ({})'.format(len(value)))
34 | else:
35 | raise Exception("Unknown result type {}".format(type(value)))
36 | else: # Value is negative, return No
37 | return str(colorama.Back.RED) + 'No' + str(colorama.Style.RESET_ALL)
38 |
39 |
40 | def write_report(report_dir: str, name: str, command: str, char_offset: int, scan_range: List[int], test_outcomes: Dict[str, Union[Set[Tuple[int, str]], str, None]]) -> None:
41 | """Write a report, containing test results, to a given directory"""
42 |
43 | # Prepare output path
44 | file_name = '{}.log'.format(re.sub(r'[\\/*?:"<>|]', "", name))
45 | output_file = os.path.join(report_dir, file_name)
46 |
47 | # Open file
48 | with open(output_file, 'w', encoding='utf-16le') as f:
49 | # Print header
50 | f.write('PROCESS OBFUSCATION REPORT FOR {}\n'.format(name))
51 | f.write('- Generated on {}\n'.format(datetime.datetime.now().isoformat()))
52 | f.write('- Command used : {}\n'.format(command))
53 | f.write('- Insertion position: {}\n'.format((' '*char_offset)+'^'))
54 | f.write('- Char ranges scanned: {}\n'.format(ranges(scan_range)))
55 |
56 | # Dash/hypten test
57 | if 'option_char' in test_outcomes:
58 | f.write('\n:: Option Char Substitution\n')
59 | outcomes = test_outcomes['option_char']
60 | if outcomes is not None:
61 | if outcomes:
62 | f.write('The following {} commands were found to be working:\n'.format(len(outcomes)))
63 | for identifier, command in sorted(outcomes, key=lambda x: x[0]):
64 | f.write('0x{:0>4X} : {}\n'.format(identifier, command))
65 | else:
66 | f.write('No alternative commands were found.\n')
67 | else:
68 | f.write('The command does not contain any arguments starting with a slash or dash.\n')
69 |
70 | # Character insertion test
71 | outcomes = test_outcomes.get('char_insert')
72 | if outcomes is not None:
73 | f.write('\n:: Character Insertion\n')
74 | if outcomes:
75 | f.write('The following {} commands were found to be working:\n'.format(len(outcomes)))
76 | for identifier, command in sorted(outcomes, key=lambda x: x[0]):
77 | try:
78 | f.write('0x{:0>4X} : {}\n'.format(identifier, command))
79 | except:
80 | f.write('0x{:0>4X} : (character can not be printed)\n'.format(identifier))
81 | else:
82 | f.write('No alternative commands were found.\n')
83 |
84 | # Character substitution test
85 | outcomes = test_outcomes.get('char_substitute')
86 | if outcomes is not None:
87 | f.write('\n:: Character Substitution\n')
88 | if outcomes:
89 | f.write('The following commands were found to be working:\n')
90 | for identifier, command in sorted(outcomes, key=lambda x: x[0]):
91 | try:
92 | f.write('0x{:0>4X} : {}\n'.format(identifier, command))
93 | except:
94 | f.write('0x{:0>4X} : (character can not be printed)\n'.format(identifier))
95 | else:
96 | f.write('No alternative commands were found.\n')
97 |
98 | # Quote insertion test
99 | outcome = test_outcomes.get('quotes')
100 | if outcome is not None:
101 | f.write('\n:: Quote Insertion\n')
102 | if outcome:
103 | f.write('Inserting quotes in the first argument did work, such as:\n')
104 | f.write('{}\n'.format(outcome))
105 | else:
106 | f.write('Inserting quotes in the first argument did not appear to be working.\n')
107 |
108 | # Shorthand commands
109 | outcomes = test_outcomes.get('shorthands')
110 | f.write('\n:: Shorthand Commands\n')
111 | if outcomes is not None:
112 | if outcomes:
113 | f.write('The following {} commands were found to be working:\n'.format(len(outcomes)))
114 | for identifier, command in sorted(outcomes, key=lambda x: len(x[1])):
115 | f.write('{}\n'.format(command))
116 | else:
117 | f.write('No alternative commands were found.\n')
118 | else:
119 | f.write('The command is too short to be further shortened.\n')
120 |
--------------------------------------------------------------------------------
/analyse_obfuscation/run.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import json
3 | import logging
4 | import os
5 | import re
6 | import shlex
7 | from argparse import Namespace
8 | from typing import List, Tuple
9 |
10 | import tqdm
11 |
12 | from .helpers import SpecialCharOperation, TqdmHandler
13 | from .output_results import print_results, write_report
14 | from .test_process_obfuscation import TestCase, TestProcessObfuscation
15 |
16 | TESTS = {'option_char': lambda test, test_case: test.check_option_char(test_case.arg_index),
17 | 'char_insert': lambda test, test_case: test.check_special_chars(test_case.char_offset, SpecialCharOperation.INSERT),
18 | 'char_substitute': lambda test, test_case: test.check_special_chars(test_case.char_offset, SpecialCharOperation.REPLACE),
19 | 'quotes': lambda test, test_case: test.check_quote_injection(test_case.arg_index),
20 | 'shorthands': lambda test, test_case: test.check_shortened_option(test_case.arg_index)}
21 |
22 |
23 | def run_tests(test_cases: List[TestCase], threads: int, report_dir: str, log: logging.Logger) -> None:
24 | """ For a list of commands: run tests, create reports, write summary to stdout """
25 | result = {}
26 | with tqdm.tqdm(test_cases, position=0, disable=len(test_cases) <= 1) as pbar:
27 | for test_case in pbar:
28 | # Extract display name
29 | _, display_name = os.path.split(test_case.command[0].strip('"'))
30 | pbar.set_description('Testing {}'.format(display_name))
31 |
32 | try:
33 | # Create test class
34 | test = TestProcessObfuscation(test_case, threads, log)
35 |
36 | # Run individual tests
37 | test_outcomes = dict()
38 | for subtest, function in TESTS.items():
39 | test_outcomes[subtest] = function(test, test_case) if not test_case.tests or subtest in test_case.tests else None
40 |
41 | # Parse results
42 | result[display_name] = test_outcomes
43 |
44 | # Write report
45 | write_report(report_dir, display_name, ' '.join(test_case.command), test_case.char_offset, test_case.scan_range, test_outcomes)
46 | except Exception:
47 | log.error("Unexpected error when executing", exc_info=True)
48 |
49 | # Print results to stdout
50 | print_results(result)
51 |
52 |
53 | def prepare_command(parser: argparse.ArgumentParser, command_flat: str, char_offset: int) -> Tuple[List[str], int, int]:
54 | """ Turns a flattened command string into a list, and generates a character offset in case none was provided """
55 | log.info("Preparing parameters for {}".format(command_flat))
56 | command_list = shlex.split(command_flat, posix=os.sep == '/')
57 | arg_index = -1
58 | if char_offset is not None:
59 | if not (0 <= char_offset and char_offset < len(command_flat)):
60 | parser.error("char offset not within bounds of (0 .. command length)")
61 | else:
62 | selected_char = command_flat[char_offset]
63 | if (0 <= char_offset and char_offset < len(command_list[0])):
64 | parser.error("cannot add characters to process name")
65 | if not re.findall(r'[a-zA-Z0-9]', selected_char):
66 | parser.error("selected char '{}' is not alphanumeric".format(selected_char))
67 |
68 | i = 0
69 | for arg_index, arg in enumerate(command_list):
70 | i += len(arg)
71 | if i > char_offset:
72 | break
73 | else:
74 | # Second char of first argument (not counting process name)
75 | arg_index = TestProcessObfuscation.select_arg_index(command_list, None)
76 | command_part_offset = TestProcessObfuscation.get_command_part_offset(command_list[arg_index].split(':')[0])
77 |
78 | char_offset = len(' '.join(command_list[0:arg_index])) + command_part_offset
79 |
80 | log.info("No char offset specified - using second char of first argument instead")
81 | log.info("Char offset = {} (char '{}', argument index = {})".format(char_offset, command_flat[char_offset], arg_index))
82 | return (command_list, char_offset, arg_index)
83 |
84 |
85 | def create_test_case(args: Namespace, parser: argparse.ArgumentParser, json_file: bool) -> TestCase:
86 | """Generates a TestCase object based on the given arguments (either on the command line or in the JSON file)"""
87 |
88 | command = None
89 | if args.command:
90 | command, char_offset, arg_index = prepare_command(parser, args.command, args.char_offset)
91 | else:
92 | raise ValueError("'--command' is required" if not json_file else "'command' should be specified")
93 |
94 | # Parse char scan range options
95 | scan_range = None
96 |
97 | if args.custom_range:
98 | if (args.range is None or args.range == 'custom'):
99 | scan_range = sum(args.custom_range, [])
100 | if 0 in scan_range:
101 | parser.error("null bytes can not be included in custom ranges. Try starting from 1 instead.")
102 | else:
103 | raise ValueError("--custom_range can not be set when --range is not set to 'custom'.")
104 | elif args.range is None or args.range == 'educated':
105 | scan_range = list(range(0x01, 0xFF)) + list(range(0x0100, 0x052F)) + list(range(0x2070, 0x218F)) + list(range(0xFF00, 0xFFEF))
106 | elif args.range == 'full':
107 | scan_range = list(range(0x01, 0xFFFF))
108 | elif args.range == 'ascii':
109 | scan_range = list(range(0x01, 0xFF))
110 | else:
111 | raise ValueError("Unexpected range '{}'".format(args.range))
112 |
113 | log.info('{} range selected ({} values)'.format(args.range, len(scan_range)))
114 |
115 | # Parse report output dir
116 | log.info('Report files will be stored in {}'.format(os.path.abspath(args.report_dir)))
117 | if not os.path.isdir(args.report_dir):
118 | parser.error("path specified in --report_dir does not exist.")
119 |
120 | return TestCase(command=command, char_offset=char_offset, arg_index=arg_index, scan_range=scan_range, pre_command=args.pre_command, post_command=args.post_command, exit_code_only=args.exit_code_only, timeout=args.timeout, tests=args.tests)
121 |
122 |
123 | # Prepare logger
124 | log = logging.getLogger(__name__)
125 | log.setLevel(logging.DEBUG)
126 |
127 |
128 | def parse_arguments() -> None:
129 | # Prepare arguments
130 | parser = argparse.ArgumentParser(add_help=False, description='Tool for identifying executables that have command-line options that can be obfuscated.')
131 |
132 | parser._action_groups.pop()
133 | required = parser.add_argument_group('required arguments (either is required)')
134 | optional_c = parser.add_argument_group('optional --command arguments')
135 | optional = parser.add_argument_group('optional arguments')
136 |
137 | # Global settings
138 | optional.add_argument('--threads', metavar='n', type=int, help='Number of threads to use', default=None)
139 | optional.add_argument('--verbose', action='store_true', help='Increase output verbosity')
140 | optional.add_argument('--quiet', action='store_true', help='Decrease output verbosity')
141 | optional.add_argument('--report_dir', metavar='c:\\path\\to\\dir', type=str, help='Path to save report files to', default="."+os.sep)
142 | optional.add_argument('--log_file', metavar='c:\\path\\to\\file.log', type=str, help='Path to save log to')
143 | optional.add_argument('--help', action='help', default=argparse.SUPPRESS, help='Show this help message and exit')
144 |
145 | # Single command options
146 | required.add_argument('--command', metavar='"proc /arg1 /arg2"', type=str, help='Single command to test')
147 | optional_c.add_argument('--range', choices=['full', 'educated', 'ascii', 'custom'], help='Character range to scan (default=educated)')
148 | optional_c.add_argument('--custom_range', metavar='0x??..0x??', type=lambda x: list(range(int(x.split('..')[0], 0), int(x.split('..')[1], 0))), nargs='+', help='Range to scan')
149 | optional_c.add_argument('--char_offset', metavar='n', type=int, help='Character position used for insertion and replacement')
150 | optional_c.add_argument('--pre_command', metavar='process_name', type=str, help='Command to run unconditionally before each attempt, piping the result to the stdin')
151 | optional_c.add_argument('--post_command', metavar='process_name', type=str, help='Command to run unconditionally after each attempt (e.g. to clean up)')
152 | optional_c.add_argument('--exit_code_only', action='store_true', help='Only base success on the exit code (and not the output of the command)')
153 | optional_c.add_argument('--timeout', metavar='n', type=float, help='Number of seconds per execution before timing out.', default=2)
154 | optional_c.add_argument('--tests', choices=list(TESTS.keys()), type=str, nargs='+', help='Number of seconds per execution before timing out.', default=None)
155 |
156 | # JSON File options
157 | required.add_argument('--json_file', metavar='c:\\path\\to\\file.jsonl', type=str, help='Path to JSON file (JSON Line formatted) containing commands config')
158 |
159 | args = parser.parse_args()
160 |
161 | tests = []
162 |
163 | # Parse verbosity options
164 | stream_handler = TqdmHandler()
165 | stream_handler.setFormatter(logging.Formatter("[%(levelname)-.4s] %(message)s"))
166 | if args.verbose:
167 | stream_handler.setLevel(logging.DEBUG)
168 | elif args.quiet:
169 | stream_handler.setLevel(logging.ERROR)
170 | else:
171 | stream_handler.setLevel(logging.WARNING)
172 | log.addHandler(stream_handler)
173 |
174 | # Parse log file options
175 | if args.log_file:
176 | file_path = os.path.abspath(args.log_file)
177 | file_handler = logging.FileHandler(file_path, 'w', encoding='utf-16le')
178 | file_handler.setLevel(logging.DEBUG)
179 | file_handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)-.4s] (%(threadName)-10s) %(message)s'))
180 | log.addHandler(file_handler)
181 |
182 | if args.json_file:
183 | single_command_args = ['command', 'range', 'custom_range', 'char_offset', 'pre_command', 'post_command', 'exit_code_only', 'tests']
184 | given_args = {key: value for (key, value) in args._get_kwargs()}
185 | if any([given_args[x] for x in single_command_args]):
186 | raise ValueError("When --json_file is specified, the following arguments should not be specified on the command line but in the JSON file: {}".format(', '.join(single_command_args)))
187 |
188 | with open(args.json_file, 'rt') as f:
189 | for line in f.readlines():
190 | if not line.strip():
191 | continue
192 | t_args = argparse.Namespace()
193 | t_args.__dict__.update(json.loads(line))
194 | args = parser.parse_args(namespace=t_args)
195 | tests.append(create_test_case(args, parser, True))
196 | else:
197 | tests = [create_test_case(args, parser, False)]
198 |
199 | run_tests(tests, threads=args.threads, report_dir=args.report_dir, log=log)
200 |
201 |
202 | if __name__ == "__main__":
203 | parse_arguments()
204 |
--------------------------------------------------------------------------------
/analyse_obfuscation/test_process_obfuscation.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import os
3 | import random
4 | import re
5 | import shlex
6 | import subprocess
7 | from multiprocessing.pool import ThreadPool
8 | from typing import List, Set, Tuple, Union
9 |
10 | import tqdm
11 |
12 | from .helpers import SpecialCharOperation
13 |
14 |
15 | class TestCase():
16 | def __init__(self, command: List[str], char_offset: int, arg_index: int, scan_range: List[int], pre_command: List[str], post_command: List[str], exit_code_only: bool, timeout: int, tests:List[str]):
17 | self.command = command
18 | self.char_offset = char_offset
19 | self.arg_index = arg_index
20 | self.scan_range = scan_range
21 | self.pre_command = pre_command
22 | self.post_command = post_command
23 | self.exit_code_only = exit_code_only
24 | self.timeout = timeout
25 | self.tests = tests
26 |
27 |
28 | class TestProcessObfuscation():
29 | def __init__(self, test_case: TestCase, threads: int, log: logging.Logger):
30 | self.log = log
31 | self.command = test_case.command
32 | self.command_flat = ' '.join(test_case.command)
33 | self.pre_command = test_case.pre_command
34 | self.post_command = test_case.post_command
35 | self.expected_code, self.expected_output = self.__get_expected_result__()
36 | self.exit_code_only = test_case.exit_code_only
37 | self.scan_range = test_case.scan_range
38 | self.timeout = test_case.timeout
39 | self.threads = threads
40 | self.tqdm = None
41 |
42 | # Class Methods
43 | @classmethod
44 | def __randomise__(cls, command_parts: str) -> str:
45 | randomised = ''.join(random.choices('0123456789ABCDEF', k=10))
46 | return command_parts.replace('{random}', randomised)
47 |
48 | @classmethod
49 | def select_arg_index(cls, command: List[str], arg_index: Union[int, None]) -> int:
50 | # Iterate over command-line arguments
51 | for i, command_part in enumerate(command):
52 | # The first argument will be the process, so ignore
53 | if i == 0 or (arg_index is not None and i != arg_index):
54 | continue
55 | # Check if the first character is a slash or hyphen - if so, select it
56 | if command_part[0] in ['/', '-']:
57 | return i
58 | # If no option char was found, fall back to the first argument
59 | # (least likely to be something like a filename)
60 | return 1
61 |
62 | @classmethod
63 | def get_command_part_offset(cls, command_part: str) -> int:
64 | # We prefer the below chars, because they have 'equivalents' in the Spacing Modifier Letters range (0x02B0 - 0x02FF)
65 | preferred_chars = 'hjrwyxsl'
66 | # Iterate over each char in the given command-line optoin
67 | for i, char in enumerate(command_part.lower()):
68 | # Ignore the first one - it will either be an option char, or
69 | # the first char of a keyword which is usually not the best candidate
70 | if i == 0:
71 | continue
72 | if any([char == preferred_char for preferred_char in preferred_chars]):
73 | return i+1
74 |
75 | return (2 if command_part[1] != '-' else 3) if len(command_part) > 1 else 1
76 |
77 | def __get_expected_result__(self) -> Tuple[int, str]:
78 | # Prepare command to run
79 | command = self.__randomise__(self.command_flat)
80 | # Run 'normal' command to get expected exit code
81 | try:
82 | result = self.__execute_command__(command, pre_command=self.pre_command)
83 | exit_code, stdout = result.returncode, "{} / {}".format(result.stdout, result.stderr)
84 | # Check if observed exit code is 0
85 | if exit_code != 0:
86 | self.log.warning("Observed exit code is {}, which is not 0 as usual".format(exit_code))
87 | self.log.warning("Test outcome may contain unexpected results")
88 | self.log.warning(stdout)
89 | # sys.exit(-1)
90 | except FileNotFoundError:
91 | self.log.error("Command \"{}\" could not be executed: file not found".format(command))
92 | raise
93 | return exit_code, stdout
94 |
95 | # Private Methods
96 | def __test_commands__(self, test: str, commands: List[Tuple[int, str]]) -> Set[Tuple[int, str]]:
97 | self.log.info('Preparing {} commands to run'.format(len(commands)))
98 | # Prepare ThreadPool
99 | with ThreadPool(self.threads) as thread_pool:
100 | # Prepare progress bar
101 | with tqdm.tqdm(total=len(commands), desc=test, position=1, leave=False) as self.tqdm:
102 | # Submit all commands to ThreadPool, collect results
103 | outcomes = list(thread_pool.map(self.__run_command__, [command for _, command in commands]))
104 | # Return all results when output was True
105 | return set([(identifier, command) for outcome, (identifier, command) in zip(outcomes, commands) if outcome])
106 |
107 | def __run_command__(self, command: str):
108 | # Prepare command
109 | command = self.__randomise__(command)
110 | # self.log.info('About to run command "{}"'.format(shlex.split(command, posix=False)))
111 | try:
112 | # Run command
113 | result = self.__execute_command__(command, timeout=self.timeout, pre_command=self.pre_command)
114 | exit_code, stdout = result.returncode, "{} / {}".format(result.stdout, result.stderr)
115 | self.log.info('Exit code {} observed ({} desired) for {}'.format(exit_code, self.expected_code, command))
116 | # Return result
117 | return exit_code == self.expected_code and (self.exit_code_only or stdout == self.expected_output)
118 | except subprocess.TimeoutExpired:
119 | self.log.warning('Timeout ({}s) elapsed for command "{}"'.format(self.timeout, command))
120 | return False
121 | except Exception as e:
122 | self.log.info("Exception when executing \"{}\": {}".format(command, e))
123 | return False
124 | finally:
125 | if self.post_command:
126 | result = None
127 | try:
128 | result = self.__execute_command__(self.post_command)
129 | except Exception as e:
130 | self.log.warning("Post command caused exception ({})".format(e))
131 | finally:
132 | self.log.info("Post command exited with exit code {}".format(result.returncode if result else "?"))
133 | if self.tqdm:
134 | self.tqdm.update()
135 |
136 | def __get_option_argument__(self, arg_index: int) -> int:
137 | return self.select_arg_index(self.command, arg_index)
138 |
139 | def __execute_command__(self, command: str, timeout: int = None, pre_command: list[str] = []) -> subprocess.CompletedProcess:
140 | cmd = command.split(' ') # list(shlex.shlex(command, punctuation_chars=True, posix=True)) #[shlex.quote(c) for c in shlex.split(command, posix=True)]
141 | # self.log.debug('About to run command "{}"'.format(' '.join(cmd)))
142 | p1 = subprocess.Popen(shlex.split(pre_command, posix=True) if os.sep == '/' else pre_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE) if pre_command else None
143 | return subprocess.run(cmd if os.sep == '/' else command, stdin=p1.stdout if p1 else None, capture_output=True, timeout=timeout)
144 |
145 | # Public Methods
146 | def check_special_chars(self, char_at_position: int, operation: SpecialCharOperation) -> Set[Tuple[int, str]]:
147 | # Prepare operation
148 | op = None
149 | if operation == SpecialCharOperation.INSERT:
150 | op = "insert"
151 | command_parts = self.command_flat[:char_at_position+1], self.command_flat[char_at_position+1:]
152 | elif operation == SpecialCharOperation.REPLACE:
153 | op = "replace"
154 | command_parts = self.command_flat[:char_at_position], self.command_flat[char_at_position+1:]
155 | else:
156 | raise ValueError('Unexpected operation {}'.format(operation))
157 | self.log.info("Starting 'special chars ({})' test".format(op))
158 | # Prepare commands to run (excluding 'original' command)
159 | new_commands = [(ordinal, chr(ordinal).join(command_parts)) for ordinal in self.scan_range if operation != SpecialCharOperation.REPLACE or chr(ordinal).lower() != self.command_flat[char_at_position].lower()]
160 | # Run commands, return results
161 | return self.__test_commands__("Special chars ({})".format(op), new_commands)
162 |
163 | def check_quote_injection(self, arg_index: int) -> Union[str, None]:
164 | self.log.info("Starting 'quote insertion' test")
165 | # Check if valid command was given
166 | if not self.command or len(self.command) < 2:
167 | return None
168 | # Simply add quotes between 0,1 and 1,2 of first argument - e.g. net s"t"art
169 | command_part = self.__get_option_argument__(arg_index)
170 | quote = '"' # if os.sep != '/' else '\\"'
171 | test_arg = self.command[command_part][:1] + quote + self.command[command_part][1] + quote + self.command[command_part][2:]
172 | new_command = ' '.join(self.command[:command_part] + [test_arg] + self.command[command_part+1:])
173 | # Quotes don't work in subprocess when using lists
174 | result = self.__run_command__(new_command)
175 | # Return command if working, blank string if not
176 | return new_command if result else ''
177 |
178 | def check_shortened_option(self, arg_index: int) -> Union[None, Set[Tuple[int, str]]]:
179 | self.log.info("Starting 'shortened option' test")
180 | # Check if valid command was given
181 | if not self.command or len(self.command) < 2:
182 | raise ValueError('Unexpected length {}'.format(len(self.command)))
183 | # Shorten the second argument by [1..len(command)-1] chars
184 | selected_command_part_index = self.__get_option_argument__(arg_index)
185 | selected_command_part = self.command[selected_command_part_index]
186 | new_commands = []
187 | # check if there are any colons or equal signs in there (e.g. /active:true)
188 | selected_command_part_split = list(filter(None, re.split("[:=]", selected_command_part)))
189 | if len(selected_command_part_split) > 1:
190 | # If so, only try to shorten the first bit - leave the argument intact (e.g. /activ:true.../a:true)
191 | size = len(selected_command_part_split[0])
192 | # Check if argument is long enough
193 | if size <= 2:
194 | self.log.info("Length of selected command-line option is {}, cannot be further shortened".format(size))
195 | return None
196 | for i in range(size-1):
197 | test_arg = selected_command_part[0:(i+1)] + selected_command_part[size:]
198 | new_commands.append((i, ' '.join(self.command[:selected_command_part_index] + [test_arg] + self.command[(selected_command_part_index+1):])))
199 | else:
200 | # If not, just shorten the full argument
201 | size = len(selected_command_part)
202 | # Check if argument is long enough
203 | if size <= 2:
204 | self.log.info("Length of selected command-line option is {}, cannot be further shortened".format(size))
205 | return None
206 | for i in range(size-1):
207 | test_arg = selected_command_part[0:(i+1)]
208 | new_commands.append((i, ' '.join(self.command[:selected_command_part_index] + [test_arg] + self.command[(selected_command_part_index+1):])))
209 | # Return results of commands if any were generated, None if not
210 | return self.__test_commands__("Shorthand command", new_commands) if new_commands else None
211 |
212 | def check_option_char(self, arg_index_start: int = 1) -> Union[None, Set[Tuple[int, str]]]:
213 | self.log.info("Starting 'option char subtitution' test")
214 |
215 | delimiters_alternative = ['/', '\\', '\u2215', '\u244a', '\u2044', '\u29F8', '\u002D', '\u007E', '\u00AD', '\u058A', '\u05BE', '\u1400', '\u1806', '\u2010', '\u2010', '\u2012', '\u2013', '\u2014', '\u2015', '\u2053', '\u2212', '\u2212', '\u2212', '\u2E17', '\u2E3A', '\u2E3B', '\u301C', '\u3030', '\u30A0', '\uFE31', '\uFE32', '\uFE58', '\uFE63', '\uFF0D']
216 | delimiters_standard = ['/', '-']
217 | self.log.info("Looking for arguments starting with one of: {}".format(' '.join(delimiters_standard)))
218 |
219 | # Iterate over command-line arguments
220 | for i, command in enumerate(self.command[arg_index_start:], start=arg_index_start):
221 | # Check if delimiter is present
222 | if any([command.startswith(delimiter) for delimiter in delimiters_standard]):
223 | # If so, find its position
224 | pos = sum([len(c)+1 for c in self.command[:i]])
225 | # Break command in two parts
226 | command_parts = self.command_flat[:pos], self.command_flat[pos+1:]
227 | self.log.info("Argument found ({})".format(command))
228 | self.log.info("Preparing {} alternative signs to test".format(len(delimiters_alternative)))
229 | break
230 | else:
231 | self.log.info("No arguments found")
232 | return None # No option char found
233 |
234 | # Prepare commands to test
235 | new_commands = [(ord(char), char.join(command_parts)) for char in delimiters_alternative]
236 | return self.__test_commands__("Dash/hyphen", [command for command in new_commands if command[1] != self.command_flat])
237 |
--------------------------------------------------------------------------------
/docs/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wietze/windows-command-line-obfuscation/dd9c29e82ffc8375e97fabb98971c9c19ca01326/docs/screenshot.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | colorama
2 | terminaltables
3 | tqdm
4 |
--------------------------------------------------------------------------------
/sample/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wietze/windows-command-line-obfuscation/dd9c29e82ffc8375e97fabb98971c9c19ca01326/sample/.keep
--------------------------------------------------------------------------------
/sample/inputs/file.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ConsoleApp1
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | Console.WriteLine("Hello, world!");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/sample/inputs/file.sct:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/sample/inputs/file.vbs:
--------------------------------------------------------------------------------
1 | Module HelloWorld
2 | ' every console app starts with Main
3 | Sub Main( )
4 | System.Console.WriteLine("Hello World")
5 | End Sub
6 | End Module
--------------------------------------------------------------------------------
/sample/inputs/sleep.vbs:
--------------------------------------------------------------------------------
1 | WScript.Sleep 500
--------------------------------------------------------------------------------
/sample/inputs/x86.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wietze/windows-command-line-obfuscation/dd9c29e82ffc8375e97fabb98971c9c19ca01326/sample/inputs/x86.dll
--------------------------------------------------------------------------------
/sample/sample.jsonl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {"command": "\"C:\\Program Files\\Windows Defender\\MpCmdRun.exe\" -RemoveDefinitions -All", "range": "full", "elevated": true}
5 | {"command": "arp -a", "range": "full"}
6 | {"command": "at 12:34 /interactive cmd", "range": "full"}
7 | {"command": "bitsadmin /transfer xy https://duckduckgo.com/robots.txt c:\\windows\\temp\\robots.txt", "timeout": 5, "exit_code_only": true, "range": "full", "elevated": true}
8 | {"command": "C:\\windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe -out:cache\\file.exe inputs\\file.cs", "char_offset": 59, "range": "full"}
9 | {"command": "c:\\windows\\Microsoft.NET\\Framework64\\v4.0.30319\\jsc.exe /target:exe /out:cache\\file.exe inputs\\file.js", "range": "full"}
10 | {"command": "c:\\windows\\Microsoft.NET\\Framework64\\v4.0.30319\\vbc.exe /target:exe /out:cache\\file.exe inputs\\file.vbs", "range": "full"}
11 | {"command": "certutil -split -urlcache -f https://www.bing.com/robots.txt cache\\{random}.txt", "range": "full"}
12 | {"command": "cmdkey /list", "range": "full"}
13 | {"command": "cmstp.exe /s c:\\windows\\temp\\cmstp.inf", "range": "educated"}
14 | {"command": "curl -N https://www.google.com/robots.txt -r 0-16", "range": "full"}
15 | {"command": "findstr /offline \"findstr\" \"*.json\"", "range": "full"}
16 | {"command": "fltmc.exe filters", "range": "full"}
17 | {"command": "forfiles /P c:\\windows\\ /M *.bin /c \"cmd /c echo hi\"", "range": "full"}
18 | {"command": "ipconfig /displaydns", "range": "full"}
19 | {"command": "nbtstat -n", "range": "full"}
20 | {"command": "net share x=c:\\ /remark:{random}", "post_command": "net share /delete x", "range": "full"}
21 | {"command": "netsh advfirewall show currentprofile state", "range": "full"}
22 | {"command": "netstat -p UDPv6", "range": "full"}
23 | {"command": "nltest /domain_trusts", "range": "full"}
24 | {"command": "nslookup -querytype=ALL -timeout=10 _ldap._tcp.dc._msdcs.WORKGROUP", "range": "full"}
25 | {"command": "ping /n 1 localhost", "range": "full"}
26 | {"command": "powershell /encodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==", "timeout": 5, "range": "educated", "comment": "Too slow for 'full' range"}
27 | {"command": "query process /id:123", "range": "full"}
28 | {"command": "qwinsta /mode", "range": "full"}
29 | {"command": "reg export HKCU\\SOFTWARE\\Microsoft\\accessibility cache\\out.reg /y", "range": "full"}
30 | {"command": "regsvr32 /s /u /i:inputs\\file.sct scrobj.dll", "char_offset":13, "range": "educated", "comment": "Special case - look at the generated file `inputs\\results.txt` to see the commands that worked."}
31 | {"command": "route print 123*", "range": "full"}
32 | {"command": "sc query eventlog", "range": "full"}
33 | {"command": "schtasks /showsid /TN \"\\Microsoft\\XblGameSave\\XblGameSaveTask\"", "range": "full"}
34 | {"command": "systeminfo /s localhost", "timeout": 5, "exit_code_only": true, "range": "full"}
35 | {"command": "takeown /F config.json", "range": "full"}
36 | {"command": "taskkill /im test.exe", "range": "full"}
37 | {"command": "tasklist /fi \"USERNAME eq test\"", "timeout": 5, "range": "full"}
38 | {"command": "wevtutil gli HardwareEvents", "exit_code_only": true, "range": "full"}
39 | {"command": "winrs -remote:localhost echo hello", "range": "full", "elevated": true}
40 | {"command": "wmic os get BuildNumber", "range": "full"}
41 |
--------------------------------------------------------------------------------
/sample_results/arp.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR arp
2 | - Generated on 2021-01-02T14:08:31.751740
3 | - Command used : arp -a
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 8 commands were found to be working:
9 | 0x002F : arp /a
10 | 0x2010 : arp ‐a
11 | 0x2012 : arp ‒a
12 | 0x2015 : arp ―a
13 | 0x2044 : arp ⁄a
14 | 0x2212 : arp −a
15 | 0x2215 : arp ∕a
16 | 0xFF0D : arp -a
17 |
18 | :: Character Insertion
19 | The following 67 commands were found to be working:
20 | 0x0022 : arp -"a
21 | 0x0041 : arp -Aa
22 | 0x0044 : arp -Da
23 | 0x0047 : arp -Ga
24 | 0x0053 : arp -Sa
25 | 0x0061 : arp -aa
26 | 0x0064 : arp -da
27 | 0x0067 : arp -ga
28 | 0x0073 : arp -sa
29 | 0x00A0 : arp - a
30 | 0x0100 : arp -Āa
31 | 0x0101 : arp -āa
32 | 0x0102 : arp -Ăa
33 | 0x0103 : arp -ăa
34 | 0x0104 : arp -Ąa
35 | 0x0105 : arp -ąa
36 | 0x010E : arp -Ďa
37 | 0x010F : arp -ďa
38 | 0x0111 : arp -đa
39 | 0x011C : arp -Ĝa
40 | 0x011D : arp -ĝa
41 | 0x011E : arp -Ğa
42 | 0x011F : arp -ğa
43 | 0x0120 : arp -Ġa
44 | 0x0121 : arp -ġa
45 | 0x0122 : arp -Ģa
46 | 0x0123 : arp -ģa
47 | 0x015A : arp -Śa
48 | 0x015B : arp -śa
49 | 0x015C : arp -Ŝa
50 | 0x015D : arp -ŝa
51 | 0x015E : arp -Şa
52 | 0x015F : arp -şa
53 | 0x0191 : arp -Ƒa
54 | 0x0192 : arp -ƒa
55 | 0x01CD : arp -Ǎa
56 | 0x01CE : arp -ǎa
57 | 0x01DE : arp -Ǟa
58 | 0x01DF : arp -ǟa
59 | 0x01E4 : arp -Ǥa
60 | 0x01E5 : arp -ǥa
61 | 0x01E6 : arp -Ǧa
62 | 0x01E7 : arp -ǧa
63 | 0x0261 : arp -ɡa
64 | 0x02BA : arp -ʺa
65 | 0x030E : arp -̎a
66 | 0x0393 : arp -Γa
67 | 0x03A3 : arp -Σa
68 | 0x03B1 : arp -αa
69 | 0x03B4 : arp -δa
70 | 0x03C3 : arp -σa
71 | 0x2007 : arp - a
72 | 0x201F : arp -‟a
73 | 0x2026 : arp -…a
74 | 0x202F : arp - a
75 | 0x2033 : arp -″a
76 | 0x2036 : arp -‶a
77 | 0x210A : arp -ℊa
78 | 0xFF02 : arp -"a
79 | 0xFF21 : arp -Aa
80 | 0xFF24 : arp -Da
81 | 0xFF27 : arp -Ga
82 | 0xFF33 : arp -Sa
83 | 0xFF41 : arp -aa
84 | 0xFF44 : arp -da
85 | 0xFF47 : arp -ga
86 | 0xFF53 : arp -sa
87 |
88 | :: Character Substitution
89 | The following commands were found to be working:
90 | 0x0047 : arp -G
91 | 0x0067 : arp -g
92 | 0x00A0 : arp -
93 | 0x0100 : arp -Ā
94 | 0x0101 : arp -ā
95 | 0x0102 : arp -Ă
96 | 0x0103 : arp -ă
97 | 0x0104 : arp -Ą
98 | 0x0105 : arp -ą
99 | 0x011C : arp -Ĝ
100 | 0x011D : arp -ĝ
101 | 0x011E : arp -Ğ
102 | 0x011F : arp -ğ
103 | 0x0120 : arp -Ġ
104 | 0x0121 : arp -ġ
105 | 0x0122 : arp -Ģ
106 | 0x0123 : arp -ģ
107 | 0x0191 : arp -Ƒ
108 | 0x0192 : arp -ƒ
109 | 0x01CD : arp -Ǎ
110 | 0x01CE : arp -ǎ
111 | 0x01DE : arp -Ǟ
112 | 0x01DF : arp -ǟ
113 | 0x01E4 : arp -Ǥ
114 | 0x01E5 : arp -ǥ
115 | 0x01E6 : arp -Ǧ
116 | 0x01E7 : arp -ǧ
117 | 0x0261 : arp -ɡ
118 | 0x0393 : arp -Γ
119 | 0x03B1 : arp -α
120 | 0x2007 : arp -
121 | 0x2026 : arp -…
122 | 0x202F : arp -
123 | 0x210A : arp -ℊ
124 | 0xFF21 : arp -A
125 | 0xFF27 : arp -G
126 | 0xFF41 : arp -a
127 | 0xFF47 : arp -g
128 |
129 | :: Quote Insertion
130 | Inserting quotes in the first argument did work, such as:
131 | arp -"a"
132 |
133 | :: Shorthand Commands
134 | No alternative commands were found.
135 |
--------------------------------------------------------------------------------
/sample_results/at.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR at
2 | - Generated on 2021-01-02T21:06:28.538054
3 | - Command used : at 12:34 /interactive cmd
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | No alternative commands were found.
9 |
10 | :: Character Insertion
11 | The following 2 commands were found to be working:
12 | 0x0009 : at 12:34 /inter active cmd
13 | 0x0020 : at 12:34 /inter active cmd
14 |
15 | :: Character Substitution
16 | The following commands were found to be working:
17 | 0x0009 : at 12:34 /inte active cmd
18 | 0x0020 : at 12:34 /inte active cmd
19 |
20 | :: Quote Insertion
21 | Inserting quotes in the first argument did work, such as:
22 | at 12:34 /"i"nteractive cmd
23 |
24 | :: Shorthand Commands
25 | The following 10 commands were found to be working:
26 | at 12:34 /i cmd
27 | at 12:34 /in cmd
28 | at 12:34 /int cmd
29 | at 12:34 /inte cmd
30 | at 12:34 /inter cmd
31 | at 12:34 /intera cmd
32 | at 12:34 /interac cmd
33 | at 12:34 /interact cmd
34 | at 12:34 /interacti cmd
35 | at 12:34 /interactiv cmd
36 |
--------------------------------------------------------------------------------
/sample_results/bitsadmin.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR bitsadmin
2 | - Generated on 2021-01-02T18:20:46.580663
3 | - Command used : bitsadmin /transfer xy https://duckduckgo.com/robots.txt c:\windows\temp\robots.txt
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | No alternative commands were found.
9 |
10 | :: Character Insertion
11 | No alternative commands were found.
12 |
13 | :: Character Substitution
14 | No alternative commands were found.
15 |
16 | :: Quote Insertion
17 | Inserting quotes in the first argument did work, such as:
18 | bitsadmin /"t"ransfer xy https://duckduckgo.com/robots.txt c:\windows\temp\robots.txt
19 |
20 | :: Shorthand Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/cmdkey.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR cmdkey
2 | - Generated on 2021-01-02T17:21:35.364722
3 | - Command used : cmdkey /list
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 1 commands were found to be working:
9 | 0x002D : cmdkey -list
10 |
11 | :: Character Insertion
12 | The following 2 commands were found to be working:
13 | 0x004C : cmdkey /Llist
14 | 0x006C : cmdkey /llist
15 |
16 | :: Character Substitution
17 | No alternative commands were found.
18 |
19 | :: Quote Insertion
20 | Inserting quotes in the first argument did not appear to be working.
21 |
22 | :: Shorthand Commands
23 | The following 3 commands were found to be working:
24 | cmdkey /l
25 | cmdkey /li
26 | cmdkey /lis
27 |
--------------------------------------------------------------------------------
/sample_results/cmstp.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR cmstp.exe
2 | - Generated on 2020-12-03T21:53:50.349533
3 | - Command used : cmstp.exe /s c:\users\wietze\downloads\cmstp.inf
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0x00FE 0x02B0..0x02FE 0x2070..0x209E
6 |
7 | :: Character Insertion
8 | The following 3 commands were found to be working:
9 | 0x2072 : cmstp.exe /s c:\users\wietze\downloads\cmstp.inf
10 | 0x2073 : cmstp.exe /s c:\users\wietze\downloads\cmstp.inf
11 | 0x209D : cmstp.exe /s c:\users\wietze\downloads\cmstp.inf
12 |
13 | :: Character Substitution
14 | The following commands were found to be working:
15 | 0x0049 : cmstp.exe /I c:\users\wietze\downloads\cmstp.inf
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did not appear to be working.
19 |
20 | :: Shorthand Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/csc.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR csc.exe
2 | - Generated on 2020-11-28T22:27:16.668663
3 | - Command used : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe -out:My.exe inputs\file.cs
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The following 1 commands were found to be working:
9 | 0x002F : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /out:My.exe inputs\file.cs
10 |
11 | :: Character Insertion
12 | No alternative commands were found.
13 |
14 | :: Character Replacement
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did not appear to be working.
19 |
20 | :: Shortened Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/curl.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR curl
2 | - Generated on 2021-01-04T02:00:40.003795
3 | - Command used : curl -N https://www.google.com/robots.txt -r 0-16
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | No alternative commands were found.
9 |
10 | :: Character Insertion
11 | The following 12 commands were found to be working:
12 | 0x004C : curl -NL https://www.google.com/robots.txt -r 0-16
13 | 0x0070 : curl -Np https://www.google.com/robots.txt -r 0-16
14 | 0x011D : curl -Nĝ https://www.google.com/robots.txt -r 0-16
15 | 0x0144 : curl -Nń https://www.google.com/robots.txt -r 0-16
16 | 0x0146 : curl -Nņ https://www.google.com/robots.txt -r 0-16
17 | 0x0154 : curl -NŔ https://www.google.com/robots.txt -r 0-16
18 | 0x019A : curl -Nƚ https://www.google.com/robots.txt -r 0-16
19 | 0x01E7 : curl -Nǧ https://www.google.com/robots.txt -r 0-16
20 | 0x01F0 : curl -Nǰ https://www.google.com/robots.txt -r 0-16
21 | 0x2009 : curl -N https://www.google.com/robots.txt -r 0-16
22 | 0xFF41 : curl -Na https://www.google.com/robots.txt -r 0-16
23 | 0xFF46 : curl -Nf https://www.google.com/robots.txt -r 0-16
24 |
25 | :: Character Substitution
26 | The following commands were found to be working:
27 | 0x011E : curl -Ğ https://www.google.com/robots.txt -r 0-16
28 | 0x0139 : curl -Ĺ https://www.google.com/robots.txt -r 0-16
29 | 0x0143 : curl -Ń https://www.google.com/robots.txt -r 0-16
30 | 0x0144 : curl -ń https://www.google.com/robots.txt -r 0-16
31 | 0x01E4 : curl -Ǥ https://www.google.com/robots.txt -r 0-16
32 | 0x210A : curl -ℊ https://www.google.com/robots.txt -r 0-16
33 | 0x2112 : curl -ℒ https://www.google.com/robots.txt -r 0-16
34 | 0x211D : curl -ℝ https://www.google.com/robots.txt -r 0-16
35 | 0xFF11 : curl -1 https://www.google.com/robots.txt -r 0-16
36 |
37 | :: Quote Insertion
38 | Inserting quotes in the first argument did not appear to be working.
39 |
40 | :: Shorthand Commands
41 | No alternative commands were found.
42 |
--------------------------------------------------------------------------------
/sample_results/findstr.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR findstr
2 | - Generated on 2020-11-30T15:00:17.278099
3 | - Command used : findstr /offline "findstr" "*.json"
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The following 11 commands were found to be working:
9 | 0x002D : findstr -offline "findstr" "*.json"
10 | 0x00AD : findstr offline "findstr" "*.json"
11 | 0x2010 : findstr ‐offline "findstr" "*.json"
12 | 0x2012 : findstr ‒offline "findstr" "*.json"
13 | 0x2013 : findstr –offline "findstr" "*.json"
14 | 0x2014 : findstr —offline "findstr" "*.json"
15 | 0x2015 : findstr ―offline "findstr" "*.json"
16 | 0x2044 : findstr ⁄offline "findstr" "*.json"
17 | 0x2212 : findstr −offline "findstr" "*.json"
18 | 0x2215 : findstr ∕offline "findstr" "*.json"
19 | 0xFF0D : findstr -offline "findstr" "*.json"
20 |
21 | :: Character Insertion
22 | No alternative commands were found.
23 |
24 | :: Character Replacement
25 | The following commands were found to be working:
26 | 0x0139 : findstr /offĹine "findstr" "*.json"
27 | 0x013A : findstr /offĺine "findstr" "*.json"
28 | 0x013B : findstr /offĻine "findstr" "*.json"
29 | 0x013C : findstr /offļine "findstr" "*.json"
30 | 0x013D : findstr /offĽine "findstr" "*.json"
31 | 0x013E : findstr /offľine "findstr" "*.json"
32 | 0x0141 : findstr /offŁine "findstr" "*.json"
33 | 0x0142 : findstr /offłine "findstr" "*.json"
34 | 0x019A : findstr /offƚine "findstr" "*.json"
35 | 0x2112 : findstr /offℒine "findstr" "*.json"
36 | 0x2113 : findstr /offℓine "findstr" "*.json"
37 | 0xFF2C : findstr /offLine "findstr" "*.json"
38 | 0xFF4C : findstr /offline "findstr" "*.json"
39 |
40 | :: Quote Insertion
41 | Inserting quotes in the first argument did work, such as:
42 | findstr /"o"ffline "findstr" "*.json"
43 |
44 | :: Shortened Commands
45 | No alternative commands were found.
46 |
--------------------------------------------------------------------------------
/sample_results/fltmc.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR fltmc.exe
2 | - Generated on 2020-11-30T14:21:00.481512
3 | - Command used : fltmc.exe filters
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The command does not contain any arguments starting with a slash or dash.
9 |
10 | :: Character Insertion
11 | The following 1 commands were found to be working:
12 | 0x0022 : fltmc.exe fi"lters
13 |
14 | :: Character Replacement
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did work, such as:
19 | fltmc.exe f"i"lters
20 |
21 | :: Shortened Commands
22 | No alternative commands were found.
23 |
--------------------------------------------------------------------------------
/sample_results/forfiles.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR forfiles
2 | - Generated on 2020-12-03T22:36:42.564321
3 | - Command used : forfiles /P c:\windows\ /M *.bin /c "cmd /c echo HI"
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Character Insertion
8 | No alternative commands were found.
9 |
10 | :: Character Substitution
11 | The following commands were found to be working:
12 | 0x1D3E : forfiles /ᴾ c:\windows\ /M *.bin /c "cmd /c echo HI"
13 | 0x1D56 : forfiles /ᵖ c:\windows\ /M *.bin /c "cmd /c echo HI"
14 |
15 | :: Quote Insertion
16 | Inserting quotes in the first argument did work, such as:
17 | forfiles /"P" c:\windows\ /M *.bin /c "cmd /c echo HI"
18 |
19 | :: Shorthand Commands
20 | No alternative commands were found.
21 |
--------------------------------------------------------------------------------
/sample_results/icacls.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR icacls
2 | - Generated on 2021-01-03T20:00:31.704185
3 | - Command used : icacls "c:\users\wietze\downloads\test.txt" /grant administrators:(f)
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | No alternative commands were found.
9 |
10 | :: Character Insertion
11 | No alternative commands were found.
12 |
13 | :: Character Substitution
14 | No alternative commands were found.
15 |
16 | :: Quote Insertion
17 | Inserting quotes in the first argument did work, such as:
18 | icacls "c:\users\wietze\downloads\test.txt" /"g"rant administrators:(f)
19 |
20 | :: Shorthand Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/jsc.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR jsc.exe
2 | - Generated on 2021-01-04T01:41:59.300625
3 | - Command used : c:\windows\Microsoft.NET\Framework64\v4.0.30319\jsc.exe /target:exe /out:cache\file.exe inputs\file.js
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 1 commands were found to be working:
9 | 0x002D : c:\windows\Microsoft.NET\Framework64\v4.0.30319\jsc.exe -target:exe /out:cache\file.exe inputs\file.js
10 |
11 | :: Character Insertion
12 | No alternative commands were found.
13 |
14 | :: Character Substitution
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did work, such as:
19 | c:\windows\Microsoft.NET\Framework64\v4.0.30319\jsc.exe /"t"arget:exe /out:cache\file.exe inputs\file.js
20 |
21 | :: Shorthand Commands
22 | The following 1 commands were found to be working:
23 | c:\windows\Microsoft.NET\Framework64\v4.0.30319\jsc.exe /t:exe /out:cache\file.exe inputs\file.js
24 |
--------------------------------------------------------------------------------
/sample_results/mpcmdrun.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR MpCmdRun.exe
2 | - Generated on 2021-01-02T17:39:03.094686
3 | - Command used : "C:\Program Files\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 1 commands were found to be working:
9 | 0x002F : "C:\Program Files\Windows Defender\MpCmdRun.exe" /RemoveDefinitions -All
10 |
11 | :: Character Insertion
12 | No alternative commands were found.
13 |
14 | :: Character Substitution
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did work, such as:
19 | "C:\Program Files\Windows Defender\MpCmdRun.exe" -"R"emoveDefinitions -All
20 |
21 | :: Shorthand Commands
22 | No alternative commands were found.
23 |
--------------------------------------------------------------------------------
/sample_results/msiexec.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR msiexec
2 | - Generated on 2020-11-30T06:39:36.837353
3 | - Command used : msiexec /y "inputs\test.dll"
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The following 1 commands were found to be working:
9 | 0x002D : msiexec -y "inputs\test.dll"
10 |
11 | :: Character Insertion
12 | No alternative commands were found.
13 |
14 | :: Character Replacement
15 | The following commands were found to be working:
16 | 0x005A : msiexec /Z "inputs\test.dll"
17 | 0x007A : msiexec /z "inputs\test.dll"
18 |
19 | :: Quote Insertion
20 | Inserting quotes in the first argument did not appear to be working.
21 |
22 | :: Shortened Commands
23 | No alternative commands were found.
24 |
--------------------------------------------------------------------------------
/sample_results/net.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR net
2 | - Generated on 2020-11-29T00:38:17.078462
3 | - Command used : net share x=c:\ /remark:{random}
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | No alternative commands were found.
9 |
10 | :: Character Insertion
11 | The following 1 commands were found to be working:
12 | 0x0022 : net share x=c:\ /"remark:{random}
13 |
14 | :: Character Replacement
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did work, such as:
19 | net share x=c:\ /"r"emark:{random}
20 |
21 | :: Shortened Commands
22 | The following commands were found to be working:
23 | net share x=c:\ /r:{random}
24 | net share x=c:\ /re:{random}
25 | net share x=c:\ /rem:{random}
26 | net share x=c:\ /rema:{random}
27 | net share x=c:\ /remar:{random}
28 |
--------------------------------------------------------------------------------
/sample_results/netsh.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR netsh
2 | - Generated on 2020-11-30T12:40:20.824276
3 | - Command used : netsh advfirewall show currentprofile state
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The command does not contain any arguments starting with a slash or dash.
9 |
10 | :: Character Insertion
11 | No alternative commands were found.
12 |
13 | :: Character Replacement
14 | No alternative commands were found.
15 |
16 | :: Quote Insertion
17 | Inserting quotes in the first argument did work, such as:
18 | netsh a"d"vfirewall show currentprofile state
19 |
20 | :: Shortened Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/netstat.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR netstat
2 | - Generated on 2021-01-02T14:24:28.627896
3 | - Command used : netstat -p UDPv6
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 8 commands were found to be working:
9 | 0x002F : netstat /p UDPv6
10 | 0x2010 : netstat ‐p UDPv6
11 | 0x2012 : netstat ‒p UDPv6
12 | 0x2015 : netstat ―p UDPv6
13 | 0x2044 : netstat ⁄p UDPv6
14 | 0x2212 : netstat −p UDPv6
15 | 0x2215 : netstat ∕p UDPv6
16 | 0xFF0D : netstat -p UDPv6
17 |
18 | :: Character Insertion
19 | The following 33 commands were found to be working:
20 | 0x0046 : netstat -Fp UDPv6
21 | 0x004E : netstat -Np UDPv6
22 | 0x0050 : netstat -Pp UDPv6
23 | 0x0056 : netstat -Vp UDPv6
24 | 0x0066 : netstat -fp UDPv6
25 | 0x006E : netstat -np UDPv6
26 | 0x0070 : netstat -pp UDPv6
27 | 0x0076 : netstat -vp UDPv6
28 | 0x0143 : netstat -Ńp UDPv6
29 | 0x0144 : netstat -ńp UDPv6
30 | 0x0145 : netstat -Ņp UDPv6
31 | 0x0146 : netstat -ņp UDPv6
32 | 0x0147 : netstat -Ňp UDPv6
33 | 0x0148 : netstat -ňp UDPv6
34 | 0x03A6 : netstat -Φp UDPv6
35 | 0x03C0 : netstat -πp UDPv6
36 | 0x03C6 : netstat -φp UDPv6
37 | 0x207F : netstat -ⁿp UDPv6
38 | 0x20A7 : netstat -₧p UDPv6
39 | 0x2115 : netstat -ℕp UDPv6
40 | 0x2118 : netstat -℘p UDPv6
41 | 0x2119 : netstat -ℙp UDPv6
42 | 0x2131 : netstat -ℱp UDPv6
43 | 0x221A : netstat -√p UDPv6
44 | 0x2229 : netstat -∩p UDPv6
45 | 0xFF26 : netstat -Fp UDPv6
46 | 0xFF2E : netstat -Np UDPv6
47 | 0xFF30 : netstat -Pp UDPv6
48 | 0xFF36 : netstat -Vp UDPv6
49 | 0xFF46 : netstat -fp UDPv6
50 | 0xFF4E : netstat -np UDPv6
51 | 0xFF50 : netstat -pp UDPv6
52 | 0xFF56 : netstat -vp UDPv6
53 |
54 | :: Character Substitution
55 | The following commands were found to be working:
56 | 0x03C0 : netstat -π UDPv6
57 | 0x20A7 : netstat -₧ UDPv6
58 | 0x2118 : netstat -℘ UDPv6
59 | 0x2119 : netstat -ℙ UDPv6
60 | 0xFF30 : netstat -P UDPv6
61 | 0xFF50 : netstat -p UDPv6
62 |
63 | :: Quote Insertion
64 | Inserting quotes in the first argument did work, such as:
65 | netstat -"p" UDPv6
66 |
67 | :: Shorthand Commands
68 | No alternative commands were found.
69 |
--------------------------------------------------------------------------------
/sample_results/ping.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR ping
2 | - Generated on 2020-11-30T07:07:36.415555
3 | - Command used : ping /n 1 localhost
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The following 1 commands were found to be working:
9 | 0x002D : ping -n 1 localhost
10 |
11 | :: Character Insertion
12 | The following 1 commands were found to be working:
13 | 0x006E : ping /nn 1 localhost
14 |
15 | :: Character Replacement
16 | No alternative commands were found.
17 |
18 | :: Quote Insertion
19 | Inserting quotes in the first argument did work, such as:
20 | ping /"n" 1 localhost
21 |
22 | :: Shortened Commands
23 | No alternative commands were found.
24 |
--------------------------------------------------------------------------------
/sample_results/powershell.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR powershell
2 | - Generated on 2020-11-29T10:12:00.012891
3 | - Command used : powershell /encodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0x00FE 0x02B0..0x02FE 0x2070..0x209E
6 |
7 | :: Different dash/hyphens
8 | The following 4 commands were found to be working:
9 | 0x002D : powershell -encodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
10 | 0x2013 : powershell –encodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
11 | 0x2014 : powershell —encodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
12 | 0x2015 : powershell ―encodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
13 |
14 | :: Character Insertion
15 | No alternative commands were found.
16 |
17 | :: Character Replacement
18 | No alternative commands were found.
19 |
20 | :: Quote Insertion
21 | Inserting quotes in the first argument did work, such as:
22 | powershell /"e"ncodedcommand ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
23 |
24 | :: Shortened Commands
25 | The following 12 commands were found to be working:
26 | powershell /e ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
27 | powershell /en ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
28 | powershell /enc ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
29 | powershell /enco ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
30 | powershell /encod ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
31 | powershell /encode ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
32 | powershell /encoded ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
33 | powershell /encodedc ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
34 | powershell /encodedco ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
35 | powershell /encodedcom ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
36 | powershell /encodedcomm ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
37 | powershell /encodedcomma ZQBjAGgAbwAgACIAQAB3AGkAZQB0AHoAZQAiAA==
--------------------------------------------------------------------------------
/sample_results/regsvr32.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR regsvr32
2 | - Generated on 2021-01-02T20:09:36.730781
3 | - Command used : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0x00FE 0x02B0..0x02FE 0x2070..0x209E
6 |
7 | :: Option Char Substitution
8 | The following 30 commands were found to be working:
9 | 0x002D : regsvr32 /s /u -i:inputs\file.sct scrobj.dll
10 | 0x005C : regsvr32 /s /u \i:inputs\file.sct scrobj.dll
11 | 0x007E : regsvr32 /s /u ~i:inputs\file.sct scrobj.dll
12 | 0x00AD : regsvr32 /s /u i:inputs\file.sct scrobj.dll
13 | 0x058A : regsvr32 /s /u ֊i:inputs\file.sct scrobj.dll
14 | 0x05BE : regsvr32 /s /u ־i:inputs\file.sct scrobj.dll
15 | 0x1400 : regsvr32 /s /u ᐀i:inputs\file.sct scrobj.dll
16 | 0x1806 : regsvr32 /s /u ᠆i:inputs\file.sct scrobj.dll
17 | 0x2010 : regsvr32 /s /u ‐i:inputs\file.sct scrobj.dll
18 | 0x2012 : regsvr32 /s /u ‒i:inputs\file.sct scrobj.dll
19 | 0x2013 : regsvr32 /s /u –i:inputs\file.sct scrobj.dll
20 | 0x2014 : regsvr32 /s /u —i:inputs\file.sct scrobj.dll
21 | 0x2015 : regsvr32 /s /u ―i:inputs\file.sct scrobj.dll
22 | 0x2044 : regsvr32 /s /u ⁄i:inputs\file.sct scrobj.dll
23 | 0x2053 : regsvr32 /s /u ⁓i:inputs\file.sct scrobj.dll
24 | 0x2212 : regsvr32 /s /u −i:inputs\file.sct scrobj.dll
25 | 0x2215 : regsvr32 /s /u ∕i:inputs\file.sct scrobj.dll
26 | 0x244A : regsvr32 /s /u ⑊i:inputs\file.sct scrobj.dll
27 | 0x29F8 : regsvr32 /s /u ⧸i:inputs\file.sct scrobj.dll
28 | 0x2E17 : regsvr32 /s /u ⸗i:inputs\file.sct scrobj.dll
29 | 0x2E3A : regsvr32 /s /u ⸺i:inputs\file.sct scrobj.dll
30 | 0x2E3B : regsvr32 /s /u ⸻i:inputs\file.sct scrobj.dll
31 | 0x301C : regsvr32 /s /u 〜i:inputs\file.sct scrobj.dll
32 | 0x3030 : regsvr32 /s /u 〰i:inputs\file.sct scrobj.dll
33 | 0x30A0 : regsvr32 /s /u ゠i:inputs\file.sct scrobj.dll
34 | 0xFE31 : regsvr32 /s /u ︱i:inputs\file.sct scrobj.dll
35 | 0xFE32 : regsvr32 /s /u ︲i:inputs\file.sct scrobj.dll
36 | 0xFE58 : regsvr32 /s /u ﹘i:inputs\file.sct scrobj.dll
37 | 0xFE63 : regsvr32 /s /u ﹣i:inputs\file.sct scrobj.dll
38 | 0xFF0D : regsvr32 /s /u -i:inputs\file.sct scrobj.dll
39 |
40 | :: Character Insertion
41 | The following 222 commands were found to be working:
42 | 0x0001 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
43 | 0x0002 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
44 | 0x0003 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
45 | 0x0004 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
46 | 0x0005 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
47 | 0x0006 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
48 | 0x0007 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
49 | 0x0008 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
50 | 0x0009 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
51 | 0x000A : regsvr32 /s /u
52 | /i:inputs\file.sct scrobj.dll
53 | 0x000B : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
54 | 0x000C : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
55 | 0x000D : regsvr32 /s /u
/i:inputs\file.sct scrobj.dll
56 | 0x000E : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
57 | 0x000F : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
58 | 0x0010 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
59 | 0x0011 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
60 | 0x0012 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
61 | 0x0013 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
62 | 0x0014 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
63 | 0x0015 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
64 | 0x0016 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
65 | 0x0017 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
66 | 0x0018 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
67 | 0x0019 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
68 | 0x001A : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
69 | 0x001B : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
70 | 0x001C : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
71 | 0x001D : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
72 | 0x001E : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
73 | 0x001F : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
74 | 0x0020 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
75 | 0x0021 : regsvr32 /s /u! /i:inputs\file.sct scrobj.dll
76 | 0x0023 : regsvr32 /s /u# /i:inputs\file.sct scrobj.dll
77 | 0x0024 : regsvr32 /s /u$ /i:inputs\file.sct scrobj.dll
78 | 0x0025 : regsvr32 /s /u% /i:inputs\file.sct scrobj.dll
79 | 0x0026 : regsvr32 /s /u& /i:inputs\file.sct scrobj.dll
80 | 0x0027 : regsvr32 /s /u' /i:inputs\file.sct scrobj.dll
81 | 0x0028 : regsvr32 /s /u( /i:inputs\file.sct scrobj.dll
82 | 0x0029 : regsvr32 /s /u) /i:inputs\file.sct scrobj.dll
83 | 0x002A : regsvr32 /s /u* /i:inputs\file.sct scrobj.dll
84 | 0x002B : regsvr32 /s /u+ /i:inputs\file.sct scrobj.dll
85 | 0x002C : regsvr32 /s /u, /i:inputs\file.sct scrobj.dll
86 | 0x002D : regsvr32 /s /u- /i:inputs\file.sct scrobj.dll
87 | 0x002E : regsvr32 /s /u. /i:inputs\file.sct scrobj.dll
88 | 0x002F : regsvr32 /s /u/ /i:inputs\file.sct scrobj.dll
89 | 0x0030 : regsvr32 /s /u0 /i:inputs\file.sct scrobj.dll
90 | 0x0031 : regsvr32 /s /u1 /i:inputs\file.sct scrobj.dll
91 | 0x0032 : regsvr32 /s /u2 /i:inputs\file.sct scrobj.dll
92 | 0x0033 : regsvr32 /s /u3 /i:inputs\file.sct scrobj.dll
93 | 0x0035 : regsvr32 /s /u5 /i:inputs\file.sct scrobj.dll
94 | 0x0036 : regsvr32 /s /u6 /i:inputs\file.sct scrobj.dll
95 | 0x0037 : regsvr32 /s /u7 /i:inputs\file.sct scrobj.dll
96 | 0x0038 : regsvr32 /s /u8 /i:inputs\file.sct scrobj.dll
97 | 0x0039 : regsvr32 /s /u9 /i:inputs\file.sct scrobj.dll
98 | 0x003A : regsvr32 /s /u: /i:inputs\file.sct scrobj.dll
99 | 0x003B : regsvr32 /s /u; /i:inputs\file.sct scrobj.dll
100 | 0x003C : regsvr32 /s /u< /i:inputs\file.sct scrobj.dll
101 | 0x003D : regsvr32 /s /u= /i:inputs\file.sct scrobj.dll
102 | 0x003E : regsvr32 /s /u> /i:inputs\file.sct scrobj.dll
103 | 0x003F : regsvr32 /s /u? /i:inputs\file.sct scrobj.dll
104 | 0x0040 : regsvr32 /s /u@ /i:inputs\file.sct scrobj.dll
105 | 0x0041 : regsvr32 /s /uA /i:inputs\file.sct scrobj.dll
106 | 0x0042 : regsvr32 /s /uB /i:inputs\file.sct scrobj.dll
107 | 0x0043 : regsvr32 /s /uC /i:inputs\file.sct scrobj.dll
108 | 0x0044 : regsvr32 /s /uD /i:inputs\file.sct scrobj.dll
109 | 0x0045 : regsvr32 /s /uE /i:inputs\file.sct scrobj.dll
110 | 0x0046 : regsvr32 /s /uF /i:inputs\file.sct scrobj.dll
111 | 0x0047 : regsvr32 /s /uG /i:inputs\file.sct scrobj.dll
112 | 0x0048 : regsvr32 /s /uH /i:inputs\file.sct scrobj.dll
113 | 0x0049 : regsvr32 /s /uI /i:inputs\file.sct scrobj.dll
114 | 0x004A : regsvr32 /s /uJ /i:inputs\file.sct scrobj.dll
115 | 0x004B : regsvr32 /s /uK /i:inputs\file.sct scrobj.dll
116 | 0x004C : regsvr32 /s /uL /i:inputs\file.sct scrobj.dll
117 | 0x004D : regsvr32 /s /uM /i:inputs\file.sct scrobj.dll
118 | 0x004E : regsvr32 /s /uN /i:inputs\file.sct scrobj.dll
119 | 0x004F : regsvr32 /s /uO /i:inputs\file.sct scrobj.dll
120 | 0x0050 : regsvr32 /s /uP /i:inputs\file.sct scrobj.dll
121 | 0x0051 : regsvr32 /s /uQ /i:inputs\file.sct scrobj.dll
122 | 0x0052 : regsvr32 /s /uR /i:inputs\file.sct scrobj.dll
123 | 0x0053 : regsvr32 /s /uS /i:inputs\file.sct scrobj.dll
124 | 0x0054 : regsvr32 /s /uT /i:inputs\file.sct scrobj.dll
125 | 0x0055 : regsvr32 /s /uU /i:inputs\file.sct scrobj.dll
126 | 0x0056 : regsvr32 /s /uV /i:inputs\file.sct scrobj.dll
127 | 0x0057 : regsvr32 /s /uW /i:inputs\file.sct scrobj.dll
128 | 0x0058 : regsvr32 /s /uX /i:inputs\file.sct scrobj.dll
129 | 0x0059 : regsvr32 /s /uY /i:inputs\file.sct scrobj.dll
130 | 0x005A : regsvr32 /s /uZ /i:inputs\file.sct scrobj.dll
131 | 0x005B : regsvr32 /s /u[ /i:inputs\file.sct scrobj.dll
132 | 0x005C : regsvr32 /s /u\ /i:inputs\file.sct scrobj.dll
133 | 0x005D : regsvr32 /s /u] /i:inputs\file.sct scrobj.dll
134 | 0x005E : regsvr32 /s /u^ /i:inputs\file.sct scrobj.dll
135 | 0x005F : regsvr32 /s /u_ /i:inputs\file.sct scrobj.dll
136 | 0x0060 : regsvr32 /s /u` /i:inputs\file.sct scrobj.dll
137 | 0x0061 : regsvr32 /s /ua /i:inputs\file.sct scrobj.dll
138 | 0x0067 : regsvr32 /s /ug /i:inputs\file.sct scrobj.dll
139 | 0x006A : regsvr32 /s /uj /i:inputs\file.sct scrobj.dll
140 | 0x006C : regsvr32 /s /ul /i:inputs\file.sct scrobj.dll
141 | 0x006E : regsvr32 /s /un /i:inputs\file.sct scrobj.dll
142 | 0x006F : regsvr32 /s /uo /i:inputs\file.sct scrobj.dll
143 | 0x0070 : regsvr32 /s /up /i:inputs\file.sct scrobj.dll
144 | 0x0071 : regsvr32 /s /uq /i:inputs\file.sct scrobj.dll
145 | 0x0072 : regsvr32 /s /ur /i:inputs\file.sct scrobj.dll
146 | 0x0073 : regsvr32 /s /us /i:inputs\file.sct scrobj.dll
147 | 0x0074 : regsvr32 /s /ut /i:inputs\file.sct scrobj.dll
148 | 0x0075 : regsvr32 /s /uu /i:inputs\file.sct scrobj.dll
149 | 0x0076 : regsvr32 /s /uv /i:inputs\file.sct scrobj.dll
150 | 0x0077 : regsvr32 /s /uw /i:inputs\file.sct scrobj.dll
151 | 0x0078 : regsvr32 /s /ux /i:inputs\file.sct scrobj.dll
152 | 0x0079 : regsvr32 /s /uy /i:inputs\file.sct scrobj.dll
153 | 0x007A : regsvr32 /s /uz /i:inputs\file.sct scrobj.dll
154 | 0x007B : regsvr32 /s /u{ /i:inputs\file.sct scrobj.dll
155 | 0x007C : regsvr32 /s /u| /i:inputs\file.sct scrobj.dll
156 | 0x007D : regsvr32 /s /u} /i:inputs\file.sct scrobj.dll
157 | 0x007E : regsvr32 /s /u~ /i:inputs\file.sct scrobj.dll
158 | 0x007F : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
159 | 0x0081 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
160 | 0x008D : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
161 | 0x008F : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
162 | 0x0090 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
163 | 0x009D : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
164 | 0x00A0 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
165 | 0x00A1 : regsvr32 /s /u¡ /i:inputs\file.sct scrobj.dll
166 | 0x00A2 : regsvr32 /s /u¢ /i:inputs\file.sct scrobj.dll
167 | 0x00A3 : regsvr32 /s /u£ /i:inputs\file.sct scrobj.dll
168 | 0x00A4 : regsvr32 /s /u¤ /i:inputs\file.sct scrobj.dll
169 | 0x00A5 : regsvr32 /s /u¥ /i:inputs\file.sct scrobj.dll
170 | 0x00A6 : regsvr32 /s /u¦ /i:inputs\file.sct scrobj.dll
171 | 0x00A7 : regsvr32 /s /u§ /i:inputs\file.sct scrobj.dll
172 | 0x00A8 : regsvr32 /s /u¨ /i:inputs\file.sct scrobj.dll
173 | 0x00A9 : regsvr32 /s /u© /i:inputs\file.sct scrobj.dll
174 | 0x00AA : regsvr32 /s /uª /i:inputs\file.sct scrobj.dll
175 | 0x00AB : regsvr32 /s /u« /i:inputs\file.sct scrobj.dll
176 | 0x00AC : regsvr32 /s /u¬ /i:inputs\file.sct scrobj.dll
177 | 0x00AD : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
178 | 0x00AF : regsvr32 /s /u¯ /i:inputs\file.sct scrobj.dll
179 | 0x00B2 : regsvr32 /s /u² /i:inputs\file.sct scrobj.dll
180 | 0x00B3 : regsvr32 /s /u³ /i:inputs\file.sct scrobj.dll
181 | 0x00B4 : regsvr32 /s /u´ /i:inputs\file.sct scrobj.dll
182 | 0x00B6 : regsvr32 /s /u¶ /i:inputs\file.sct scrobj.dll
183 | 0x00B7 : regsvr32 /s /u· /i:inputs\file.sct scrobj.dll
184 | 0x00B8 : regsvr32 /s /u¸ /i:inputs\file.sct scrobj.dll
185 | 0x00B9 : regsvr32 /s /u¹ /i:inputs\file.sct scrobj.dll
186 | 0x00BC : regsvr32 /s /u¼ /i:inputs\file.sct scrobj.dll
187 | 0x00BD : regsvr32 /s /u½ /i:inputs\file.sct scrobj.dll
188 | 0x00BE : regsvr32 /s /u¾ /i:inputs\file.sct scrobj.dll
189 | 0x00C0 : regsvr32 /s /uÀ /i:inputs\file.sct scrobj.dll
190 | 0x00C1 : regsvr32 /s /uÁ /i:inputs\file.sct scrobj.dll
191 | 0x00C2 : regsvr32 /s /u /i:inputs\file.sct scrobj.dll
192 | 0x00C3 : regsvr32 /s /uà /i:inputs\file.sct scrobj.dll
193 | 0x00C4 : regsvr32 /s /uÄ /i:inputs\file.sct scrobj.dll
194 | 0x00C5 : regsvr32 /s /uÅ /i:inputs\file.sct scrobj.dll
195 | 0x00C6 : regsvr32 /s /uÆ /i:inputs\file.sct scrobj.dll
196 | 0x00C7 : regsvr32 /s /uÇ /i:inputs\file.sct scrobj.dll
197 | 0x00C8 : regsvr32 /s /uÈ /i:inputs\file.sct scrobj.dll
198 | 0x00C9 : regsvr32 /s /uÉ /i:inputs\file.sct scrobj.dll
199 | 0x00CA : regsvr32 /s /uÊ /i:inputs\file.sct scrobj.dll
200 | 0x00CB : regsvr32 /s /uË /i:inputs\file.sct scrobj.dll
201 | 0x00CC : regsvr32 /s /uÌ /i:inputs\file.sct scrobj.dll
202 | 0x00CD : regsvr32 /s /uÍ /i:inputs\file.sct scrobj.dll
203 | 0x00CE : regsvr32 /s /uÎ /i:inputs\file.sct scrobj.dll
204 | 0x00CF : regsvr32 /s /uÏ /i:inputs\file.sct scrobj.dll
205 | 0x00D0 : regsvr32 /s /uÐ /i:inputs\file.sct scrobj.dll
206 | 0x00D1 : regsvr32 /s /uÑ /i:inputs\file.sct scrobj.dll
207 | 0x00D2 : regsvr32 /s /uÒ /i:inputs\file.sct scrobj.dll
208 | 0x00D3 : regsvr32 /s /uÓ /i:inputs\file.sct scrobj.dll
209 | 0x00D4 : regsvr32 /s /uÔ /i:inputs\file.sct scrobj.dll
210 | 0x00D6 : regsvr32 /s /uÖ /i:inputs\file.sct scrobj.dll
211 | 0x00D7 : regsvr32 /s /u× /i:inputs\file.sct scrobj.dll
212 | 0x00D8 : regsvr32 /s /uØ /i:inputs\file.sct scrobj.dll
213 | 0x00D9 : regsvr32 /s /uÙ /i:inputs\file.sct scrobj.dll
214 | 0x00DA : regsvr32 /s /uÚ /i:inputs\file.sct scrobj.dll
215 | 0x00DB : regsvr32 /s /uÛ /i:inputs\file.sct scrobj.dll
216 | 0x00DC : regsvr32 /s /uÜ /i:inputs\file.sct scrobj.dll
217 | 0x00DD : regsvr32 /s /uÝ /i:inputs\file.sct scrobj.dll
218 | 0x00DE : regsvr32 /s /uÞ /i:inputs\file.sct scrobj.dll
219 | 0x00DF : regsvr32 /s /uß /i:inputs\file.sct scrobj.dll
220 | 0x00E0 : regsvr32 /s /uà /i:inputs\file.sct scrobj.dll
221 | 0x00E3 : regsvr32 /s /uã /i:inputs\file.sct scrobj.dll
222 | 0x00E4 : regsvr32 /s /uä /i:inputs\file.sct scrobj.dll
223 | 0x00E5 : regsvr32 /s /uå /i:inputs\file.sct scrobj.dll
224 | 0x00E9 : regsvr32 /s /ué /i:inputs\file.sct scrobj.dll
225 | 0x00EA : regsvr32 /s /uê /i:inputs\file.sct scrobj.dll
226 | 0x00EB : regsvr32 /s /uë /i:inputs\file.sct scrobj.dll
227 | 0x00EC : regsvr32 /s /uì /i:inputs\file.sct scrobj.dll
228 | 0x00EE : regsvr32 /s /uî /i:inputs\file.sct scrobj.dll
229 | 0x00EF : regsvr32 /s /uï /i:inputs\file.sct scrobj.dll
230 | 0x00F0 : regsvr32 /s /uð /i:inputs\file.sct scrobj.dll
231 | 0x00F1 : regsvr32 /s /uñ /i:inputs\file.sct scrobj.dll
232 | 0x00F2 : regsvr32 /s /uò /i:inputs\file.sct scrobj.dll
233 | 0x00F3 : regsvr32 /s /uó /i:inputs\file.sct scrobj.dll
234 | 0x00F4 : regsvr32 /s /uô /i:inputs\file.sct scrobj.dll
235 | 0x00F5 : regsvr32 /s /uõ /i:inputs\file.sct scrobj.dll
236 | 0x00F6 : regsvr32 /s /uö /i:inputs\file.sct scrobj.dll
237 | 0x00F7 : regsvr32 /s /u÷ /i:inputs\file.sct scrobj.dll
238 | 0x00F8 : regsvr32 /s /uø /i:inputs\file.sct scrobj.dll
239 | 0x00F9 : regsvr32 /s /uù /i:inputs\file.sct scrobj.dll
240 | 0x00FA : regsvr32 /s /uú /i:inputs\file.sct scrobj.dll
241 | 0x00FB : regsvr32 /s /uû /i:inputs\file.sct scrobj.dll
242 | 0x00FC : regsvr32 /s /uü /i:inputs\file.sct scrobj.dll
243 | 0x00FD : regsvr32 /s /uý /i:inputs\file.sct scrobj.dll
244 | 0x00FE : regsvr32 /s /uþ /i:inputs\file.sct scrobj.dll
245 | 0x02B9 : regsvr32 /s /uʹ /i:inputs\file.sct scrobj.dll
246 | 0x02BA : regsvr32 /s /uʺ /i:inputs\file.sct scrobj.dll
247 | 0x02BC : regsvr32 /s /uʼ /i:inputs\file.sct scrobj.dll
248 | 0x02C4 : regsvr32 /s /u˄ /i:inputs\file.sct scrobj.dll
249 | 0x02C6 : regsvr32 /s /uˆ /i:inputs\file.sct scrobj.dll
250 | 0x02C8 : regsvr32 /s /uˈ /i:inputs\file.sct scrobj.dll
251 | 0x02C9 : regsvr32 /s /uˉ /i:inputs\file.sct scrobj.dll
252 | 0x02CA : regsvr32 /s /uˊ /i:inputs\file.sct scrobj.dll
253 | 0x02CB : regsvr32 /s /uˋ /i:inputs\file.sct scrobj.dll
254 | 0x02CD : regsvr32 /s /uˍ /i:inputs\file.sct scrobj.dll
255 | 0x02DA : regsvr32 /s /u˚ /i:inputs\file.sct scrobj.dll
256 | 0x02DC : regsvr32 /s /u˜ /i:inputs\file.sct scrobj.dll
257 | 0x2070 : regsvr32 /s /u⁰ /i:inputs\file.sct scrobj.dll
258 | 0x2075 : regsvr32 /s /u⁵ /i:inputs\file.sct scrobj.dll
259 | 0x2077 : regsvr32 /s /u⁷ /i:inputs\file.sct scrobj.dll
260 | 0x207F : regsvr32 /s /uⁿ /i:inputs\file.sct scrobj.dll
261 | 0x2080 : regsvr32 /s /u₀ /i:inputs\file.sct scrobj.dll
262 | 0x2082 : regsvr32 /s /u₂ /i:inputs\file.sct scrobj.dll
263 | 0x2087 : regsvr32 /s /u₇ /i:inputs\file.sct scrobj.dll
264 | 0x2088 : regsvr32 /s /u₈ /i:inputs\file.sct scrobj.dll
265 |
266 | :: Character Substitution
267 | The following commands were found to be working:
268 | 0x0043 : regsvr32 /s /C /i:inputs\file.sct scrobj.dll
269 | 0x0045 : regsvr32 /s /E /i:inputs\file.sct scrobj.dll
270 | 0x0049 : regsvr32 /s /I /i:inputs\file.sct scrobj.dll
271 | 0x004E : regsvr32 /s /N /i:inputs\file.sct scrobj.dll
272 | 0x0053 : regsvr32 /s /S /i:inputs\file.sct scrobj.dll
273 | 0x0056 : regsvr32 /s /V /i:inputs\file.sct scrobj.dll
274 | 0x0063 : regsvr32 /s /c /i:inputs\file.sct scrobj.dll
275 | 0x0065 : regsvr32 /s /e /i:inputs\file.sct scrobj.dll
276 | 0x0069 : regsvr32 /s /i /i:inputs\file.sct scrobj.dll
277 | 0x006E : regsvr32 /s /n /i:inputs\file.sct scrobj.dll
278 | 0x0073 : regsvr32 /s /s /i:inputs\file.sct scrobj.dll
279 | 0x0076 : regsvr32 /s /v /i:inputs\file.sct scrobj.dll
280 |
281 | :: Quote Insertion
282 | Inserting quotes in the first argument did work, such as:
283 | regsvr32 /s /u /"i":inputs\file.sct scrobj.dll
284 |
285 | :: Shorthand Commands
286 | No alternative commands were found.
287 |
--------------------------------------------------------------------------------
/sample_results/robocopy.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR robocopy
2 | - Generated on 2021-01-04T00:10:55.206747
3 | - Command used : robocopy c:\windows\temp c:\windows\temp\temp2 /L
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 1 commands were found to be working:
9 | 0x002D : robocopy c:\windows\temp c:\windows\temp\temp2 -L
10 |
11 | :: Character Insertion
12 | No alternative commands were found.
13 |
14 | :: Character Substitution
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did not appear to be working.
19 |
20 | :: Shorthand Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/route.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR ROUTE
2 | - Generated on 2021-01-02T14:38:35.220402
3 | - Command used : ROUTE PRINT 123*
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The command does not contain any arguments starting with a slash or dash.
9 |
10 | :: Character Insertion
11 | No alternative commands were found.
12 |
13 | :: Character Substitution
14 | The following commands were found to be working:
15 | 0x0154 : ROUTE PŔINT 123*
16 | 0x0155 : ROUTE PŕINT 123*
17 | 0x0156 : ROUTE PŖINT 123*
18 | 0x0157 : ROUTE PŗINT 123*
19 | 0x0158 : ROUTE PŘINT 123*
20 | 0x0159 : ROUTE PřINT 123*
21 | 0x211B : ROUTE PℛINT 123*
22 | 0x211C : ROUTE PℜINT 123*
23 | 0x211D : ROUTE PℝINT 123*
24 | 0xFF32 : ROUTE PRINT 123*
25 | 0xFF52 : ROUTE PrINT 123*
26 |
27 | :: Quote Insertion
28 | Inserting quotes in the first argument did work, such as:
29 | ROUTE P"R"INT 123*
30 |
31 | :: Shorthand Commands
32 | No alternative commands were found.
33 |
--------------------------------------------------------------------------------
/sample_results/sc.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR sc
2 | - Generated on 2020-11-29T03:08:00.958477
3 | - Command used : sc query eventlog
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The command does not contain any arguments starting with a slash or dash.
9 |
10 | :: Character Insertion
11 | No alternative commands were found.
12 |
13 | :: Character Replacement
14 | No alternative commands were found.
15 |
16 | :: Quote Insertion
17 | Inserting quotes in the first argument did work, such as:
18 | sc q"u"ery eventlog
19 |
20 | :: Shortened Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/schtasks.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR schtasks
2 | - Generated on 2021-01-02T13:24:43.862104
3 | - Command used : schtasks /showsid /TN \Microsoft\XblGameSave\XblGameSaveTask
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 2 commands were found to be working:
9 | 0x002D : schtasks -showsid /TN \Microsoft\XblGameSave\XblGameSaveTask
10 | 0xFE63 : schtasks ﹣showsid /TN \Microsoft\XblGameSave\XblGameSaveTask
11 |
12 | :: Character Insertion
13 | No alternative commands were found.
14 |
15 | :: Character Substitution
16 | The following commands were found to be working:
17 | 0x02E2 : schtasks /ˢhowsid /TN \Microsoft\XblGameSave\XblGameSaveTask
18 |
19 | :: Quote Insertion
20 | Inserting quotes in the first argument did work, such as:
21 | schtasks /"s"howsid /TN \Microsoft\XblGameSave\XblGameSaveTask
22 |
23 | :: Shorthand Commands
24 | No alternative commands were found.
25 |
--------------------------------------------------------------------------------
/sample_results/systeminfo.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR systeminfo
2 | - Generated on 2020-11-30T14:00:18.809353
3 | - Command used : systeminfo /s localhost
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The following 2 commands were found to be working:
9 | 0x002D : systeminfo -s localhost
10 | 0xFE63 : systeminfo ﹣s localhost
11 |
12 | :: Character Insertion
13 | No alternative commands were found.
14 |
15 | :: Character Replacement
16 | The following commands were found to be working:
17 | 0x02E2 : systeminfo /ˢ localhost
18 |
19 | :: Quote Insertion
20 | Inserting quotes in the first argument did work, such as:
21 | systeminfo /"s" localhost
22 |
23 | :: Shortened Commands
24 | No alternative commands were found.
25 |
--------------------------------------------------------------------------------
/sample_results/takeown.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR takeown
2 | - Generated on 2021-01-02T21:21:32.881566
3 | - Command used : takeown /F config.json
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 2 commands were found to be working:
9 | 0x002D : takeown -F config.json
10 | 0xFE63 : takeown ﹣F config.json
11 |
12 | :: Character Insertion
13 | The following 2 commands were found to be working:
14 | 0x0009 : takeown /F config.json
15 | 0x0020 : takeown /F config.json
16 |
17 | :: Character Substitution
18 | The following commands were found to be working:
19 | 0x1DA0 : takeown /ᶠ config.json
20 |
21 | :: Quote Insertion
22 | Inserting quotes in the first argument did work, such as:
23 | takeown /"F" config.json
24 |
25 | :: Shorthand Commands
26 | No alternative commands were found.
27 |
--------------------------------------------------------------------------------
/sample_results/taskkill.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR taskkill
2 | - Generated on 2021-01-02T15:11:02.001944
3 | - Command used : taskkill /im test.exe
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 2 commands were found to be working:
9 | 0x002D : taskkill -im test.exe
10 | 0xFE63 : taskkill ﹣im test.exe
11 |
12 | :: Character Insertion
13 | No alternative commands were found.
14 |
15 | :: Character Substitution
16 | The following commands were found to be working:
17 | 0x1D35 : taskkill /ᴵm test.exe
18 |
19 | :: Quote Insertion
20 | Inserting quotes in the first argument did work, such as:
21 | taskkill /"i"m test.exe
22 |
23 | :: Shorthand Commands
24 | No alternative commands were found.
25 |
--------------------------------------------------------------------------------
/sample_results/tasklist.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR tasklist
2 | - Generated on 2020-11-30T13:22:20.949047
3 | - Command used : tasklist /fi "USERNAME eq test"
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The following 2 commands were found to be working:
9 | 0x002D : tasklist -fi "USERNAME eq test"
10 | 0xFE63 : tasklist ﹣fi "USERNAME eq test"
11 |
12 | :: Character Insertion
13 | No alternative commands were found.
14 |
15 | :: Character Replacement
16 | The following commands were found to be working:
17 | 0x1DA0 : tasklist /ᶠi "USERNAME eq test"
18 |
19 | :: Quote Insertion
20 | Inserting quotes in the first argument did work, such as:
21 | tasklist /"f"i "USERNAME eq test"
22 |
23 | :: Shortened Commands
24 | No alternative commands were found.
25 |
--------------------------------------------------------------------------------
/sample_results/vbc.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR vbc.exe
2 | - Generated on 2021-01-04T00:22:20.956666
3 | - Command used : c:\windows\Microsoft.NET\Framework64\v4.0.30319\vbc.exe /target:exe /out:cache\file.exe inputs\file.vbs
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 1 commands were found to be working:
9 | 0x002D : c:\windows\Microsoft.NET\Framework64\v4.0.30319\vbc.exe -target:exe /out:cache\file.exe inputs\file.vbs
10 |
11 | :: Character Insertion
12 | No alternative commands were found.
13 |
14 | :: Character Substitution
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did not appear to be working.
19 |
20 | :: Shorthand Commands
21 | The following 1 commands were found to be working:
22 | c:\windows\Microsoft.NET\Framework64\v4.0.30319\vbc.exe /t:exe /out:cache\file.exe inputs\file.vbs
23 |
--------------------------------------------------------------------------------
/sample_results/vssadmin.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR vssadmin.exe
2 | - Generated on 2021-01-03T22:36:50.549504
3 | - Command used : c:\users\wietze\downloads\test\vssadmin.exe list volumes
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The command does not contain any arguments starting with a slash or dash.
9 |
10 | :: Character Insertion
11 | No alternative commands were found.
12 |
13 | :: Character Substitution
14 | No alternative commands were found.
15 |
16 | :: Quote Insertion
17 | Inserting quotes in the first argument did work, such as:
18 | c:\users\wietze\downloads\test\vssadmin.exe l"i"st volumes
19 |
20 | :: Shorthand Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/winrm.cmd.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR winrm.cmd
2 | - Generated on 2021-01-03T23:23:18.787991
3 | - Command used : c:\windows\system32\winrm.cmd get winrm/config -format:text
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0x00FE 0x02B0..0x02FE 0x2070..0x209E
6 |
7 | :: Option Char Substitution
8 | The following 1 commands were found to be working:
9 | 0x002F : c:\windows\system32\winrm.cmd get winrm/config /format:text
10 |
11 | :: Character Insertion
12 | The following 1 commands were found to be working:
13 | 0x005E : c:\windows\system32\winrm.cmd get winrm/config -for^mat:text
14 |
15 | :: Character Substitution
16 | No alternative commands were found.
17 |
18 | :: Quote Insertion
19 | Inserting quotes in the first argument did not appear to be working.
20 |
21 | :: Shorthand Commands
22 | The following 1 commands were found to be working:
23 | c:\windows\system32\winrm.cmd get winrm/config -f:text
24 |
--------------------------------------------------------------------------------
/sample_results/winrs.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR winrs
2 | - Generated on 2021-01-02T21:01:52.318909
3 | - Command used : winrs -r:localhost echo hello
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Option Char Substitution
8 | The following 1 commands were found to be working:
9 | 0x002F : winrs /r:localhost echo hello
10 |
11 | :: Character Insertion
12 | No alternative commands were found.
13 |
14 | :: Character Substitution
15 | No alternative commands were found.
16 |
17 | :: Quote Insertion
18 | Inserting quotes in the first argument did not appear to be working.
19 |
20 | :: Shorthand Commands
21 | No alternative commands were found.
22 |
--------------------------------------------------------------------------------
/sample_results/wmic.log:
--------------------------------------------------------------------------------
1 | PROCESS OBFUSCATION REPORT FOR wmic
2 | - Generated on 2020-11-29T02:56:59.426171
3 | - Command used : wmic os get BuildNumber
4 | - Insertion position: ^
5 | - Char ranges scanned: 0x0001..0xFFFE
6 |
7 | :: Different dash/hyphens
8 | The command does not contain any arguments starting with a slash or dash.
9 |
10 | :: Character Insertion
11 | No alternative commands were found.
12 |
13 | :: Character Replacement
14 | No alternative commands were found.
15 |
16 | :: Quote Insertion
17 | Inserting quotes in the first argument did not appear to be working.
18 |
19 | :: Shortened Commands
20 | No alternative commands were found.
21 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 | description_short = "Project for identifying executables that have command-line options that can be obfuscated, possibly bypassing detection rules."
4 | with open("README.md", "r", encoding="utf-8") as fh:
5 | description_long = fh.read()
6 |
7 | setuptools.setup(
8 | name="analyse_obfuscation",
9 | version="1.1.0",
10 | author="@Wietze",
11 | description=description_short,
12 | long_description=description_long,
13 | long_description_content_type="text/markdown",
14 | url="https://github.com/wietze/windows-command-line-obfuscation",
15 | packages=setuptools.find_packages(),
16 | classifiers=[
17 | "Programming Language :: Python :: 3",
18 | "License :: OSI Approved :: GNU Affero General Public License v3",
19 | "Operating System :: Microsoft :: Windows",
20 | 'Intended Audience :: Developers',
21 | 'Intended Audience :: Information Technology',
22 | 'Intended Audience :: System Administrators',
23 | 'Topic :: Security',
24 | 'Topic :: Internet :: Log Analysis',
25 | 'Environment :: Console',
26 | ],
27 | entry_points={
28 | 'console_scripts': [
29 | 'analyse_obfuscation = analyse_obfuscation.run:parse_arguments'
30 | ],
31 | },
32 | install_requires=['tqdm', 'colorama', 'terminaltables']
33 | )
34 |
--------------------------------------------------------------------------------