Author: Sh0ck

BlueKeep RDP, the new EternalBlue ?

I’m back,

Today I will talk about the BlueKeep RDP vulnerability in few words.

Like you probably know, this new vulnerability affect :

  • Windows 2003
  • Windows XP
  • Windows Vista
  • Windows 7
  • Windows Server 2008
  • Windows Server 2008 R2

Not like the EternalBlue exploit, this new vulnerability don’t use SMBv1 but the RDP functionnality under Windows.

Actually the exploit remain not public but you can find some PoC on github anyway like this one :

To be clear, some guys said that you need a physical access to the server, disconnect it to exploit the vulnerability… the reality is different.

If you read the PoC source code, the vulnerability is exploited via a malformed packet who lead to a remote code execution on the target.

Ekultek, the author of the PoC explained in his source code that the generation of the payload is difficult anyway especially when ASLR is involved with it.

Like he said, he’s not shared this part of the methodology to avoid to watch the world burning.

The american NSA also asked to all companies to update their system and I’m totally agree with that.

Actually, one metasploit module is available, this module is shared between researchers and remain private but for how many time ?

Like you probably know, the ms17-010 module for EternalBlue can be exploited in few seconds, I think it will be the same situation for this one.

Finally, the full PoC is available here :

You can also check if your server is vulnerable with the rdpscan tool from Robert Graham :

On 4 June 2019, another related RDP security vulnerability (CVE-2019-9510) was reported by the CERT Coordination Center at the Carnegie Mellon University.

This flaw may affect Windows 10 1803, Windows Server 2019 or newer systems using RDP, but is considered less of a problem than the BlueKeep flaw. No patches for the flaw are currently available and workarounds have been reported.

Why the eSport is a security fail ?

Today I will talk about one of my favourite domain, the electronic sport competitions and the underground activities behind.

I will try to explain why the eSport is a security fail, I’m a old counter-strike player (CS:GO actually) so I will take this sample.

I watched many professionnals players, I followed the eSport scene many years and when I watched movies or streams directly, I was like “wow they are really strong”.

But something was wrong, some players was god like, I don’t considere myself like bad at counter-strike, I did some lan tournaments, I was global elite on the game (highest level actually) etc…

So I started to introduce myself under another nickname on a cheat community (unknowncheats forums).

I started to create some cheats on a really well know game (I will not share the name here because they decided to arrest some cheats developers recently), not to share or sell them, only for my own knowledge to learn new things about the reverse engineering (my weakness in the computer security).

And the game surprised me, there is no anticheat, only some anti-debuggers on the last version of the game (IsDebuggerPresent and some first-time exceptions that you can disable with xdbg).

To inject in the game process, you can use a simple LoadLibrary method, some guys use a manual mapping method but injections methods are mostly not considered.

Like you probably know, there is two type of cheats, internals (dll injection) and externals (actions on the game process without injections).

This game surprised me again when I tried a simple WriteProcessMemory on the online mode, you can enable the god mode, run faster, jump or fly like superman and you will be never detected because the game work in p2p mode and trust everything from the client, you can kick or crash the others players remotely.

There is also some kernel methods for the paranoid cheaters, you can use a vulnerable driver to be ring0 and avoid some anticheats:

After few months, I finally created a fully functionnal cheat for this game with ImGui included etc… I was able to execute all the game internal functions with some hashes (the game use a sort of custom virtual table where all game functions was registered with a hash, so the solution between the updates was to create an array with the old hashes and the new hashes, call the old hash, use a custom translator to call the new hash from the old one).

Now I will talk about CS:GO (yes I use the real name here but you will probably understand why).

CS:GO is one of the most game played on steam, the objective of this game is to be a counter-terrorist in a team of 5 players and kill the terrorists (5 players also in the competitive matches).

The game is actually protected by the Valve Anti-Cheat (VAC) system and an overwatch system (you can watch the game of a suspect and decide to voteban him or not).

To be honest with you, the VAC system is weak but the overwatch system is a good method, most of cheaters are banned with the overwatch method because you can’t really hide a powerful cheat (like an aimbot) but if you are smart, you can avoid to be banned if you hide your cheat (try to play with your wallhack without watch the ennemy behind a wall, play smart etc…).

There is also private cheats, a CS:GO player has been recently disqualified and banned from the FPL (Faceit Pro League), the FPL is the CS:GO Professionnal League (cash prizes are actually huge during the official tournaments) like you can see here:

day0s was qualified in a month while some professional players had to play a few years to get there.

His cheat used the game scoreboard, actually in the game, when you press “TAB” you can see your scoreboad and use your mouse to click on a player name to recommand him, mute him etc…

