C è un linguaggio che consente l'accesso diretto a risorse di basso livello. È stato originariamente realizzato per implementare il sistema operativo Unix, quindi per sua natura consente di fare le cose a livello di sistema, il che è conveniente per gli exploit.
Una conseguenza di ciò è che i programmi C compilati spesso non hanno bisogno di dipendenze esterne - come sottolineato da paj28 nei commenti.
C ++ è stato originariamente costruito sopra C e ha lo stesso accesso alle operazioni di basso livello.
Ad esempio, C consente la manipolazione diretta della memoria tramite puntatori. Una volta che un puntatore viene creato, può essere aggiunto o sottratto da a punti in altre posizioni di memoria. Con un po 'di creatività, questo può essere usato per scopi nefandi.
Al contrario, Java e C # non consentono questo tipo di manipolazione. Non consentono ad un utente di aggiungere o sottrarre una cosiddetta variabile di riferimento (l'equivalente di Java e C # dei puntatori di C).
Tradizionalmente, C e C ++ sono tradotti direttamente in codice macchina, mentre molti linguaggi moderni come Java e C # sono tradotti in codice per macchine virtuali (codice JVM e CIL). I compilatori che traducono C e C ++ direttamente in codice macchina sono prontamente disponibili su quasi tutte le piattaforme; meno per i compilatori che traducono Java o C # direttamente sul codice macchina.