Skip to main content

Cryptanalysis and attack library

Project description

samson

https://pypi.org/project/samson-crypto/

DO NOT USE SAMSON'S CRYPTOGRAPHIC PRIMITIVES TO SECURE THINGS

samson is a cryptanalysis and attack library. The intent is to provide a way to quickly prototype and execute cryptographic and side-channel attacks. samson was born from frustration with existing libraries artificially limiting user control over cryptographic primitives.

Many of the biggest cryptographic attacks have been implemented including:

  • CBC/PKCS#1v1.5/OAEP Padding Oracle
  • CRIME/BREACH
  • DSA/ECDSA nonce reuse
  • Stream cipher nonce reuse
  • Subgroup attacks
  • Hash construction attacks (length extension, fixed points, etc)
  • PRNG cracking

samson's key focuses are:

  • Flexibility: Allow the user to freely manipulate internal state
  • Uniformity: Present the user with a uniform interface
  • Convenience: Minimize time spent not directly solving a problem
  • Real world applicability: Build attacks to work generically and include interfaces to common standards

Examples

REPL

[root@localhost ~]# samson


                                                                
  /$$$$$$$  /$$$$$$  /$$$$$$/$$$$   /$$$$$$$  /$$$$$$  /$$$$$$$ 
 /$$_____/ |____  $$| $$_  $$_  $$ /$$_____/ /$$__  $$| $$__  $$
|  $$$$$$   /$$$$$$$| $$ \ $$ \ $$|  $$$$$$ | $$  \ $$| $$  \ $$
 \____  $$ /$$__  $$| $$ | $$ | $$ \____  $$| $$  | $$| $$  | $$
 /$$$$$$$/|  $$$$$$$| $$ | $$ | $$ /$$$$$$$/|  $$$$$$/| $$  | $$
|_______/  \_______/|__/ |__/ |__/|_______/  \______/ |__/  |__/
                                                                
                                                                
                                                                
    v0.2.0 -- https://github.com/wildcardcorp/samson

Python 3.5.3 (11af55503d5c, May 23 2019, 09:37:40)
[PyPy 7.0.0 with GCC 9.1.1 20190503 (Red Hat 9.1.1-1)]
IPython 7.6.0


In [1]: logging.getLogger("samson").setLevel(logging.INFO)                                                                                  
In [2]: RC4(b'what a key!').generate(12) ^ b'Hello world!'                                                                                  
Out[2]: <Bytes: b')\x1f\xb8xW}\xfc\xc5,\x0f\xc3,', byteorder=big>

In [3]: gcm = GCM(Rijndael(Bytes.random(32)).encrypt)  
   ...: data = b"Auth'd data"  
   ...: nonce = Bytes.random(8)  
   ...: ciphertext = gcm.encrypt(nonce=nonce, plaintext=b'Hello world!', data=data)  
   ...: gcm.decrypt(nonce, ciphertext, data)                                                                                                
Out[3]: <Bytes: b'Hello world!', byteorder=big>

In [4]: ciphertext_b = gcm.encrypt(nonce=nonce, plaintext=b'Wait the same nonce?', data=b'') 
   ...:  
   ...: ciphertext_a, tag_a = ciphertext[:-16], ciphertext[-16:] 
   ...: ciphertext_b, tag_b = ciphertext_b[:-16], ciphertext_b[-16:] 
   ...:  
   ...: candidates = ForbiddenAttack().execute(data, ciphertext_a, tag_a, b'', ciphertext_b, tag_b) 
   ...: gcm.H in candidates                                                                                                                 
Out[4]: True

In [5]: bf = Blowfish(b"world's worst key")  
   ...: cbc = CBC(bf.encrypt, bf.decrypt, block_size=8, iv=Bytes.random(8))  
   ...:   
   ...: def oracle_func(attempt):  
   ...:     try:  
   ...:         _ = cbc.decrypt(attempt)  
   ...:         return True  
   ...:     except Exception as _:  
   ...:         return False  
   ...:   
   ...:   
   ...: ciphertext = cbc.encrypt(b'secret plaintext')  
   ...: attack = CBCPaddingOracleAttack(PaddingOracle(oracle_func), block_size=8, iv=cbc.iv)  
   ...: recovered_plaintext = attack.execute(ciphertext)                                                                                    
Blocks cracked: 100%|█████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 14.25blocks/s]
Bytes cracked: 100%|██████████████████████████████████████████████████████████████████████████████████████| 8/8 [00:00<00:00, 226.56bytes/s]

In [6]: recovered_plaintext                                                                                                                 
Out[6]: <Bytes: b'secret plaintext\x08\x08\x08\x08\x08\x08\x08\x08', byteorder=big>

In [7]: Z_p = ZZ/ZZ(49339) 
   ...: Z_p[x](x**5 - x**3 + 1).factor()                                                                                                    
