triggerflow
play

TRIGGERFLOW Regression Testing by Advanced Execution Path Inspection - PowerPoint PPT Presentation

default TRIGGERFLOW Regression Testing by Advanced Execution Path Inspection 20 June 2019 Iaroslav Gridin Cesar Pereida Garca Nicola Tuveri Billy Bob Brumley Tampere University, Tampere, Finland 1 / 15 default Outline Analysis


  1. default TRIGGERFLOW Regression Testing by Advanced Execution Path Inspection 20 June 2019 Iaroslav Gridin Cesar Pereida García Nicola Tuveri Billy Bob Brumley Tampere University, Tampere, Finland 1 / 15

  2. default Outline ◮ Analysis subject: OpenSSL ◮ Trigger fl ow ◮ Finding bugs using it 2 / 15

  3. default OpenSSL ◮ I ndustry standard cryptographic library ◮ Has timing leak problems ◮ Countermeasures in place but not perfect 3 / 15

  4. default Timing leaks Client Server ClientHello ServerHello ◮ Some cryptographic operations Certificate execution time heavily depends on ServerKeyExchange arguments ServerHelloDone ◮ Can guess the ballpark of a number ClientKeyExchange by watching the time ◮ Critical operations are padded to [ChangeCipherSpec] counteract this Finished ◮ CT and non-CT function variants, for [ChangeCipherSpec] security or speed Finished time time 4 / 15

  5. default Timing leak countermeasure ◮ A fl ag (true/false variable) set on big numbers to ensure they are handled in constant time ◮ Requires both proper setting and proper handling ◮ Several bugs have been discovered in its usage: ◮ CVE-2016-2178 ( fl ag not propagated) ◮ CVE-2016-7056 ( fl ag not set) ◮ CVE-2018-0737 ( fl ag not set/set wrongly/not checked) struct bignum_st { BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ int top; /* Index of last used d +1. */ /* The next are internal book keeping for bn_expand. */ int dmax; /* Size of the d array. */ int neg; /* one if the number is negative */ /* # define BN_FLG_CONSTTIME 0x04 */ int flags; 5 / 15

  6. default Tracking down non-constant time operations on sensitive data ◮ Set up a breakpoint in debugger and run the program ◮ Prone to false positives ◮ This is the full graph of code paths leading up to certain non-CT codepaths in OpenSSL openssl dgst -sha512 openssl rsautl -decrypt openssl genpkey -algorithm openssl dgst -sha512 openssl genpkey -algorithm openssl dgst -sha512 openssl genpkey -algorithm openssl dgst -sha512 openssl genpkey -algorithm openssl dgst -sha512 openssl genpkey -algorithm openssl dgst -sha512 openssl genpkey -algorithm openssl dgst -sha512 openssl genpkey -algorithm openssl dgst -sha512 openssl dgst -sha512 openssl req -x509 -new -encrypt -in data -binary openssl cms -aes128 openssl cms -decrypt -sign private_key.pem -inkey private_key.pem EC -out prime192v1.pem -sign prime192v1.pem EC -out secp224r1.pem -sign secp224r1.pem -out EC -out prime256v1.pem -sign prime256v1.pem EC -out secp384r1.pem -sign secp384r1.pem -out EC -out secp521r1.pem -sign secp521r1.pem -out EC -out secp256k1.pem -sign secp256k1.pem -out EC -out sect233r1.pem -sign sect233r1.pem -out openssl genpkey -paramfile -sign dsa.pem -out lsb-release.sig openssl ec -in ec.params -key ec.key -subj '/C=FI/ST=Uusimaa/L=Helsinki/CN=localhost' -out lsb-release.pem -inkey ec.key -in lsb-release.pem -out lsb-release.sig -in lsb-release.bin -out -pkeyopt ec_paramgen_curve:prime192v1 -out lsb-release.sig -pkeyopt ec_paramgen_curve:secp224r1 lsb-release.sig data -pkeyopt ec_paramgen_curve:prime256v1 -out lsb-release.sig -pkeyopt ec_paramgen_curve:secp384r1 lsb-release.sig data -pkeyopt ec_paramgen_curve:secp521r1 lsb-release.sig data -pkeyopt ec_paramgen_curve:secp256k1 lsb-release.sig data -pkeyopt ec_paramgen_curve:sect233r1 lsb-release.sig data dsa.params -out dsa.pkey data -pubout -out ec.pkey -config openssl.cnf -out -outform PEM -recip cert.pem -inform PEM -out lsb-release data lsb-release data data cert.pem -keyopt ecdh_kdf_md:sha256 -recip cert.pem main() apps/openssl.c:181 do_cmd() apps/openssl.c:476 rsautl_main() dgst_main() genpkey_main() genpkey_main() cms_main() cms_main() cms_main() dgst_main() req_main() ec_main() apps/rsautl.c:250 apps/dgst.c:384 apps/genpkey.c:163 apps/genpkey.c:152 apps/cms.c:708 apps/cms.c:522 apps/cms.c:733 apps/dgst.c:242 apps/req.c:451 apps/ec.c:199 RSA_private_decrypt() do_fp() PEM_write_bio_PrivateKey() EVP_PKEY_keygen() genpkey_main() load_cert() load_key() PEM_read_bio_ECPrivateKey() crypto/rsa/rsa_crpt.c:43 apps/dgst.c:443 crypto/pem/pem_pkey.c:99 crypto/evp/pmeth_gn.c:107 apps/genpkey.c:102 apps/apps.c:616 apps/apps.c:711 crypto/pem/pem_all.c:152 rsa_ossl_private_decrypt() EVP_DigestSignFinal() PEM_write_bio_PKCS8PrivateKey() pkey_dsa_keygen() pkey_ctrl_string() PEM_read_bio_X509_AUX() PEM_read_bio_PrivateKey() PEM_read_bio_PrivateKey() crypto/rsa/rsa_ossl.c:426 crypto/evp/m_sigver.c:127 crypto/pem/pem_pk8.c:46 crypto/dsa/dsa_pmeth.c:235 apps/apps.c:1847 crypto/pem/pem_xaux.c:18 crypto/pem/pem_pkey.c:44 crypto/pem/pem_pkey.c:83 crypto/evp/pmeth_fn.c:66 EVP_PKEY_sign() crypto/pem/pem_pk8.c:72 do_pk8pkey() crypto/dsa/dsa_key.c:22 DSA_generate_key() EVP_PKEY_CTX_ctrl_str() crypto/evp/pmeth_lib.c:352 crypto/pem/pem_oth.c:31 PEM_ASN1_read_bio() crypto/evp/evp_pkey.c:43 EVP_PKCS82PKEY() crypto/asn1/d2i_pr.c:46 d2i_PrivateKey() pkey_rsa_sign() pkey_dsa_sign() pkey_ec_sign() EVP_PKEY2PKCS8() dsa_builtin_keygen() dsa_priv_decode() d2i_X509_AUX() old_ec_priv_decode() crypto/rsa/rsa_pmeth.c:147 crypto/dsa/dsa_pmeth.c:82 crypto/ec/ec_pmeth.c:119 crypto/evp/evp_pkey.c:71 crypto/dsa/dsa_key.c:58 crypto/dsa/dsa_ameth.c:183 crypto/x509/x_x509.c:118 crypto/ec/ec_ameth.c:446 RSA_sign() DSA_sign() ECDSA_sign() eckey_priv_encode() eckey_priv_encode() BN_mod_exp() d2i_X509() d2i_ECPrivateKey() crypto/rsa/rsa_sign.c:103 crypto/dsa/dsa_asn1.c:115 crypto/ec/ecdsa_sign.c:32 crypto/ec/ec_ameth.c:251 crypto/ec/ec_ameth.c:240 crypto/bn/bn_exp.c:154 crypto/x509/x_x509.c:86 crypto/ec/ec_asn1.c:939 RSA_private_encrypt() DSA_do_sign() ECDSA_sign_ex() i2d_ECPrivateKey() BN_mod_exp_mont() pkey_ec_ctrl_str() ASN1_item_d2i() crypto/rsa/rsa_crpt.c:37 crypto/dsa/dsa_sign.c:18 crypto/ec/ecdsa_sign.c:40 crypto/ec/ec_asn1.c:1044 crypto/bn/bn_exp.c:320 crypto/ec/ec_pmeth.c:359 crypto/asn1/tasn_dec.c:113 rsa_ossl_private_encrypt() dsa_do_sign() ossl_ecdsa_sign() EC_KEY_key2buf() ASN1_item_ex_d2i() crypto/rsa/rsa_ossl.c:285 crypto/dsa/dsa_ossl.c:97 crypto/ec/ecdsa_ossl.c:23 crypto/ec/ec_key.c:523 crypto/asn1/tasn_dec.c:123 dsa_sign_setup() ECDSA_do_sign_ex() EC_POINT_point2buf() asn1_item_embed_d2i() crypto/dsa/dsa_ossl.c:270 crypto/ec/ecdsa_sign.c:24 crypto/ec/ec_oct.c:158 crypto/asn1/tasn_dec.c:362 rsa_ossl_private_encrypt() ossl_ecdsa_sign_sig() EC_POINT_point2oct() EVP_PKEY_CTX_ctrl() asn1_template_ex_d2i() crypto/rsa/rsa_ossl.c:310 crypto/ec/ecdsa_ossl.c:261 crypto/ec/ec_oct.c:102 crypto/evp/pmeth_lib.c:328 crypto/asn1/tasn_dec.c:498 dsa_mod_inverse_fermat() ecdsa_sign_setup() ec_GFp_simple_point2oct() asn1_template_noexp_d2i() crypto/dsa/dsa_ossl.c:424 crypto/ec/ecdsa_ossl.c:126 crypto/ec/ecp_oct.c:214 crypto/asn1/tasn_dec.c:623 crypto/rsa/rsa_ossl.c:770 rsa_ossl_mod_exp() EC_POINT_get_affine_coordinates_GFp() crypto/ec/ec_lib.c:764 crypto/ec/ec_pmeth.c:223 pkey_ec_ctrl() crypto/asn1/tasn_dec.c:412 asn1_item_embed_d2i() rsa_ossl_mod_exp() ec_GFp_simple_point_get_affine_coordinates() pubkey_cb() eckey_priv_decode() crypto/rsa/rsa_ossl.c:624 crypto/ec/ecp_smpl.c:558 crypto/x509/x_pubkey.c:46 crypto/ec/ec_ameth.c:197 dsa_sign_setup() ec_GFp_mont_field_inv() x509_pubkey_decode() EC_GROUP_new_from_ecpkparameters() crypto/dsa/dsa_ossl.c:262 crypto/ec/ecp_mont.c:242 crypto/x509/x_pubkey.c:124 crypto/ec/ec_asn1.c:845 dsa_sign_setup() BN_mod_exp_mont() BN_mod_exp_mont() eckey_pub_decode() crypto/dsa/dsa_ossl.c:231 crypto/bn/bn_exp.c:359 crypto/bn/bn_exp.c:327 crypto/ec/ec_ameth.c:148 BN_MONT_CTX_set_locked() eckey_type2param() crypto/bn/bn_mont.c:448 crypto/ec/ec_ameth.c:116 BN_mod_exp_mont_consttime() EC_GROUP_new_by_curve_name() crypto/bn/bn_exp.c:664 crypto/ec/ec_curve.c:3097 ec_group_new_from_data() ec_group_new_from_data() crypto/ec/ec_curve.c:3023 crypto/ec/ec_curve.c:3060 EC_GROUP_new_curve_GFp() crypto/ec/ec_cvt.c:67 EC_GROUP_set_generator() crypto/ec/ec_lib.c:294 ec_group_new_from_data() EC_GROUP_set_curve_GFp() crypto/ec/ec_curve.c:3018 crypto/ec/ec_lib.c:416 ec_GFp_mont_group_set_curve() ec_precompute_mont_data() crypto/ec/ecp_mont.c:158 crypto/ec/ec_lib.c:990 BN_MONT_CTX_set() crypto/bn/bn_mont.c:349 BN_mod_inverse() crypto/bn/bn_gcd.c:129 int_bn_mod_inverse() crypto/bn/bn_gcd.c:161 6 / 15

  7. default Trigger fl ow demo ◮ Now, live application of Trigger fl ow will be demonstrated 7 / 15

  8. default Trigger fl ow ◮ Runs speci fi ed commands while watching execution paths ◮ Written in Ruby, uses GDB for execution tracking ◮ Works with any GDB-supported language ◮ Not restricted to OpenSSL or constant-time analysis, could be used to detect execution of any kind of interesting code ◮ Open source, M I T license ◮ https://gitlab.com/nisec/triggerflow ## DSA: generate parameters (not secret) exec openssl genpkey -genparam -algorithm DSA -out dsa.params <...> ## DSA: generate private key debug openssl genpkey -paramfile dsa.params -out dsa.pkey exec cat dsa.params dsa.pkey > dsa.pem ## DSA: sign debug openssl dgst -sha512 -sign dsa.pem -out lsb-release.sig data 8 / 15

  9. default Trigger fl ow rules ◮ Allows advanced rules like ignoring codepaths /* code before */ TRIGGERFLOW_POI if (a % 2 == 0) // /* code after */ if (something) { a = publickey; // TRIGGERFLOW_IGNORE_GROUP ec_publickey } call_suspicious_code(a) // TRIGGERFLOW_IGNORE_GROUP ec_publickey /* code before */ call_suspicious_code(a) // TRIGGERFLOW_POI_IF a.private() /* code after */ int call_suspicious_code( int a) { // TRIGGERFLOW_POI /* something interesting with a */ } call_suspicious_code(public_key) // TRIGGERFLOW_IGNORE 9 / 15

Recommend


More recommend