But like you see in this movie, the cheat use the scoreboard to move the mouse cursor where the enemy is, day0s was able to know the exact position of his enemy each time he pressed TAB.

But this is only one the private cheats used by the CS:GO players, you can found some interesting projects on unknowncheats (like some hardware sonar cheats or sound based cheats):

Some players were accused and the main question was “how they cheated in lan where you can’t use your own computer and your own hardware ?” the answer is really simple:

Steam workshop allowed to use pictures with zipped file content, some players used a custom mouse with a cheat included, some players used their smartphone in usb directly on the lan computers etc…

There is also illegal sellers available on internet:

And finally here is an interview of supex0, the KQLY and Sf‘s custom cheats developer (two french CS:GO pro players banned few years ago):

Cash prizes is the main problem of the eSport scene and a real challenge for the anti-cheats industry.

I just presented the basic stuff here but there is also a cheats industry with advanced methods like you can see here:

Here is the details about the DMA leaks :

Physical Hacking Diary

Hello folks,

Today, I am going to write an article about physical hacking and talk about my own configuration. I will keep it up to date as soon as I have new things.

The main goal of this article is to have a backpack to be ready to do some real red-team pentests (don’t do illegal things with that please).

I will write a list of tools that I own here with a brief description, why I need them and for what.

In a first time, a backpack with enough pockets is important for me, I decided to buy a Mil-Tec backpack like this one:

You can buy it here:

A smartphone if you want to check the Bluetooth Low Energy devices around, I recommand nRF Connect on android to do that, or quite simply do some social engineering, take some pictures, note something and use it like external hard-drive (choose a decent smartphone).

A computer, I personnally use my 15inch laptop:

A lighter if you need to burn something like some wires:

A lockpicking kit, I use a basic set from OKPOW like this one:

You can buy it here:

But I suggest you to use a better kit like the southord or the majestic kits.

You can also use a pickgun to be faster like this one (not recommanded because pickguns leaves traces in the locks):

You can buy it here:Ă©lectrique-maintenance-lutilisation/dp/B06ZZJ57K4/ref=sr_1_5

An ACR122U RFID Reader & Writer like this one:

You can buy it here:

And some chinese UID alterable cards:ĂŽle/dp/B0794V3XB8/ref=asc_df_B0794V3XB8/

Or better a proxmark3:

A Lan Turtle:

You can buy it here:

An endoscope for your android like this one:

I recommand this one because you have a magnet arm so you can catch some keys behind a door (this is a sample).

You can buy it here:

I recommand some thin sheets of metal with a chisel to unlock some doors (be imaginative).

I use a rtl-sdr also (rtl2832u) like this one :

You can buy it here:Ă©cepteur/dp/B013Q97J8W/ref=sr_1_7

I suggest you to buy an hackRF like this one if you want a larger band:

You can buy it here:Ă©fini-Adaptateur-Dantenne/dp/B01K1CCHR0/ref=sr_1_1_sspa

A yellow vest like this one:

You can buy it here:éfléchissant-jaune/dp/B0791KS6XN/ref=sr_1_8

If you use it you will probably not be considered like hostile (you can use some clothes like that).

A bloc note with some pens like this one:

You can buy it here:

Some wires and adapters (USB, Ethernet, Ethernet to USB etc…):

A wifi pine apple:

You can take a look here on the Hak5 website:

A rubber ducky from Hak5 or a Cactus WHID:

You can find the different informations and buy it here:

A raspberry pi with a battery extension pack:

Raspberry pi:Ăšle-B-Carte-mĂšre/dp/B07BDR5PDW/ref=asc_df_B07BDR5PDW/

Battery extension pack:

An usb soldering iron:

You can buy it here:

A foldable keyboard:

You can buy it here:

A screwdriver with several tips available, some clamps:

A wire cutter:

Touchscreen gloves (to protect your fingers and to be able to use your smartphone anyway):

A mesureing tape (check the third video):

I suggest you to watch different videos to learn some tips and avoid the famous “Red Team Field Manual”, this is a good book but your own experience is better:

Skripal Case from Russia with Love

Hello folks,

Today I will talk about the Skripal case and the OSINT methods used by the Bellingcat group to find the real identities of the russian spies behind the SergueĂŻ and Ioulia Skripal poisoning.

The story started when a friend shared me some informations about two nicknames “Dorbik” and “Matad0r“, a vendor of bullet proof hosting services (a bulletproof hosting guarantees that websites hosted in these locations will not be shut down, even if they are blatantly hosting criminal content).

I searched a bit and found some interesting informations :

