{"id":1593,"date":"2025-02-22T21:35:07","date_gmt":"2025-02-22T19:35:07","guid":{"rendered":"https:\/\/macadmin.cz\/?p=1593"},"modified":"2025-02-22T21:35:07","modified_gmt":"2025-02-22T19:35:07","slug":"decrypting-scep-pkioperation-payload","status":"publish","type":"post","link":"https:\/\/macadmin.cz\/?p=1593&lang=en","title":{"rendered":"Decrypting SCEP PKIOperation payload"},"content":{"rendered":"\n<p>MDM systems and the devices they manage do not always provide the necessary level of transparency for troubleshooting unexpected issues. Deploying certificates via SCEP is often one such case, where we may encounter multiple black boxes:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Generation of the SCEP configuration for a managed device by the MDM.<\/li>\n\n\n\n<li>The SCEP client on the managed device generates a CSR and sends it to the CA via a SCEP PKIOperation HTTP POST message.<\/li>\n\n\n\n<li>The CA and its process to generate and sign the certificate.<\/li>\n<\/ol>\n\n\n\n<p>It can be very useful to inspect exactly what the client sends to the server. For PKIOperation, the SCEP client uses a CMS\/PKCS#7 payload with an inner envelope encrypted using the public key from one of the certificates provided by the server in the GetCACert message. If you have access to the corresponding private key, the message can be easily intercepted and decrypted.<\/p>\n\n\n\n<p>\ud83d\ude1e This method won\u2019t work if the SCEP server disregards the RFC 8894 Section 7.10 recommendation to use plain HTTP and instead places the entire exchange inside a TLS transport tunnel &#8211; HTTPS.<\/p>\n\n\n\n<p>\u203c\ufe0fThe guide uses <code>openssl<\/code> command. While the subcommands are pretty standard they might not work on LibreSSL variant (which Apple ships with macOS). You may need to install pure <a href=\"https:\/\/www.openssl.org\">OpenSSL<\/a>.<\/p>\n\n\n\n<p><strong>(1)<\/strong> Use Wireshark or a similar tool to capture the network traffic when the SCEP client requests a certificate from the SCEP server. Interception can be performed on either the client or the server. Locate an HTTP POST message with <code>$operation=PKIOperation<\/code> in the URL and extract the binary content of the packet into a file &#8211; <code>payload.p7b<\/code>.<\/p>\n\n\n\n<p>You can display certificate data  by using following <code>openssl<\/code> command:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nopenssl pkcs7 -inform DER -in payload.p7b -print_certs -text\n<\/pre><\/div>\n\n\n<p><strong>(2)<\/strong> Convert the binary DER format into PEM base64. <code>openssl<\/code> expects PEM by default so we won&#8217;t have explicitly define DER with <code>-inform DER<\/code> for each command. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nopenssl pkcs7 -inform DER -outform PEM -in payload.p7b -out payload.p7m\n<\/pre><\/div>\n\n\n<p><strong>(3)<\/strong> Parse the <code>payload.p7m<\/code> file to see all data not just certificates:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nopenssl asn1parse -in payload.p7m\n<\/pre><\/div>\n\n\n<p>Look for inner PKCS7 envelope defined as <code>pkcs7-data<\/code>: <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n 0:d=0  hl=4 l=3029 cons: SEQUENCE          \n    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData\n   15:d=1  hl=4 l=3014 cons: cont &#x5B; 0 ]        \n   19:d=2  hl=4 l=3010 cons: SEQUENCE          \n   23:d=3  hl=2 l=   1 prim: INTEGER           :01\n   26:d=3  hl=2 l=  15 cons: SET               \n   28:d=4  hl=2 l=  13 cons: SEQUENCE          \n   30:d=5  hl=2 l=   9 prim: OBJECT            :sha256\n   41:d=5  hl=2 l=   0 prim: NULL              \n   43:d=3  hl=4 l=1514 cons: SEQUENCE          \n   47:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data\n   58:d=4  hl=4 l=1499 cons: cont &#x5B; 0 ]        \n   62:d=5  hl=4 l=1495 prim: OCTET STRING      &#x5B;HEX DUMP]:3080060..0000000000000\n<\/pre><\/div>\n\n\n<p><strong>(4)<\/strong> We are interested in the hexadecimal data, which in this example starts at offset 62. This is the encrypted inner PKCS#7 envelope containing the CSR and usually the SCEP challenge secret. Extract this data into a separate file.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nopenssl asn1parse -in payload.p7m -strparse 62 -out inner_payload.p7m \n<\/pre><\/div>\n\n\n<p><strong>(5)<\/strong> Decrypt the inner PKCS7 envelope by using the SCEP server certificate and private key.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nopenssl smime -decrypt -in inner_payload.p7m -inform DER -recip scep_server_certificate.crt -inkey scep_server_certificate.key -out inner_payload_decrypted.p7m\n<\/pre><\/div>\n\n\n<p><strong>(6)<\/strong> And finally read the CSR (Make sure to use OpenSSL and not LibreSSL for this one).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nopenssl req -in inner_payload_decrypted.p7m -noout -text\n<\/pre><\/div>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>MDM systems and the devices they manage do not always provide the necessary level of transparency for troubleshooting unexpected issues. Deploying certificates via SCEP is often one such case, where we may encounter multiple black boxes: It can be very useful to inspect exactly what the client sends to the server. For PKIOperation, the SCEP &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/macadmin.cz\/?p=1593&#038;lang=en\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Decrypting SCEP PKIOperation payload&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1593","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/macadmin.cz\/index.php?rest_route=\/wp\/v2\/posts\/1593","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/macadmin.cz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/macadmin.cz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/macadmin.cz\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/macadmin.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1593"}],"version-history":[{"count":3,"href":"https:\/\/macadmin.cz\/index.php?rest_route=\/wp\/v2\/posts\/1593\/revisions"}],"predecessor-version":[{"id":1596,"href":"https:\/\/macadmin.cz\/index.php?rest_route=\/wp\/v2\/posts\/1593\/revisions\/1596"}],"wp:attachment":[{"href":"https:\/\/macadmin.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/macadmin.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/macadmin.cz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}