[Tutor] application whitelisting

Dave Angel d at davea.name
Fri Sep 21 14:04:03 CEST 2012

On 09/21/2012 06:51 AM, Albert-Jan Roskam wrote:
> Hi,
> My company just started application whitelisting. Now a new version of a (benign!!) dll does not work as it (or rather, its file hash, if I understood it correctly) is not whitelisted. Is there any way I can use the same dll of a newer version? I know this sounds like a hacking request, but my intentions are sincere. My only purpose is to use ctypes to use the functions that are present in the new, but not the old, dll version.
> The code below is probably simplistic/naive, but it's a product of my frustration + curiosity. The strategy was to generate a dll that has the same file hash as the original dll by right-padding it with zero until the desired checksum is found. Why a zero? No idea. ;-)

Two catches I can think of:  1) any decent white-lister would have both
a hashcode and a size for each file it's protecting.  2) On the average,
you'll be adding more bytes to that file than exist in all the disks of
all the computers in the solar system, MANY times over.  (The number in
decimal has something like 40 digits in it)

> PS: I guess virtual environment also cannot be used for this, right?
Not as far as I know, but there are many others much more familiar with
python virtual environment.

If this were my problem, and if i had sufficient rights on the machine,
I'd install a Virtual Machine, and run things there.  But of course
you'd have to get that past the white-listers.

> import hashlib
> import contextlib
> def generateFile(infile, desired_hash, hashtype="md5"):
>     outfile = infile[:-4] + "_adjusted.dll"
>     hashlib_ = hashlib.new(hashtype)
>     with contextlib.nested(open(infile, "rb"), open(outfile, "wb")) as (f_in, f_out):
>         observed_hash = hashlib_(f_in.read())
>         found = observed_hash.hexdigest() == desired_hash
>         counter = 0
>         while True:
>             counter += 1
>             observed_hash.update("0")
>             if found:
>                 f_out.write(f_in.read() + (counter * "0"))

This limits file size to what will fit in memory in a single string.  
Assuming you have millions of petabytes of disk space and only a few
gigabytes of available RAM, you should write a loop for the counter
bytes, perhaps chunking it for compromise between memory and speed.  If
the numbers weren't SO huge, and if you were running on Linux, perhaps a
sparse file would save both a lot of time and a lot of actual disk
space.  I have no experience with them, however -- it'd be fun to learn.

>                 print "Got it: '%s'" f_out.name
>                 break
> infile = r"D:\temp\myown.dll"
> generateFile(infile, '4151e067c17a753fc5c4ec1c507d28c9')
There are known ways to break md5;  it's no longer considered
cryptographically secure.  But a trial and error method will take way
too long and this particular trial and error method will also take way
too much disk space.  Still, I'm surprised the creators of the whitelist
didn't use sha1 or sha256.

Two practical methods:  1) run it on your own machine, not under their
control   2) convince them to add your particular dll to their whitelist.



More information about the Tutor mailing list