[REDACTED Defendant #20] AKA Dorbik AKA Matad0r is a vendor of Bullet Proof Hosting services. Bulletproof hosting guarantees that websites hosted in these locations will not be shut down, even if they are blatantly hosting criminal content. Other criminals hosted carding forums and phishing sites on Dorbik’s services.

With the USA official district court document (in 2017 before the Skripal Case) :

I searched the “Dorbik” nickname in this document and found the name of the dark market vendor:

Sergei Litvinenko” -> Sergei Like “Sergei Skripal” but Litvinenko like “Alexandre Litvinenko” who was a British naturalised Russian defector and former officer of the Russian FSB secret service.

You can read his full biography here:

Like Sergei Skripal, Litvinenko got hospitalised in what was established as a case of poisoning by radioactive polonium-210 (Novitchok for the Skripal case).

He died from the poisoning on 23 November 2006.

From coincidences, I suggest that Sergei Skripal was “Sergei Litvinenko” aka “Dorbik” aka “Matad0r” and that Alexander Litvinenko was a member of his family but the informations are not enough to confirm this theory.

On 4 March 2018, Sergei Skripal and Yulia Skripal were poisoned in Salisbury with a Novichok nerve agent, according to official UK sources and the Organisation for the Prohibition of Chemical Weapons (OPCW).

In the 1990s, Sergei Skripal was an officer for Russia’s Main Intelligence Directorate (GRU) and worked as a double agent for the UK’s secret service from 1995 until his arrest in Moscow in December 2004.

Like you know, Alexander Litvinenko died in 2006, and weirdly, the same year, Sergei Skripal was convicted of high treason and sentenced to 13 years in a penal colony by a Russian court.

Two Russian nationals, who go by the names Alexander Petrov and Ruslan Boshirov were accused of the murder attempt on Sergei Skripal (fake names obviously):

Recently, On 14 September 2018, the website “Bellingcat” wrote an article about Alexander Petrov and established a link from the suspect’s passport and the russian security services, you can read the full post here:

You can see the last minute travel plans:

And you can see an important informations about his passport:

Alexander Petrov’s passport dossier is marked with a stamp containing the instruction “Do not provide any information”. This stamp does not exist in standard civilian passport files. A source working in the Russian police force who regularly works with the central database confirmed to Bellingcat and The Insider that they have never seen such a stamp on any passport form in their career. That source surmised that this marking reserved for operatives of the state under deep cover.

And more important, the domestic passport photo matches the photos released by the UK authorities and the face of the person calling himself Alexander Petrov:

Today, Bellingcat Investigation Team released others important informations, they found the real identity of Ruslan Boshirov from OSINT methods.

He was identified as a GRU colonel named Anatoliy Chepiga:

The passport file contained a photograph – dated approximately in 2003, when this passport was obtained – that strongly resembled a younger “Boshirov” as seen in passport photos released by the UK police:

The amazing work of the bellingcat team identified the suspect from a 2003 database, he used his personnal address as “Military Unit 20662, Khabarovsk“, It also listed his place of birth as “village of Nikolaevka”, further linking this person to the Hero of the Russian Federation with the same name.

Bellingcat has contacted confidentially a former Russian military officer of similar rank as Colonel Chepiga, in order to receive a reaction to what Bellingcat found. The source, speaking on condition of anonymity, expressed surprise that at least one of the operatives engaged in the operation in Salisbury had the rank of colonel. Even more surprising was the suspects’ prior award of the highest military recognition.

On 13 September the two men were interviewed on Russian television where they claimed they were tourists visiting the city.

On 2 October 2018 Bellingcat released more informations about the colonel, they obtained a photograph posted on the Russian social network “Odnoklassniki (OK)” by a visitor who visited the Far-Eastern Military Academy (abbreviated as DVOKU in Russian) where you can see a picture of the colonel.

More informations can be found on:

About the second suspect (Dr. Alexander Mishkin), Bellingcat released a full report, you are able to read it here:

Recently, a GRU hackers team tried to hack the OPCW buildings to erase some evidences from different operations, a rental car full of hacking devices has been found on a parking near the OPCW buildings :

You can read the informations on:



Today I decided to release a correct version of an ImGui menu directly hooked into a directx11 application.

The sources are available here:

I did that because my goal was to add some menus in games like GTA5, but sources available on the net was not really user/developer-friendly.

My work is based on:

I just fixed some issues, added ImGui and added the mouse / keyboard InputHook.

If you want to use it, you can compile the project (don’t forget to add MinHook and ImGui correctly) and inject your dll in the targeted directx10/11 application.

The most important part is in d3d11hook:

D3D11_HOOK_API void ImplHookDX11_Present(ID3D11Device *device, ID3D11DeviceContext *ctx, IDXGISwapChain *swap_chain)
	if (GetAsyncKeyState(OpenMenuKey) & 0x1) {
		menu->IsOpen ? menu->IsOpen = false : menu->IsOpen = true;


HRESULT __stdcall PresentHook(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
	std::call_once(g_isInitialized, [&]() {
		pSwapChain->GetDevice(__uuidof(g_pd3dDevice), reinterpret_cast<void**>(&g_pd3dDevice));

		ImGui_ImplDX11_Init(g_hWnd, g_pd3dDevice, g_pd3dContext);

	ImplHookDX11_Present(g_pd3dDevice, g_pd3dContext, g_pSwapChain);

	return phookD3D11Present(pSwapChain, SyncInterval, Flags);

I suggest you to edit ImplHookDX11_Present only if you want to add your own code.

Have a good day 😉

Read The Fancy Manual – RTFM/SigSegv1 Story

Hello folks,

Today something new is coming on my blog, yes you probably already saw it but my future posts will be only in english 🙂

I decided to do that to reach a broad public and increase my english skill of course, so please, don’t hesitate to correct me if you see any mistakes 😉

Well today I will talk about our french community, Read The Fancy Manual, to present what we did, why and for who exactly.

When we started, we was a small group of friends, our main goal was just to talk between us in Paris and drink some beers (we can’t really hide it).

We did some meetups, and some people joined us because they liked the idea to create a community in Paris in different places.

And Hackira from the game HackerzVoice asked us during the World Music Day 2017 “Hey guys why you don’t create your own event ?” I was a bit surprised, we thinked about that and answered “let’s do it”.

Few months later, we created the Read The Fancy Manual Association, declared it, and we started to search how to do that.

Our first partners was the 42 school, NewbieContest and Encelis (thank you again), we contacted some companies indirectly most of the time, only via our contacts and some of them (Synacktiv, AlgoSecure, NetXP, Yogosha, Wavestone) decided to help us.

To be honest, without them, our french computer security community would already be dead and and that would have been a pity because all of our members are passionate.

Actually, the first prequals will be launched the 28 of September with 5 challenges, we want to keep this prequals phase for the next editions to avoid a large public, only enthusiast people with enough skill to pass this phase.

I want to be clear on one point anyway, we are not elitist, beginners are welcome during the meetups to talk with our members, personnally, I am here to help everyone and share my ideas.

Some members of the french infosec are more interested to trash talk some people and I can’t accept that on my side, with RTFM, we want a clean community with a good mentality.

Anyway, I need to talk about the next steps for RTFM, our prequals will be open the 28 of September, everyone can try it for free and if you validate the different challenges, you will be able to register you and grab a ticket for approximatively 10€ (to be sure that you will come).

The first of december, the event will be organized in the 42 school in Paris, some french and english speakers will be present, and you will be able to participate to a CTF (jeopardy in solo but you could play in team also if you want).

I hope that you will like our event and if everyone liked it, we will organize more editions of course 🙂

I want to talk about another thing, but during our creation, we were able to meet the Defcon group Paris.

This group has been created just after our group, so we decided to talk with the organisators, we are not really partners actually but we decided to support them and they decided the same thing for us, I want to thank them because they are some great and really interesting people.

For the future, I would communicate more with different international groups to create a link between us without forget our main goal, be a cool french conference with a community behind and develop more projects, in our association, everyone is able to purpose something, we take the decisions in group via a voting system.

Finally, I want to thank all of you and I urge you to be the criminal of your own curiosity.

Point de vue intĂ©ressant sur l’investigation OSINT d’une image

Hello chers lecteurs,

Aujourd’hui j’ai pu avoir une conversation intĂ©ressante avec x0rz ainsi qu’une autre personne sur discord donc je souhaitais vous en faire part en espĂ©rant que cela puisse aider certaines personnes Ă  retrouver un lieu prĂ©cis visible sur une photo voir mĂȘme une personne.

x0rz a en effet demandé à plusieurs personnes ceci :

L’objectif Ă©tait donc de retrouver le lieu ou toute autre information liĂ©e Ă  cette photo.

Une personne a donc suggĂ©rer que la photo avait Ă©tĂ© prise vers le Pont d’IĂ©na Ă  cĂŽtĂ© de la Tour Eiffel :

On peut en effet voir le bĂątiment typiquement parisien juste au-dessus Ă  gauche, et les immeubles Ă  droite, une autre photo a donc Ă©tĂ© mise en ligne par cette mĂȘme personne :

D’aprĂšs cette mĂȘme personne, les tĂąches noires sur le pont semblaient ĂȘtre les bas-reliefs, ce qui a confirmĂ© le lieu gĂ©nĂ©ral de la photo.

x0rz a ensuite suggéré que la photo avait été prise en rooftop de cette façon :

En cherchant sur streetview, cette mĂȘme personne a rĂ©ussi Ă  trouver le lieu prĂ©cis en se basant sur des Ă©lĂ©ments visibles sur la photo et en les comparant :

En cherchant un peu, le lieu semblait ĂȘtre l’hotel 5 Ă©toiles Shangri-La situĂ© au 10, avenue d’IĂ©na, Paris, 75116, France :

Une autre personne sur discord a donc superposĂ©e l’image du lieu ainsi que l’image de la personne, on a donc pu observer que l’image Ă©tait bien centrĂ©e :

J’ai pour le coup suggĂ©rĂ© que les nuages visibles ne variaient pas sur le cĂŽtĂ© gauche de l’image mais qu’ils changeaient cependant sur le cĂŽtĂ© droit, on peut donc en dĂ©duire que la photo a Ă©tĂ© prise le mĂȘme jour que la photo de prĂ©sentation de l’hĂŽtel.

Cependant l’image est trop parfaite et on peut apercevoir quelques dĂ©coupes mal faites sur les cheveux du cĂŽtĂ© gauche de la femme, il est donc fort probable que cette mĂȘme femme sur la photo ait Ă©tĂ© dĂ©tourĂ©e et rajoutĂ©e par dessus l’autre image, elle n’a donc probablement jamais mis les pieds dans cet hĂŽtel.

Cette analyse est intĂ©ressante dans le sens que mĂȘme sans rĂ©sultats directs de Google Images ou bien TinEye, il est toujours possible de repĂ©rer plusieurs petits Ă©lĂ©ments disponibles sur une photo et de remonter petit Ă  petit jusqu’Ă  retrouver l’endroit prĂ©cis ainsi que l’angle oĂč elle a Ă©tĂ© prise, mais Ă©galement la date approximative sans mĂȘme analyser les metadata.

Pour plus d’informations, vous pouvez jeter un oeil sur l’article exceptionnel de x0rz :

Group Chat chiffré en AES256 avec NodeJS

Cher visiteur,

Il y a quelques temps de cela, je cherchais une messagerie chiffrĂ©e utilisable en groupe, aprĂšs avoir cherchĂ© un peu, testĂ© des messageries comme Wire (qui est pour le moment pour ma part une des plus secure que j’ai pu trouver mĂȘme si ça manque cruellement de fonctionnalitĂ©s), jabber avec otr ou mĂȘme omemo et bien d’autres.

Je me suis donc posĂ© la question “et si je m’amusais Ă  refaire un chat de groupe de façon chiffrĂ©” ?

Du coup je me suis permis de rĂ©aliser cette idĂ©e, bien sĂ»r il s’agit d’un PoC et beaucoup pensent qu’implĂ©menter soit mĂȘme une crypto est risquĂ© (ils ont trĂšs certainement raison).

J’ai donc dĂ©cidĂ© de me faire ma propre implĂ©mentation en utilisant comme vecteur d’initialisation (IV), des flux rss publics, de ce fait, l’AES change Ă  chaque fois qu’une nouvelle actualitĂ© est publiĂ©e sur le flux rss spĂ©cifiĂ©, pour sĂ©curiser un peu la chose, j’ai rajoutĂ© un salt Ă  communiquer entre clients avant la conversation, une meilleure solution serait d’utiliser des certificats mais Ă©changer tous les certificats entre chaque client est plutĂŽt fastidieux.


var io = require('').listen(1337);

var allClients = [];

io.sockets.on('connection', function (socket) {
	socket.on('send', function(data) {
		if(data.type == 'connected') {
			socket.nickname = data.content;
			socket.broadcast.emit('send', { type : 'connected', content: socket.nickname + " is now connected" });
			socket.emit('send', { type : 'connected', content: socket.nickname + " is now connected" });
		} else if (data.type == 'list') {
			var nicknames = [];
			allClients.forEach(function(socket) {
			socket.emit('send', { type : 'list', content: nicknames });
		} else if (data.type == 'message') {
			socket.broadcast.emit('send', { type : 'message', content: data.content });

	socket.on('disconnect', function() {
      	var i = allClients.indexOf(socket);
      	allClients.splice(i, 1);
      	socket.broadcast.emit('send', { type : 'disconnect', content: socket.nickname + " is now disconnected" });


var server = 'http://localhost:1337';

var readline = require('readline');
var io = require('');
var socket;
var colors = require('colors');
var parser = require('rss-parser');
var sha256 = require('sha256');
var crypto = require('crypto'), algorithm = 'aes-256-ctr';

var rl = readline.createInterface(process.stdin, process.stdout);

var rss_link = '';
var aes_salt = 'YourSaltIfYouWant';

var nickname;
rl.question("Please enter a nickname: ", function(name) {
	nickname = name;
	socket = io.connect(server, {reconnect: true});
    socket.emit('send', { type: 'connected', content: name });

    socket.on('connect', function () { 
		socket.on('send', function(data) {
			if(data.type == 'connected') {
			} else if (data.type == 'list') {
				data.content.forEach(function(nickname) {
			} else  if (data.type == 'message') {
				parser.parseURL(rss_link, function(err, parsed) {
					var iv = sha256(parsed.feed.entries[0].title + parsed.feed.entries[1].title);
					console.log(decrypt(iv + aes_salt, data.content));
			} else if (data.type == 'disconnect') {

		rl.on('line', function (line) {
			if(line.indexOf('!help') > -1) {
				console.log(colors.yellow('!list -> Check who is online.'));
			} else if(line.indexOf('!list') > -1) {
				socket.emit('send', { type: 'list' });
			} else {
				parser.parseURL(rss_link, function(err, parsed) {
					var iv = sha256(parsed.feed.entries[0].title + parsed.feed.entries[1].title);
					var message = encrypt(iv + aes_salt, nickname + " : " + line);
				  	socket.emit('send', { type: 'message', content: message });

function encrypt(key, message) {
	var cipher = crypto.createCipher(algorithm,key)
  	var crypted = cipher.update(message,'utf8','hex')
  	crypted +='hex');
	return crypted;

function decrypt(key, message) {
	var decipher = crypto.createDecipher(algorithm,key)
  	var decrypt = decipher.update(message,'hex','utf8')
  	decrypt +='utf8');
	return decrypt;

DĂ©velopper avec NodeJS, Express, MongoDB, PugJS et Socket.IO

Cher visiteur,

Dans cet article, nous allons voir comment concevoir une application web plutÎt robuste avec NodeJS et Mongodb de façon trÚs simple et minimaliste.

Pour les plus nĂ©ophytes d’entre vous qui n’ont aucunes connaissances des routes nodejs, dĂ©pendances et j’en passe, le mieux est de commencer par la base de NodeJS via le tutoriel de mateo21 sur :

Tout d’abord, il vous faudra installer NodeJS ainsi que MongoDB

Sous Windows (Windows Server ou 10) :

Il suffit d’installer NodeJS en version LTS pour Windows x64 et MongoDB en version Windows Server, l’outil Ă©tant compatible aussi pour Windows 10.

Sous Linux :

apt-get install nodejs && apt-get install mongodb

Une fois l’environnement installĂ©, il vous suffit d’ouvrir un terminal ou une console Windows et taper cette commande pour vĂ©rifier l’installation (ceci vous retournera la version de nodejs installĂ© sur votre post) :

node -v

Pour commencer votre application, il vous faudra créer un répertoire et naviguer dedans via le terminal et la console et taper :

npm init

Cette commande aura pour objectif de vous poser des questions sur votre application, quelle est sa version, son auteur et j’en passe, elle finira ensuite par crĂ©er un fichier package.json qui contiendra toutes ces informations ainsi que les packages npm utilisĂ©s par votre application, les packages npm Ă©tant des extensions proposĂ©es par la communautĂ© NodeJS.

Votre package.json devrait maintenant ressembler Ă  ceci :

  "name": "application",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "author": "",
  "license": "ISC"

La partie main avec “index.js” sera votre point d’entrĂ©e de l’application, du coup, le main de votre application sera “index.js” que vous devez crĂ©er en plaçant un code minimal dedans :

var express = require('express');
var app = express();
var pug = require('pug');
var io = require('').listen(app.listen(80));

conf = {
	lang: "fr",
	title: "Mon application",
	urlsocketio: ""

app.set('view engine', 'pug');

app.get('/', function(req, res) {
    res.render('index', { conf:conf } );

Il existe une autre façon de coder avec NodeJS si vous voulez rĂ©ellement de l’objet avec “TypeScript”, je ne l’aborderais pas ici mais libre Ă  vous de l’utiliser.

Pour faire fonctionner votre application, il vous faudra aussi installer les packages npm dont votre application a besoin, lancer cette commande dans le répertoire de votre application :

npm install express pug –save

Le –save permettant d’insĂ©rer vos packages dans le package.json ce qui permettra de dĂ©ployer votre application Ă  l’avenir avec un simple “npm install” sans avoir besoin de vous souvenir des noms de chaque package.

Maintenant vous devez crĂ©er un template Pug, Pug Ă©tant un langage simplifiĂ© du HTML qui a un gros avantage, c’est qu’on ne ferme aucune balise du coup le code est allĂ©gĂ©, prenons l’exemple d’une page HTML classique avec Bootstrap :

<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Mon Application</title>
    <link rel="stylesheet" href="" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <h1>Hello, world!</h1>
      <script src=""></script>
      <script src="" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

Celle-ci s’Ă©crira de cette façon avec Pug (faites un rĂ©pertoire views dans votre application avec un index.pug et copiez ce code dedans) :

		meta(http-equiv="X-UA-Compatible" content="IE=edge")
		meta(name="viewport" content="width=device-width, initial-scale=1")
		title Mon Application
		link(rel="stylesheet" href="" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous")
		h1 Hello, world!
		script(src="" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous")

Plus sympathique du coup pour de grandes pages html vous vous en doutez.

Si tout se passe bien, vous pouvez dĂšs maintenant lancer votre application nodejs en faisant un “node index.js”, si vous naviguez avec votre navigateur sur le port 80 comme dĂ©finit dans le code, vous verrez votre hello world.

Que faire maintenant ? on va bien entendu pousser la chose en codant un exemple de login avec un code de sécurité captcha et ainsi vous serez capable de coder vos propres applications.

Tout d’abord, il faut faudra modifier un peu votre index.js :

var express = require('express');
var app = express();
var pug = require('pug');
var io = require('').listen(app.listen(80));
var session = require('cookie-session');
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var sha256 = require('sha256');
var svgCaptcha = require('svg-captcha');

var MongoClient = require('mongodb').MongoClient;
var MongoClientURL = "mongodb://";

conf = {
	lang: "fr",
	title: "Mon application",
	urlsocketio: ""

app.use("/styles", express.static(__dirname + '/styles'));
app.set('view engine', 'pug');

app.use(session({secret: 'mysessionsecretpassphrase'}));
app.use(function(req, res, next){
    if (typeof(req.session.user) === 'undefined') {
        req.session.user = {};

app.get('/', function(req, res) {
	if (Object.keys(req.session.user).length > 0) {
		username = req.session.user.username;
		res.render('panel', { conf:conf, user:req.session.user }  );
    } else {
        var captcha = svgCaptcha.create();
    	req.session.captcha = captcha.text;
        res.render('index', { conf:conf, "captcha":captcha });
});'/login', urlencodedParser, function(req, res) {
	if(req.body.captcha === req.session.captcha) {
		MongoClient.connect(MongoClientURL, function(err, db) {
			db.collection('users').findOne({ 'username':req.body.username, 'password':sha256(req.body.password) }, function(err, result) {
				if(result !== null) {
	                req.session.user = result;
	} else {
		var captcha = svgCaptcha.create();
    	req.session.captcha = captcha.text;
    	res.render('index', { "captcha":captcha, "error":"The security code entered is not correct." });

app.get('/logout', function (req, res) {
    delete req.session.user;

Comme vous pouvez le voir dans cette exemple, on a rajoutĂ© tout ce qui est nĂ©cessaire pour gĂ©rer une page de login avec captcha en se connectant au serveur mongodb local sur la base de donnĂ©es “mydatabase”, vu que nous avons rajoutĂ© des packages npm il va falloir les installer un Ă  un :

npm install cookie-session body-parser sha256 svg-captcha mongodb –save

À noter qu’il est possible d’avoir du sha512 ou d’autres algos pour chiffrer ses mots de passes, rĂ©fĂ©rez vous aux diffĂ©rents packages npm.

Connectons nous Ă  notre base de donnĂ©es mongodb, de base sur Windows, il vous faudra lancer l’exĂ©cutable se trouvant dans :

C:\Program Files\MongoDB\Server\3.4\bin\

Vous aurez à ce moment là deux exécutables :

– mongo.exe : Le client CLI permettant de se connecter Ă  notre serveur mongodb.
– mongod.exe : Le serveur en lui mĂȘme.

ExĂ©cutons mongod.exe pour lancer notre serveur et connectons nous Ă  l’aide de mongo.exe, vous devriez pouvoir exĂ©cuter des commandes dans celui-ci, voici un rĂ©capitulatif des diffĂ©rentes commandes importantes :

show dbs : Permet de voir les base de données disponibles.
use namedb : Permet d’utiliser une base de donnĂ©es, namedb Ă©tant le nom de la base de donnĂ©es que vous souhaitez utiliser (donc mydatabase)
show collections : Permet de voir les tables de la base de données sélectionnée.
db.nametable.insert() : Permet d’insĂ©rer des donnĂ©es dans une table, nametable Ă©tant notre nom de table.
db.nametable.find() : Permet de chercher des données dans une table.
db.nametable.remove() : Permet de supprimer des données dans une table.
db.nametable.update() : Permet de mettre à jour des données dans une table.
db.nametable.drop() : Permet de drop totalement la table.

Il existe une multitude de commandes, je vous conseille de vous rendre sur la documentation officielle pour plus de détails.

Nous allons donc créer notre utilisateur admin avec le mot de passe admin1234 :

use mydatabase
db.users.insert( { username:"admin", password:"ac9689e2272427085e35b9d3e3e8bed88cb3434828b43b86fc0596cad4c6e270" } );

Le hash Ă©tant notre sha256 de “admin1234”, si tout se passe bien, vous devriez avoir comme rĂ©sultat :

WriteResult({ "nInserted" : 1 })

Nous pouvons donc maintenant nous connecter Ă  notre panel, pour cela il va aussi falloir modifier votre index.pug :

		meta(http-equiv="X-UA-Compatible" content="IE=edge")
		meta(name="viewport" content="width=device-width, initial-scale=1")
		title #{conf.title}
		link(rel="stylesheet" href="" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous")
		link(rel="stylesheet" href="styles/login.css")
						form.form-signin(action="login" method="post")
							h2.form-signin-heading Please sign in
							input.form-control(name="username" type="text" placeholder="Username..." required autofocus)
							input.form-control(name="password" type="password" placeholder="Password..." required)
							div#captcha !{}
							input.form-control(style="margin-bottom: 0.5em;" name="captcha" type="text" placeholder="Security code..." required)
							button.btn.btn-lg.btn-primary.btn-block(type="submit") Sign in
							if error
								p#error #{error}
		script(src="" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous")

Et créer un fichier styles/login.css :

* {
    margin: 0;
    padding: 0;
body {
    padding-top: 40px;
    padding-bottom: 40px;
    background-color: #eee;
.form-signin {
    max-width: 330px;
    padding: 15px;
    margin: 0 auto;
.form-signin .form-signin-heading,
.form-signin .checkbox {
    margin-bottom: 10px;
.form-signin .checkbox {
    font-weight: normal;
.form-signin .form-control {
    position: relative;
    height: auto;
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
    padding: 10px;
    font-size: 16px;
.form-signin .form-control:focus {
    z-index: 2;
.form-signin input[type="text"] {
    margin-bottom: -1px;
    border-bottom-right-radius: 0;
    border-bottom-left-radius: 0;
.form-signin input[type="password"] {
    margin-bottom: 10px;
    border-top-left-radius: 0;
    border-top-right-radius: 0;

#captcha {
    text-align: center;

#error {
    color: #ff0000;
    text-align: center;

Ainsi que notre panel.pug :

		meta(http-equiv="X-UA-Compatible" content="IE=edge")
		meta(name="viewport" content="width=device-width, initial-scale=1")
		title #{conf.title}
		link(rel="stylesheet" href="" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous")
		h1 hello #{user.username}

Vous avez maintenant un code avec un formulaire de login fonctionnel sous nodejs, express, mongodb et pugjs, qu’en est il de ?

Pour communiquer avec il nous suffit de modifier notre index.js en rajoutant :

io.sockets.on('connection', function (socket) {
	socket.emit('logged', "Le serveur vous salue !");

	socket.on('message', function (message) {

socket.emit se chargera d’envoyer un message au client, socket.on attendra la rĂ©ponse du client, il est aussi possible d’utiliser socket.broadcast.emit() pour envoyer un message Ă  tous les clients en mĂȘme temps.

Pour réceptionner le message cÎté client, il vous suffira de rajouter ce javascript dans panel.pug :

		meta(http-equiv="X-UA-Compatible" content="IE=edge")
		meta(name="viewport" content="width=device-width, initial-scale=1")
		title #{conf.title}
		link(rel="stylesheet" href="" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous")
		h1 hello #{user.username}
			var socket = io.connect('#{conf.urlsocketio}');
			socket.on('logged', function(message) {
				socket.emit('message', "Salut serveur, je suis connecté !");

VoilĂ , en espĂ©rant que cet article vous a permis d’avoir une bonne approche sur nodejs, mongodb, pugjs et express, vous ĂȘtes maintenant capable de dĂ©velopper en real time et de façon sĂ©curisĂ© (n’oubliez tout de mĂȘme pas que mongodb est certes du NoSQL mais NoSQL ne veut pas dire qu’il n’y a plus d’injections possibles, il vous faudra faire attention si vous utilisez les variables $where, $set et autres dans mongodb).

Une autre chose importante à savoir, de base mongodb autorise les connexions invités, vérifiez bien que votre serveur utilise son fichier de configuration pour ne pas autoriser de connexions distantes.

Voici les sources complÚtes de mon article légÚrement améliorées :


Pour dĂ©ployer la source, npm install 😉