{"id":601,"date":"2023-08-20T15:33:20","date_gmt":"2023-08-20T13:33:20","guid":{"rendered":"https:\/\/koban3.me\/?p=601"},"modified":"2023-08-20T15:44:40","modified_gmt":"2023-08-20T13:44:40","slug":"steganografia-e-bypass-ajax","status":"publish","type":"post","link":"https:\/\/koban3.me\/index.php\/2023\/08\/20\/steganografia-e-bypass-ajax\/","title":{"rendered":"Steganografia e bypass Ajax"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"601\" class=\"elementor elementor-601\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-92db217 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"92db217\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-95b2009\" data-id=\"95b2009\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-768754e elementor-widget elementor-widget-heading\" data-id=\"768754e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-large\">Di cosa si tratta?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b097dba elementor-widget elementor-widget-text-editor\" data-id=\"b097dba\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Riprendendo l&#8217;idea di inviare dati a un server esterno simulando il caricamento di un&#8217;immagine [<a style=\"background-color: #ffffff;\" href=\"https:\/\/koban3.me\/index.php\/2023\/06\/12\/svg-keylogger\/\">Leggi l&#8217;articolo &#8220;SVG Keylogger&#8221;<\/a>], ho deciso di estendere la tecnica per riuscire anche a ricevere dati da remoto senza usare le normali chiamate Ajax. Per fare ci\u00f2, sono ricorso all&#8217;antichissima ma sempre valida tecnica della &#8220;<span style=\"font-weight: bolder;\">steganografia<\/span>&#8220;.<\/p><p>Ma perch\u00e9 tanto sbattimento? Perch\u00e9 cos\u00ec facendo si bypassa il CORS ed altri controlli standard di sicurezza del browser.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dadf0d2 elementor-widget elementor-widget-heading\" data-id=\"dadf0d2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-large\">Cenni sulla steganografia<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7ceab8b elementor-widget elementor-widget-text-editor\" data-id=\"7ceab8b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>&#8220;La steganografia \u00e8 una tecnica che si prefigge di nascondere la comunicazione tra due interlocutori. [&#8230;] Generalmente, i messaggi nascosti sembrano essere (o fanno parte di) qualcos&#8217;altro: immagini, articoli, liste della spesa o un altro testo di copertura. Ad esempio, il messaggio nascosto pu\u00f2 essere un inchiostro invisibile tra le linee di una lettera privata. [&#8230;] La steganografia, a differenza della crittografia, consente di nascondere un messaggio all&#8217;interno di un vettore che possa consentirne il trasporto senza destare sospetti&#8221; &#8211; Cit. Wikipedia<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-355a9b4 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"355a9b4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><b>La stenografia nella storia<\/b><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3f0917c elementor-widget elementor-widget-text-editor\" data-id=\"3f0917c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Un esempio curioso di uso della steganografia nella storia \u00e8 quello narrato da Erodoto: Demarato di Sparta, per avvisare i compatrioti di una possibile invasione persiana scrisse su una tavoletta un messaggio da nascondere, poi copr\u00ec la tavoletta di cera e sulla cera scrisse un messaggio innocuo. Dato che nell&#8217;antichit\u00e0 le tavolette di cera erano normalmente usate per scrivere testi provvisori, questa non dest\u00f2 sospetti. (Per chi avesse visto l&#8217;ultimo Indiana Jones &#8220;Il quadrante del destino&#8221;, la scena sulla barca in cui scoprono il messaggio nascosto nella tavoletta di cera)<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b69e0ab elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"b69e0ab\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><b>Steganografia digitale<\/b><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9cc4dc5 elementor-widget elementor-widget-text-editor\" data-id=\"9cc4dc5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Per la steganografia digitale esistono molteplici sistemi di implementazione, quello pi\u00f9 utilizzato di solito \u00e8 il nascondere il messaggio all&#8217;interno di un&#8217;immagine sostituendo ogni carattere nel bit meno significativo di ogni pixel. In parole povere, il colore dei pixel modificati varierebbe talmente poco che all&#8217;occhio umano non risulterebbe nessuna differenza apparente tra l&#8217;immagine originale e quella contenente il messaggio.\u00a0<\/p><p>(per dettagli invito come sempre ad approfondire a parte)<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-52e5767 elementor-widget elementor-widget-heading\" data-id=\"52e5767\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-large\">Mani al codice<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f0164a1 elementor-widget elementor-widget-text-editor\" data-id=\"f0164a1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Il progetto \u00e8 sviluppato in NodeJs e si occuapa anche della creazione e gestione del webserver, ed \u00e8 composto da due applicativi distinti: la parte client e la parte server. Perch\u00e9 questa scelta? Per emulare la comunicazione tra due domini distinti e superare i limiti del CORS (il server risponde sulla porta 8080 e il client sulla porta 7070).<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b85b1a6 elementor-widget elementor-widget-text-editor\" data-id=\"b85b1a6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>PS: Il progetto inoltre \u00e8 stato sviluppato nel tempo di qualche ora in una notte in cui quest&#8217;idea non mi faceva dormire finch\u00e9 non avessi provato a realizzarla, quindi \u00e8 tutto molto &#8220;grezzo&#8221; e ridotto all&#8217;osso solo per dimostrarne il funzionamento.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4166a6a elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"4166a6a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><b>Server<\/b><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-454fa94 elementor-widget elementor-widget-text-editor\" data-id=\"454fa94\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>L&#8217;applicativo server espone un&#8217;api che prende in input il testo da codificare e ci genera un&#8217;immagine (&#8220;text_to_image&#8221;). Per semplicit\u00e0, la routine non inserisce il messaggio in un&#8217;immagine gi\u00e0 esistente ma ne genera una nuova codificando ogni carattere del messaggio nelle componenti colore di ogni pixel.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0361332 elementor-widget elementor-widget-text-editor\" data-id=\"0361332\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Es. codifica messaggio &#8220;ABC&#8221;:<\/p><p>A =&gt; codice ascii 0x41 (65)<br \/>B =&gt; codice ascii 0x42 (66)<br \/>C =&gt; codice ascii 0x43 (67)<\/p><p>Colore del pixel risultante: RGBA(65,66,67,255) (alpha sempre al massimo!)<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b378ce0 elementor-widget elementor-widget-text-editor\" data-id=\"b378ce0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Passiamo all&#8217;api che si occupa di intercettare la chiamata, generare l&#8217;immagine con il testo ricevuto e inviarla in risposta al client:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-62aeef5 elementor-widget elementor-widget-elementor-syntax-highlighter\" data-id=\"62aeef5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"elementor-syntax-highlighter.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<pre><code class='language-javascript'>app.get(&#039;\/text.jpg&#039;, (req, res) =&gt; \n{\n    let _p = req.query[&#039;p&#039;];\n\n    let _buffer = text_to_image(_p);\n\n    res.contentType(&#039;image\/jpeg&#039;);\n    res.send(_buffer);\n}); <\/code><\/pre><script>\nif (!document.getElementById('syntaxed-prism')) {\n\tvar my_awesome_script = document.createElement('script');\n\tmy_awesome_script.setAttribute('src','https:\/\/koban3.me\/wp-content\/plugins\/syntax-highlighter-for-elementor\/assets\/prism2.js');\n\tmy_awesome_script.setAttribute('id','syntaxed-prism');\n\tdocument.body.appendChild(my_awesome_script);\n} else {\n\twindow.Prism && Prism.highlightAll();\n}\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fc58dc8 elementor-widget elementor-widget-text-editor\" data-id=\"fc58dc8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Ed ora la routine che si occupa del lavoro sporco, cio\u00e8 quello di prendere il testo in chiaro e splittarlo nei vari pixel di una nuova immagine generata a runtime:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a13a254 elementor-widget elementor-widget-elementor-syntax-highlighter\" data-id=\"a13a254\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"elementor-syntax-highlighter.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<pre><code class='language-javascript'>function text_to_image(text)\r\n{   \r\n    const width = Math.ceil(text.length \/ 3);\r\n    const height = 1;\r\n\r\n    const canvas = createCanvas(width, height);\r\n    const context = canvas.getContext(&quot;2d&quot;);\r\n\r\n    let _char_index = 0;\r\n    let _x = 0;\r\n    let _y = 0;\r\n\r\n    while(_char_index &lt; text.length)\r\n    {\r\n        let _image_data = context.createImageData(1, 1); \r\n        let _pixel_data = _image_data.data;                   \r\n        for(let _byte_index = 0; _byte_index &lt; 3; _byte_index++)\r\n        {\r\n            let _ascii_code = (_char_index &gt;= text.length ? 0 : text.charCodeAt(_char_index));\r\n\r\n            _pixel_data[_byte_index] = _ascii_code;\r\n\r\n            _char_index++;\r\n        }\r\n\r\n        _pixel_data[3] = 255; \/\/ alpha a 255 &egrave; fondamentale altrimenti i colori non vengono decodificati!\r\n\r\n        context.putImageData(_image_data, _x, _y);  \r\n\r\n        _x++;\r\n    }\r\n\r\n    const buffer = canvas.toBuffer(&quot;image\/png&quot;);\r\n\r\n    return buffer;\r\n}\r\n <\/code><\/pre><script>\nif (!document.getElementById('syntaxed-prism')) {\n\tvar my_awesome_script = document.createElement('script');\n\tmy_awesome_script.setAttribute('src','https:\/\/koban3.me\/wp-content\/plugins\/syntax-highlighter-for-elementor\/assets\/prism2.js');\n\tmy_awesome_script.setAttribute('id','syntaxed-prism');\n\tdocument.body.appendChild(my_awesome_script);\n} else {\n\twindow.Prism && Prism.highlightAll();\n}\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d68a194 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"d68a194\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><b>Spiegazione<\/b><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fa17389 elementor-widget elementor-widget-text-editor\" data-id=\"fa17389\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>La routine prende il testo passato come parametro e genera un oggetto &#8220;Canvas&#8221; monodimensionale (per semplicit\u00e0 tutti i pixel generati staranno sullo stesso asse). A quel punto scorre ogni elemento del testo da nascondere e ne inserisce il codice ascii nelle componenti colore dei vari pixel in modo sequenziale. Alla fine la routine restituisce un buffer contenente i byte dell&#8217;immagine in formato &#8220;png&#8221;, pronto da essere inviato nel buffer di risposta della chiamata web.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2ca8808 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"2ca8808\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><b>Client<\/b><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ac869da elementor-widget elementor-widget-text-editor\" data-id=\"ac869da\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Il principio di funzionamento di base si riaggancia a quello gi\u00e0 discusso nell&#8217;articolo sopra citato [<a style=\"background-color: #ffffff;\" href=\"https:\/\/koban3.me\/index.php\/2023\/06\/12\/svg-keylogger\/\">Leggi l&#8217;articolo &#8220;SVG Keylogger&#8221;<\/a>], cio\u00e8 viene generato un nuovo oggetto &#8220;img&#8221; a cui viene impostata la propriet\u00e0 &#8220;src&#8221; con l&#8217;url dell&#8217;api remota. Il limite \u00e8 che essendo un oggetto immagine, e la risposta ricevuta \u00e8 un&#8217;immagine (valida o no che sia), non si pu\u00f2 interpretare la risposta direttamente come se fosse del semplice testo (json o altri formati).<\/p><p>Di conseguenza, per estrarre la risposta ricevuta dal server, bisogna effettuare il processo inverso e cio\u00e8 scorrere ogni pixel e riconvertire il valore di ogni componente colore in caratteri ascii.\u00a0<\/p><p>Chiaramente per fare questo \u00e8 necessario prima impostare una callback all&#8217;evento &#8220;onload&#8221; dell&#8217;oggetto &#8220;img&#8221; creato, altrimenti non sapremo mai con certezza quando il browser ha completato il caricamento dell&#8217;immagine con la nostra risposta.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fbe7e86 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"fbe7e86\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Di seguito il cuore del meccanisco che si occupa di effettuare la chiamata e recuperarne la risposta \u00e8 inserito all&#8217;interno della routine &#8220;call&#8221; che accetta in input il testo da inviare all&#8217;api remota e un&#8217;eventuale callback alla quale verr\u00e0 passata la risposta.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-887addf elementor-widget elementor-widget-elementor-syntax-highlighter\" data-id=\"887addf\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"elementor-syntax-highlighter.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<pre><code class='language-javascript'>function call(parameter, callback)\r\n{\r\n    var img = new Image();\r\n\r\n    img.src = &#039;http:\/\/localhost:8080\/text.jpg?p=&#039; + encodeURIComponent(parameter);\r\n    img.crossOrigin = &quot;anonymous&quot;; \/\/ Essenziale per bypass CORS!\r\n\r\n    img.onload = function() \r\n    {\r\n        var canvas = document.createElement(&#039;canvas&#039;);\r\n\r\n        canvas.width = img.width;\r\n        canvas.height = img.height;\r\n\r\n        var ctx = canvas.getContext(&#039;2d&#039;);\r\n\r\n        ctx.drawImage(img, 0, 0);\r\n\r\n        let _text = &quot;&quot;;\r\n\r\n        console.log(&#039;Image width: &#039; + img.width);\r\n        console.log(&#039;Image height: &#039; + img.height);\r\n\r\n        let _image_data = ctx.getImageData(0, 0, img.width, img.height);\r\n\r\n        console.log(_image_data);\r\n\r\n        let _srgb_index = 0;\r\n\r\n        for(let _byte_index = 0; _byte_index &lt; img.width * 4; _byte_index++)\r\n        {\r\n            if(_srgb_index &lt; 3)\r\n            {\r\n                let _char_code = _image_data.data[_byte_index];\r\n\r\n                if(_char_code == 0)\r\n                {\r\n                    \/\/ EOF\r\n\r\n                    console.log(&quot;EOF!&quot;);\r\n\r\n                    break;\r\n                }\r\n\r\n                \/\/console.log(_image_data);\r\n\r\n                _text += String.fromCharCode(_char_code);\r\n                \r\n                _srgb_index++;\r\n            }\r\n            else\r\n            {\r\n                _srgb_index = 0;\r\n            }\r\n        }\r\n\r\n        console.log(_text);\r\n\r\n        if(callback != undefined)\r\n        {\r\n            callback(_text);\r\n        }\r\n    };\r\n} <\/code><\/pre><script>\nif (!document.getElementById('syntaxed-prism')) {\n\tvar my_awesome_script = document.createElement('script');\n\tmy_awesome_script.setAttribute('src','https:\/\/koban3.me\/wp-content\/plugins\/syntax-highlighter-for-elementor\/assets\/prism2.js');\n\tmy_awesome_script.setAttribute('id','syntaxed-prism');\n\tdocument.body.appendChild(my_awesome_script);\n} else {\n\twindow.Prism && Prism.highlightAll();\n}\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-87f0ca5 elementor-widget elementor-widget-text-editor\" data-id=\"87f0ca5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Nota fondamentale: \u00e8 essenziale che all&#8217;oggetto &#8220;img&#8221; creato per effettuare la chiamata, venga impostata la propriet\u00e0 &#8220;<strong>crossOrigin<\/strong>&#8221; con il valore &#8220;<strong>anonymous<\/strong>&#8220;, altrimenti il solito CORS bloccher\u00e0 la chiamata e tutto finir\u00e0 in un nulla di fatto.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-906318b elementor-widget elementor-widget-elementor-syntax-highlighter\" data-id=\"906318b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"elementor-syntax-highlighter.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<pre><code class='language-javascript'>img.crossOrigin = &quot;anonymous&quot;; \/\/ Essenziale per bypass CORS! <\/code><\/pre><script>\nif (!document.getElementById('syntaxed-prism')) {\n\tvar my_awesome_script = document.createElement('script');\n\tmy_awesome_script.setAttribute('src','https:\/\/koban3.me\/wp-content\/plugins\/syntax-highlighter-for-elementor\/assets\/prism2.js');\n\tmy_awesome_script.setAttribute('id','syntaxed-prism');\n\tdocument.body.appendChild(my_awesome_script);\n} else {\n\twindow.Prism && Prism.highlightAll();\n}\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0fe0d30 elementor-widget elementor-widget-heading\" data-id=\"0fe0d30\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-large\">Link al codice<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3d92bbc elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"3d92bbc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tHo creato un repository pubblico dove caricher\u00f2 i vari progetti di esempio.\n\nQuesto \u00e8 il link per poter scaricare il codice di esempio illustrato in questo articolo:\u00a0<a style=\"background-color: #ffffff;\" href=\"https:\/\/gitlab.com\/koban3_demos\/steg_bypass_ajax\/\">Koban3 demo&#8217;s &#8211; steg_bypass_ajax<\/a>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cb31a1e elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"cb31a1e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-194290a elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"194290a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Have fun! \ud83d\ude42<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Di cosa si tratta? Riprendendo l&#8217;idea di inviare dati a un server esterno simulando il caricamento di un&#8217;immagine [Leggi l&#8217;articolo &#8220;SVG Keylogger&#8221;], ho deciso di estendere la tecnica per riuscire anche a ricevere dati da remoto senza usare le normali chiamate Ajax. Per fare ci\u00f2, sono ricorso all&#8217;antichissima ma sempre [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"class_list":["post-601","post","type-post","status-publish","format-standard","hentry","category-web"],"_links":{"self":[{"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/posts\/601","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/comments?post=601"}],"version-history":[{"count":16,"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/posts\/601\/revisions"}],"predecessor-version":[{"id":631,"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/posts\/601\/revisions\/631"}],"wp:attachment":[{"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/media?parent=601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/categories?post=601"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/koban3.me\/index.php\/wp-json\/wp\/v2\/tags?post=601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}