Out[7]: 
{<Polynomial: x**2 + ZZ(34751)*x + ZZ(20606), coeff_ring=ZZ/ZZ(49339)>: 1,
 <Polynomial: x**3 + ZZ(14588)*x**2 + ZZ(39369)*x + ZZ(31211), coeff_ring=ZZ/ZZ(49339)>: 1}

In [8]: F = FF(2, 8) 
   ...: F[36] / F(x + 1)                                                                                                                    
Out[8]: <FiniteFieldElement: val=x**4 + x**3 + x**2, field=F_(2**8)>

In [9]: gcd(F[2], F[10])                                                                                                                    
Out[9]: <FiniteFieldElement: val=x, field=F_(2**8)>

CLI

[root@localhost ~]# samson hash md5 texttohash
0d7e83711c9c8efa135653ef124cc23b

[root@localhost ~]# echo -n "texttohash" | samson hash md5
0d7e83711c9c8efa135653ef124cc23b

[root@localhost ~]# samson hash blake2b texttohash
de92a99c2d5cb8386cada3589b7c70efa27c6d99a3ec1a2f9313258c0e91229f2279ccf68d6766aa20d124ca415dacbb89fb657013de1a2009752084186445a7

[root@localhost ~]# samson hash keccak texttohash --args=r=1044,c=512,digest_bit_size=256
1a568ef9ead0b2a9eeffc1d1e9a688c9153f33719ac5b30a533d1edba0e301b8

[root@localhost ~]# samson pki generate rsa --args=bits=1024
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQChL/Xmka6z8EEiwNC+NXrEs1WHFjUz364hPfFlOMVAmrrWHsAls71U+6
5VybjZPpYOBGcr/M2C6al9W7y18fkf3gAZhfPLvat8OpsfM+ltmlLJ3kTLiVJo2Y+KTPNz
I9nrKUgD/KEcL73kvwJGYL+YwX8YNcbxKv5rNxB0kdW33wIDAQABAoGBAJhMe7ie4AZutO
zEaLfASj6+/8oC5sQbzijkoUi16lLPoEeeiIlXGkbJA4FVd430/81AxccfN4NBin7DBjyX
5H2BmsN3rPGnsCKC+uY4z2+er7B+i2YHgF1K5ymC/8pFV5eU5GTVF0FxZHtviLhDA0p8Fh
liii2JNpM2MDgj7j9BAkEAuzKx+nspNtH+myjMHMRkswLiMIQ8VonOXmH6aBnQekzYvAmy
nCbSlbYohxCYjrPy+a76siSIGK+SO8YpxG7MIQJBANxt8S+ZnrmPZKoWEu3pcn95Fa26Up
qz2L2YemqRid6BlE2/2+cLYMVglEUfhgrqvNCFbwqc1UgeK47065iUA/8CQExZE7+uBZQn
N2k+zWiaLNvZvDi/ZgCBedqCqWdVx/JpbyfZ6K/JIbAPuB3GBgKFn/53gCWxwpQW31RjsN
s9uSECQQDOpkN2XI5xZ/z3d7pHUJQG7X1lYUgPwItxM4GQZuDZuKFQQo3mDMSsRd667tK7
aVWaJ33ydRV+hspPO02jvSABAkAPaMHmQcEN8c8bOWc5VjH8kxcV5iHUw88WH9hEKpHTsk
j+LYTu11aOZXFh4dmw5jHd1gjA4bD24c0f5NN7vQLJ
-----END RSA PRIVATE KEY-----

[root@localhost ~]# samson pki generate rsa --args=bits=128,p=7 --encoding=pkcs8
-----BEGIN PRIVATE KEY-----
MFMCAQAwDQYJKoZIhvcNAQEBBQAEPzA9AgEAAgkEI+1gRNRD9i8CAwEAAQIJAIiZ98pCij
jhAgEHAgkAl2sNwLCb/pkCAQUCCQCImffKQoo44QIBBQ==
-----END PRIVATE KEY-----

[root@localhost ~]# samson pki generate rsa --args=bits=256 --pub
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAKItLmP4OG4LIOgWZRt+MFOifSHsoow9NcwAwt
p3Xx0NAgMBAAE=
-----END PUBLIC KEY-----

[root@localhost ~]# samson pki generate ecdsa --args=curve=nistp256 --encoding=openssh
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQnJDxj9BKhFg50vqrwzDGtJtmmlhK3
E1l1k6L1eHlLO9MGu2JnTzV6tRFNDuCqs9QkCUDkm3sTYq+9tspJ9ISLAAAAsJ0TFlidEx
ZYAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCckPGP0EqEWDnS+
qvDMMa0m2aaWErcTWXWTovV4eUs70wa7YmdPNXq1EU0O4Kqz1CQJQOSbexNir722ykn0hI
sAAAAhALJ58WavKVYz2fG3koYq3Pthpmg9MJVmStjRyZMYqCrmAAAAEG5vaG9zdEBsb2Nh
bGhvc3QBAgMEBQYH
-----END OPENSSH PRIVATE KEY-----

