Last Updated: 2018-12-15 19:27:12 UTC
by Didier Stevens (Version: 1)
I received some questions about the de-DOSfuscation I did with Python in my last diary entry: "Yet Another DOSfuscation Sample".
From a reader submitted malicious document, I extracted the following command:
This DOS command uses a for loop to convert the numbers in yellow to a new command (PowerShell). The numbers are not converted to characters using the ASCII table, but using a custom table that is provided with variable eA0 (the characters in red).
An interpreter like Python can be used to do the conversion. Here is how I did this, step by step:
First I put the numbers in a list, that I let Python print:
Remark that I did not include the last number present in the list (86): this number indicates the end of the list and is not to be converted to a character (this would cause an index error if I tried).
Next I add a "list comprehension" to the Python statement: [number for number in [... numbers ...]]:
With this list comprehension, I can perform a calculation with each number in the list, by replacing the expression number by a more complex expression. What I do, is use number to index the "red string": ['''red string'''[number] for number in [... numbers ...]]:
Also, remark that the "red string" contains a single quote, hence I can not use a single quote to delimit the string: that's why I use 3 single quoutes: '''red string'''.
The result is a list of characters. I can now concatenate all those characters with ''.join(...):
Let me illustrate a couple of errors you might encounter when you apply this method.
First, you get this when you include the last number (86):
"string index out of range": 86 is bigger than the largest index that can be used on the "red string", hence I get this index error. 86 is not an "index number", but a "stop number".
This is the error you get if you use single quotes to delimit the "red string":
The single quote inside the "red string" is taken as the closing single quote of the string, and the remainder of the string is parsed as a Python expression, which fails.
Finally, I updated my numbers-to-string tool with option -t, so that you don't have to write a long Python statement to do the decoding, but can use my numbers-to-string tool instead: