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 most prevalent cryptographic attacks have been implemented including:
- CBC/PKCS#1v1.5/OAEP Padding Oracle
- CRIME/BREACH
- DSA/ECDSA nonce reuse
- Stream cipher nonce reuse
- Subgroup confinement 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
The REPL's prompt provides information about the execution context and is formatted as such:
┌──(samson)─[EXECUTION NUMBER]─[CURRENT TIME]─[LAST EXECUTION TIME]─[USER@HOSTNAME]─[CWD]
└─$
Usage of the REPL:
╰─>$ samson
/%%%%%%% /%%%%%% /%%%%%%/%%%% /%%%%%%% /%%%%%% /%%%%%%%
/%%_____/ |____ %%| %%_ %%_ %% /%%_____/ /%%__ %%| %%__ %%
| %%%%%% /%%%%%%%| %% \ %% \ %%| %%%%%% | %% \ %%| %% \ %%
\____ %% /%%__ %%| %% | %% | %% \____ %%| %% | %%| %% | %%
/%%%%%%%/| %%%%%%%| %% | %% | %% /%%%%%%%/| %%%%%%/| %% | %%
|_______/ \_______/|__/ |__/ |__/|_______/ \______/ |__/ |__/
v0.3.0 -- https://github.com/wildcardcorp/samson
Python 3.6.9 (78d4c48fa091, Apr 30 2020, 07:55:31)
[PyPy 7.3.1 with GCC 10.0.1 20200328 (Red Hat 10.0.1-0.11)]
IPython 7.16.1
┌──(samson)─[1]─[15:48:44]─[0:00:00.001813]─[vixen@localhost]─[/home/vixen]
└─$ logging.getLogger("samson").setLevel(logging.INFO)
┌──(samson)─[2]─[15:48:45]─[0:00:00.000970]─[vixen@localhost]─[/home/vixen]
└─$ # Using stream ciphers and byte manipulation
..: RC4(b'what a key!').generate(12) ^ b'Hello world!'
<Bytes: b')\x1f\xb8xW}\xfc\xc5,\x0f\xc3,', byteorder='big'>
┌──(samson)─[3]─[15:48:48]─[0:00:00.008846]─[vixen@localhost]─[/home/vixen]
└─$ # Example of AES-GCM-256
..: gcm = GCM(Rijndael(Bytes.random(32)))
..: 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)
<Bytes: b'Hello world!', byteorder='big'>
┌──(samson)─[4]─[15:48:53]─[0:00:00.027646]─[vixen@localhost]─[/home/vixen]
└─$ # Forbidden attack on GCM
..: 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 = GCM.nonce_reuse_attack(data, ciphertext_a, tag_a, b'', ciphertext_b, tag_b)
..: gcm.H in [auth_key for auth_key, tag_mask in candidates]
True
┌──(samson)─[5]─[15:49:09]─[0:00:12.005071]─[vixen@localhost]─[/home/vixen]
└─$ # CBC padding oracle attacks on arbitrary block ciphers
..: bf = Blowfish(b"world's worst key")
..: cbc = CBC(bf, iv=Bytes.random(8))
..:
..: def oracle_func(attempt):
..: try:
..: cbc.decrypt(attempt)
..: return True
..: except Exception:
..: return False
..:
..: ciphertext = cbc.encrypt(b'secret plaintext')
..: attack = CBCPaddingOracleAttack(PaddingOracle(oracle_func), block_size=8)
..: recovered = attack.execute(cbc.iv + ciphertext)
Bytes cracked: 100%|████████████████████████████████████████████████████████████████| 8/8 [00:00<00:00, 8.97bytes/s]
Bytes cracked: 100%|████████████████████████████████████████████████████████████████| 8/8 [00:00<00:00, 9.61bytes/s]
Bytes cracked: 100%|████████████████████████████████████████████████████████████████| 8/8 [00:00<00:00, 9.33bytes/s]
Blocks cracked: 100%|███████████████████████████████████████████████████████████████| 3/3 [00:02<00:00, 1.13blocks/s]
┌──(samson)─[6]─[15:49:13]─[0:00:02.809287]─[vixen@localhost]─[/home/vixen]
└─$ recovered
<Bytes: b'secret plaintext\x08\x08\x08\x08\x08\x08\x08\x08', byteorder='big'>
┌──(samson)─[7]─[15:49:15]─[0:00:00.012327]─[vixen@localhost]─[/home/vixen]
└─$ # Fully-fledged computer algebra system
..: Z_p = ZZ/ZZ(49339)
..: P = Z_p[x]
..: (x**5 - x**3 + 1).factor()
<Factors: factors=SortedDict({<Polynomial: x^2 + (34751)*x + 20606, coeff_ring=ZZ/(ZZ(49339))>: 1, <Polynomial: x^3 + (14588)*x^2 + (39369)*x + 31211, coeff_ring=ZZ/(ZZ(49339))>: 1})>
┌──(samson)─[8]─[15:49:19]─[0:00:00.338368]─[vixen@localhost]─[/home/vixen]
└─$ # Strong support for elliptic curves and constructing curves with specific properties
..: E = EllipticCurve.generate_curve_with_trace(256, 1)
..: G = E.find_gen()
..: d = random_int(G.order())
..: Q = G*d
..: phi = E.additive_transfer_map()
..: (phi(Q)/phi(G))[0] == d
True
┌──(samson)─[9]─[15:49:33]─[0:00:07.236282]─[vixen@localhost]─[/home/vixen]
└─$ # Discrete logarithm functions automatically select fastest algorithms
..: Q/G
38120689741865273838011422678879489970102804037838036905741887846548120785636
# Hash the text 'texttohash' with MD5
[root@localhost ~]# samson hash md5 texttohash
0d7e83711c9c8efa135653ef124cc23b
# Hash the text 'texttohash' with MD5 from STDIN
[root@localhost ~]# echo -n "texttohash" | samson hash md5
0d7e83711c9c8efa135653ef124cc23b
# Hash the text 'texttohash' with BlAKE2b
[root@localhost ~]# samson hash blake2b texttohash
de92a99c2d5cb8386cada3589b7c70efa27c6d99a3ec1a2f9313258c0e91229f2279ccf68d6766aa20d124ca415dacbb89fb657013de1a2009752084186445a7
# Hash the text 'texttohash' with Keccak instantiated with arguments
[root@localhost ~]# samson hash keccak texttohash --args=r=1044,c=512,digest_bit_size=256
1a568ef9ead0b2a9eeffc1d1e9a688c9153f33719ac5b30a533d1edba0e301b8
# Factor an integer and display progress bar
[root@localhost ~]# samson factor --args=visual=True 282265139124268609605114400022085050598
factor: Bits factored: 63%|██████████████████████████████▍ | 80.95/127.73 [00:00<00:00, 568.47bit/s]
2 * 3 * 239 * 94933 * 3394031 * 5122385479 * 119262202443691
# Generate a 1024-bit RSA key (default private, default PKCS1 encoding)
[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-----
# Generate a 128-bit RSA key, set `p` to 7, and encode using PKCS8
[root@localhost ~]# samson pki generate rsa --args=bits=128,p=7 --encoding=pkcs8
-----BEGIN PRIVATE KEY-----
MFMCAQAwDQYJKoZIhvcNAQEBBQAEPzA9AgEAAgkEI+1gRNRD9i8CAwEAAQIJAIiZ98pCij
jhAgEHAgkAl2sNwLCb/pkCAQUCCQCImffKQoo44QIBBQ==
-----END PRIVATE KEY-----
# Generate a 256-bit RSA key and return the public key
[root@localhost ~]# samson pki generate rsa --args=bits=256 --pub
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAKItLmP4OG4LIOgWZRt+MFOifSHsoow9NcwAwt
p3Xx0NAgMBAAE=
-----END PUBLIC KEY-----
# Generate an ECDSA key with the NIST P-256 curve and encode for OpenSSH
[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-----
# Generate an EdDSA key with the Ed25519 curve, encode for OpenSSH, and output public key
[root@localhost ~]# samson pki generate eddsa --args=curve=ed25519 --encoding=openssh --pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG0Ru2OL3mSV1aOopjhcxK+pg6fTYcyxOfBy4cjJQ0T4 nohost@localhost
# Parse an RSA key from STDIN
[root@localhost ~]# openssl genrsa 512 | samson pki parse rsa
Generating RSA private key, 512 bit long modulus (2 primes)
.....+++++++++++++++++++++++++++
......+++++++++++++++++++++++++++
e is 65537 (0x010001)
<PKCS1RSAPrivateKey: key=<RSA: bits=512, e=65537, d=6296796031568503581556207616280967962807076376387317648643496104387929361057440965008899658110684774371838723815081555180232276065759547740996145801493 (501 bits), alt_d=4861274696277509906222134778771643290062658423191630102815100016025231770956604600068400157229874779574456479225803315459261204941026741668937047997477337 (511 bits), p=106617888174141873449919799002923479536903497687797534434241495625009665443277, q=91072482927370968074071590901226339936836118841645415967348631148765293177239, n=9709955800491882805281157142310724644199702693630485570332913039841687683191292008577884027985052180990073430823450207424691388280323554369165878661972203 (512 bits), phi=4854977900245941402640578571155362322099851346815242785166456519920843841595547159103391257571764094800084640501988233904080972664960982121196051851675844 (511 bits)>>
# Parse key from file '/tmp/rsa', auto detect key type, and re-encode it as an X509 certificate
[root@localhost ~]# samson pki parse auto @/tmp/rsa --encoding x509_cert --pub
-----BEGIN CERTIFICATE-----
MIIBEDCBu6ADAgECAgEAMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNVBAMTAmNhMB4XDTIwMT
AyOTEyMDQzMloXDTIxMTAyOTEyMDQzMlowDTELMAkGA1UEAxMCY2EwXDANBgkqhkiG9w0B
AQEFAANLADBIAkEA6wreAbl8FoaIP7tEMLPKKgZxNLR5GU3NLWX2VdLcRDjCln8jU7ko1V
l+NYf1Ks6InaBiz6WxWsEQJRptN1b17wIDAQABgQIACoICAAswDQYJKoZIhvcNAQELBQAD
QQBz0kaxh5y44pyFu4JqiTcdf85K/LOjaHozvR7dX4D+pWYLTJpbinrH2/DPgMqV5+ac+h
tOJeM1ywT1m2oHLaQN
-----END CERTIFICATE-----
# Generate an ECDSA key with the NIST P-521 curve, add the certificate authority attribute, set its serial number to 666, and set its issuer to 'CN=hiya,O=hiya-corp,L=Rack City'
[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-----
# Generate an ECDSA key with the secp224k1 curve, encode it as an X509 certificate signing request, and output its public key
[root@localhost ~]# samson pki generate ecdsa --args=curve=secp224k1 --encoding X509_CSR --pub
-----BEGIN CERTIFICATE REQUEST-----
MIG9MGYCAQAwDTELMAkGA1UEAxMCY2EwUDAQBgcqhkjOPQIBBgUrgQQAIAM8AAQAFY8I6Z
P7vKDMqRYWHaPfK3c9sBIn5hLWt6hhowAVBF1H8tJBL2yHiERYfppAvpOHUomYzyMNg9KY
oAAwEQYIKoZIzj0EAwIGBSuBBAAgA0AAMD0CHBEMaqmfHfRYZV/O/iLFq6PfFh0sFl2f9n
E1SLYCHQCAP23HzLH7frnf8diYX7fJDgNGhY9Xcf8e0iJm
-----END CERTIFICATE REQUEST-----
# Generate a Diffie-Hellman key and encode it as a DNSSEC key
[root@localhost ~]# samson pki generate dh --encoding dns_key
Private-key-format: v1.3
Algorithm: 2 (DH)
Prime(p): ///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjftawv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXTmmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhghfDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq5RXSJhiY+gUQFXKOWoqsqmj//////////w==
Generator(g): Ag==
Private_value(x): U+i2s0/q1S/TqGaLKVem8nopEIRnRUwMUr0hB/rsbrO930OCS7/ORezcFlzabnI8oAwX7rbjY//7Bc9j15FSrhptdG2XDKScz7BMEqmNYh4UFbnghXvnsqzPMxXHocEsqT4OXYeaCIkYAMoPZRJp7B50NalYz+x9VMZ1kwWSEqlC+LpzDjG5go+OOkURxQmWQMTpp5iyQjQkzu1vvuUVd3shg1QEOi5MUkrxAiA3KdrZSzT3Duzleiuzutj9D5o7LOhJ5P/rF/sPwJaIHVS1rc7+u63JcNLVbQzPjFSPkLRh3fFCUSMhP8rc0yTgxv15zqgbLm2ewpL0Cfkd7C9l1Q==
Public_value(y): A1U638iDLE+BDe7nQZ3ncHI6UDKRFWF03QJJHPhuOlvbut0vfRwoDgdERADKKzvSwZ7nauVT06c95UuEVOzVKU2aOVVF8zlAZJsKXyckEjtUHcwUF6lXzh5EjZ915KAp9LyoExSou5IVHXzjb8cy+cnG4GBWUMX8LZZ57FtkavSoZ7FLKItek1pVhleoUbjJcLo58lH9GbJqBj0oTvURe3wI4VNd52dhm9cUd4ZfnhGQzNm8YvekdW94W4MHLJ5BwV50lRMLvfWMYdfUJ+Gdd3CtCx0ge1I6Brm4YZF1Er8SM7IxuDrGeOcC+NPT92XQHqUl1tn4r9X31LGPam9ZIg==
Created: 20201029163524
Publish: 20201029163524
Activate: 20201029163524
- Auditing infrastructure
- Modelling existing systems
- Solving/creating CTFs
- Runtime: PyPy 7.3.1 (Python 3.6.9)
- Architecture: Linux 5.11.22-100.fc32.x86_64 #1 SMP
- OS: Fedora Security Lab (Fedora release 32)
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.
sudo dnf -y install pypy3 pypy3-devel
pypy3 -m ensurepip
pypy3 -m pip install samson-crypto
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 -y install pypy3
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
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.