[root@localhost ~]# samson pki generate eddsa --args=curve=ed25519 --encoding=openssh --pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG0Ru2OL3mSV1aOopjhcxK+pg6fTYcyxOfBy4cjJQ0T4 nohost@localhost

[root@localhost ~]# openssl genrsa 128 | samson pki parse rsa
Generating RSA private key, 128 bit long modulus
.+++++++++++++++++++++++++++
..+++++++++++++++++++++++++++
e is 65537 (0x010001)
<RSA: bits=128, p=18204634713468071783, q=14777058483132963961, e=65537, n=269010951824990204830693900060300012463, phi=134505475912495102398856103431849488360, d=14600484545241469070379515690589701393, alt_d=14600484545241469070379515690589701393>

[root@localhost ~]# samson pki generate ecdsa --args=curve=p521 --pub --encoding=x509_cert --encoding-args=ca=1,serial_number=666,issuer=#'CN=hiya,O=hiya-corp,L=Rack City'#
-----BEGIN CERTIFICATE-----
MIICAzCCAV6gAwIBAgICApowEQYIKoZIzj0EAwIGBSuBBAAjMDcxDTALBgNVBAMTBGhpeW
ExEjAQBgNVBAoTCWhpeWEtY29ycDESMBAGA1UEBwwJUmFjayBDaXR5MB4XDTE5MDMxNTA5
MDMwMloXDTIwMDMxNTA5MDMwMlowDTELMAkGA1UEAxMCY2EwgZswEAYHKoZIzj0CAQYFK4
EEACMDgYYABADfi2+eDb9LhtBKZx61bQEG/2uunKr64EGv5+CBNGQEz4RL8fC6wXG14vj0
m+It8FtADxeyud+59/MpZFk34HH4UgCvec9lWIGC/VspYySEtMyiMQGxFcGjSF30xMHmxV
VdtCd0lwpno8swFynZbKyrTFpQPRE2xQKKi/dUh1MGBYeAhoECBKCCAgSwozIwMDAdBgNV
HQ4EFgQUpFMCF9swcVSxvdGnBNrfB4PRdcIwDwYDVR0TAQH/BAUwAwEB/zARBggqhkjOPQ
QDAgYFK4EEACMDgYsCwgYcCQgCtM/WKF1HGFVNXRvL+38bFgbtjkAc6lkgnv76bdngWhZj
KzxOGlBrUMD0vXbjp0wpDnpynBxYXNZxHIrERMolw1wJBS72VR5m4ubujrW2ynM5p9hoc3
0SK8pZp5HLipmI9gjF/ywqZZGskyFt/nK4wfU3CaoOPOxI86AC5nbwn6f5Y4wA
-----END CERTIFICATE-----

Example Use Cases

  • Auditing infrastructure
  • Modelling existing systems
  • Solving/creating CTFs

Testing Environment

  • Runtime: PyPy 7.0.0 (Python 3.5.3)
  • Architecture: Linux 5.1.18-300.fc30.x86_64_64 #1 SMP
  • OS: Fedora Security Lab (Fedora release 30)

Installation

Recommended OS is Fedora and recommended Python implementation is PyPy

Note that PyPy may not install samson's scripts to PATH.

Workarounds include:

  • Calling samson from where PyPy did install it
  • Installing samson with CPython's pip as well

samson's samson script tries to call CPython for CLI commands anyway due to the load times of PyPy.

RHEL derivatives (tested on Fedora Security Lab 30)

sudo dnf -y install pypy3 pypy3-devel
pypy3 -m ensurepip
pypy3 -m pip install samson-crypto

Debian derivatives (tested on Kali Linux 2019.2 64-bit)

Debian/Ubuntu/Kali don't want you to install pip with ensurepip, but they only provide the package for CPython. The following is a workaround that creates a virtualenv to prevent screwing with the system's pip.

apt-get -y install pypy3 pypy3-dev
pypy3 -m venv myvenv --without-pip --system-site-packages
wget https://bootstrap.pypa.io/get-pip.py
./myvenv/bin/pypy3-c ./get-pip.py
./myvenv/bin/pypy3-c -m pip install samson-crypto

Which can then by accessed like

./myvenv/bin/pypy3-c ./myvenv/bin/samson-py

Performance

samson's primitives aren't the fastest nor were they meant to be. If you're concerned about performance, you have a couple of options:

  • Use primitives from a faster library (e.g. pycrypto)
  • Use PyPy instead of CPython

Since samson mostly calls Python, PyPy offers large speed-ups. However, the latest stable version of PyPy works with Python 3.5 while SHA3 was introduced in 3.6. samson's SHA3 will still work, but the tests will fail.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

samson-crypto-0.2.1.dev0.tar.gz (5.0 MB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page