Debugging native applications with WinDBG

Configurare windows perchè tramite (WER – Windows Error Reporting) crei un user-mode minidump quando un’applicazione va in crash:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx


“Starting with Windows Server 2008 and Windows Vista with Service Pack 1 (SP1), Windows Error Reporting (WER) can be configured so that full user-mode dumps are collected and stored locally after a user-mode application crashes. Applications that do their own custom crash reporting, including .NET applications, are not supported by this feature (for those see http://www.codeproject.com/Articles/1934/Post-Mortem-Debugging-Your-Application-with-Minidu).

This feature is not enabled by default. Enabling the feature requires administrator privileges. To enable and configure the feature, use the following registry values under the

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps

key.

Value Description Type Default value
DumpFolder The path where the dump files are to be stored. If you do not use the default path, then make sure that the folder contains ACLs that allow the crashing process to write data to the folder.For service crashes, the dump is written to service specific profile folders depending on the service account used.For example, the profile folder for System services is %WINDIR%\System32\Config\SystemProfile.
For Network and Local Services, the folder is %WINDIR%\ServiceProfiles.
REG_EXPAND_SZ %LOCALAPPDATA%\CrashDumps
DumpCount The maximum number of dump files in the folder. When the maximum value is exceeded, the oldest dump file in the folder will be replaced with the new dump file. REG_DWORD 10
DumpType Specify one of the following dump types:

  • 0: Custom dump
  • 1: Mini dump
  • 2: Full dump
REG_DWORD 1
CustomDumpFlags The custom dump options to be used. This value is used only when DumpType is set to 0.The options are a bitwise combination of the MINIDUMP_TYPE enumeration values. REG_DWORD MiniDumpWithDataSegs | MiniDumpWithUnloadedModules | MiniDumpWithProcessThreadData.

These registry values represent the global settings.

You can also provide per-application settings that override the global settings.

To create a per-application setting, create a new key for your application under

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps 
(for example,HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApplication.exe).

Add your dump settings under the MyApplication.exe key.

If your application crashes, WER will first read the global settings, and then will override any of the settings with your application-specific settings.

After an application crashes and prior to its termination, the system will check the registry settings to determine whether a local dump is to be collected.

After the dump collection has completed, the application will be allowed to terminate normally.

If the application supports recovery, the local dump is collected before the recovery callback is called.

These dumps are configured and controlled independently of the rest of the WER infrastructure.

You can make use of the local dump collection even if WER is disabled or if the user cancels WER reporting.

The local dump can be different than the dump sent to Microsoft.”


Testiamo quindi il tutto:

Creiamo un’applicazione nativa che vada in crash e chiamiamola WinDbgMinidumpTestCrash.exe (ecco il codice che utilizzerò per questo esempio)

#include <iostream>

using namespace std;

void main() {
	cout << "Hello, World!\n";
	cout << "Type a key\n";

	char c = 'a';
	cin >> c;

	// Crash!
	char *p;
	p[1] = 'b';
}

Abilitiamo quindi la generazione dei minidump per questa applicazione:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\WinDbgMinidumpTestCrash.exe]
"DumpType"=dword:00000001
"DumpFolder"=hex(2):43,00,3a,00,5c,00,74,00,65,00,6d,00,70,00,00,00

La cartella DumpFolder è “C:\temp”, il tipo di Dump è 1 (minidump).

Lanciamo quindi l’applicazione che andrà in crash e genererà a questo punto il suo minidump all’interno di C:\temp
windbg_crash1

windbg_crash2
A questo punto dobbiamo andare a lanciare WinDBG e caricare il file di dump appena creato:

Solo caricando il file… ci ammonisce che abbiamo un’eccezione…
windbg_crash3

Configuriamo la cartella dove mettere i simboli delle classi di Microsoft

*** configure symbols to be downloaded from Microsoft
.symfix c:\symbols

Ricarichiamo il tutto (lasciamo il tempo al download dei simboli)

*** Reload anything which has been loaded so far
.reload

windbg_crash4
Poi andiamo ad eseguire il comando che WinDbg ci diceva di lanciare per accedere alle informazioni sulla nostra eccezione

.excr

E boom! Ecco la riga incriminata! 😀
windbg_crash5
Se andiamo a lanciare anche il comando

!analyze -v

Ecco che WinDBG ci mostra esattamente il punto anche nella finestra di comando:

windbg_crash_analyze_v

 

Nel caso in cui il progetto con cui è stato compilato l’eseguibile non si trovi più nello stesso percorso (il modulo da errore di caricamento symboli):

crash_windbg7
occrre andare a dire a WinDBG dove trovare il .pdb e i sorgenti con gli appositi menu:
crash_windbg8
E richiamare nuovamente .ecxr

crash_windbg9

Ed ecco riapparire il nostro codice incriminato!

Ecco perchè a volte è bene tenere sotto versioning anche i file compilati e i file con i simboli di debug 😉
crash_windbg10

 

Debugging native applications with WinDBG

Creare un certificato SSL di durata maggiore di 2 anni tramite CA Server Windows

Installate la CA su di un Server di dominio facendo attenzione ad installare anche il ruolo di “Certification Authority Web Enrollment” e impostando il certificato della CA ad un valore di anni opportuno (e.g. se volete un certificato utente di 20 anni allora il certificato della rootCA deve essere di almeno 20 anni).

server_roles

Da un IIS generare una richiesta di certificato. Io la richiesta l’ho fatta direttamente dall’IIS (versione 7) della mia CA.

iis_request

Occorre andare a duplicare il Template WebServer (che di default ha validità dei certificati rilasciati di 2 anni) e mettere la validità a 20 anni.

template

template_20

A questo punto occorre accedere al webservice direttamente dalla CA o da un PC con le credenziali opportune per l’Enroll dei certificati

https://localhost/certsrv

e cliccare su “Request a Certificate“.

request

Scegliere la modalità avanzata

advanced_request

Mettere la richiesta (base64) generata in precedenza nel campo richiesto

submit_request

E scaricare il proprio certificato in formato .cer

Una volta scaricato il certificato l’ho importato nella mia CA nello snap-in  “Certificates” di mmc.

Una volta importato lo potete esportare in formato .pfx includendo la chiave privata.

In questo modo il certificato .pfx sarà pronto per poter essere installato sul server web per il quale era stata fatta la richiesta.

N.B. Attenzione che io sono risucito a generare un certificato con un template di 20 anni perchè il certificato della mia rootCA aveva validità ventennale. Se voi avete un certificato della vostra rootCA che ha validità X anni allora dovete generare un duplicato del template WebServer che abbia validità al massimo X anni!

Io ho anche modificato i valori dei seguenti registry:

reg_values

—————————-

Non ero subito riuscito a generare il certificato… ecco l post che avevo fatto su serverfault. Ho fatto varie prove di duplicazione template e generazione della richiesta.

Alla fine facendo tutto dalla CA (richiesta + installazione snap-in + export del certificato) sono riuscito ad avere il mio file .pfx da importare su IIS7 del server per il quale avevo richiesto il certificato.

http://serverfault.com/questions/689999/windows-server-2012-root-enterprise-certification-authority-issue-certificates-o/690858#690858

Creare un certificato SSL di durata maggiore di 2 anni tramite CA Server Windows

How to configure Windows Firewall to allow pings (Win7 and above)

1. From the Start menu, search for Windows Firewall with Advanced Security and choose it.

2. From the left pane, click Inbound Rules.

3. In the right pane, find the rules titled File and Printer Sharing (Echo Request – ICMPv4-In).

4. Right-click each rule and choose Enable Rule.

How to configure Windows Firewall to allow pings (Win7 and above)

Arduino e applicazione time-critical

Ho visto molte librerie online che ti permettono di leggere e scrivere gli I/O più velocemente su Arduino.

Il fatto è che se siamo sensibili ai tempi di risposta (si parla di microsecondi) e lavoriamo con molti output allora non ci resta che sporcarci le mani con i registri.

Fonte: http://www.arduino.cc/en/Reference/PortManipulation

Ecco il classico esempio “Blink” riscritto utilizzando i registri:

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  DDRB = DDRB | B00100000;
}

// the loop function runs over and over again forever
void loop() {
  PORTB = PORTB | B00100000;  // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  PORTB = PORTB & B11011111;    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

Port Registers

Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Arduino board. The chips used on the Arduino board (the ATmega8 and ATmega168) have three ports:

  • B (digital pin 8 to 13)
  • C (analog input pins)
  • D (digital pins 0 to 7)

Each port is controlled by three registers, which are also defined variables in the arduino language. The DDR register, determines whether the pin is an INPUT or OUTPUT. The PORT register controls whether the pin is HIGH or LOW, and the PIN register reads the state of INPUT pins set to input with pinMode(). The maps of the ATmega8 and ATmega168 chips show the ports. The newer Atmega328p chip follows the pinout of the Atmega168 exactly.

DDR and PORT registers may be both written to, and read. PIN registers correspond to the state of inputs and may only be read.

PORTD maps to Arduino digital pins 0 to 7

DDRD – The Port D Data Direction Register – read/write
PORTD – The Port D Data Register – read/write
PIND – The Port D Input Pins Register – read only

PORTB maps to Arduino digital pins 8 to 13 The two high bits (6 & 7) map to the crystal pins and are not usable

DDRB – The Port B Data Direction Register – read/write
PORTB – The Port B Data Register – read/write
PINB – The Port B Input Pins Register – read only

PORTC maps to Arduino analog pins 0 to 5. Pins 6 & 7 are only accessible on the Arduino Mini

DDRC – The Port C Data Direction Register – read/write
PORTC – The Port C Data Register – read/write
PINC – The Port C Input Pins Register – read only

Each bit of these registers corresponds to a single pin; e.g. the low bit of DDRB, PORTB, and PINB refers to pin PB0(digital pin 8). For a complete mapping of Arduino pin numbers to ports and bits, see the diagram for your chip:ATmega8, ATmega168. (Note that some bits of a port may be used for things other than i/o; be careful not to change the values of the register bits corresponding to them.)

Examples

Referring to the pin map above, the PortD registers control Arduino digital pins 0 to 7.

You should note, however, that pins 0 & 1 are used for serial communications for programming and debugging the Arduino, so changing these pins should usually be avoided unless needed for serial input or output functions. Be aware that this can interfere with program download or debugging.

DDRD is the direction register for Port D (Arduino digital pins 0-7). The bits in this register control whether the pins in PORTD are configured as inputs or outputs so, for example:

DDRD = B11111110;  // sets Arduino pins 1 to 7 as outputs, pin 0 as input
DDRD = DDRD | B11111100;  // this is safer as it sets pins 2 to 7 as outputs
	                  // without changing the value of pins 0 & 1, which are RX & TX
                          //See the bitwise operators reference pages and The Bitmath Tutorial in the Playground

PORTD is the register for the state of the outputs. For example;

PORTD = B10101000; // sets digital pins 7,5,3 HIGH

You will only see 5 volts on these pins however if the pins have been set as outputs using the DDRD register or with pinMode().

PIND is the input register variable It will read all of the digital input pins at the same time.

Why use port manipulation?

From The Bitmath Tutorial

Generally speaking, doing this sort of thing is not a good idea. Why not? Here are a few reasons:

  • The code is much more difficult for you to debug and maintain, and is a lot harder for other people to understand. It only takes a few microseconds for the processor to execute code, but it might take hours for you to figure out why it isn’t working right and fix it! Your time is valuable, right? But the computer’s time is very cheap, measured in the cost of the electricity you feed it. Usually it is much better to write code the most obvious way.
  • The code is less portable. If you use digitalRead() and digitalWrite(), it is much easier to write code that will run on all of the Atmel microcontrollers, whereas the control and port registers can be different on each kind of microcontroller.
  • It is a lot easier to cause unintentional malfunctions with direct port access. Notice how the line DDRD = B11111110; above mentions that it must leave pin 0 as an input pin. Pin 0 is the receive line (RX) on the serial port. It would be very easy to accidentally cause your serial port to stop working by changing pin 0 into an output pin! Now that would be very confusing when you suddenly are unable to receive serial data, wouldn’t it?

So you might be saying to yourself, great, why would I ever want to use this stuff then? Here are some of the positive aspects of direct port access:

  • You may need to be able to turn pins on and off very quickly, meaning within fractions of a microsecond. If you look at the source code in lib/targets/arduino/wiring.c, you will see that digitalRead() and digitalWrite() are each about a dozen or so lines of code, which get compiled into quite a few machine instructions. Each machine instruction requires one clock cycle at 16MHz, which can add up in time-sensitive applications. Direct port access can do the same job in a lot fewer clock cycles.
  • Sometimes you might need to set multiple output pins at exactly the same time. Calling digitalWrite(10,HIGH); followed by digitalWrite(11,HIGH); will cause pin 10 to go HIGH several microseconds before pin 11, which may confuse certain time-sensitive external digital circuits you have hooked up. Alternatively, you could set both pins high at exactly the same moment in time using PORTB |= B1100;
  • If you are running low on program memory, you can use these tricks to make your code smaller. It requires a lot fewer bytes of compiled code to simultaneously write a bunch of hardware pins simultaneously via the port registers than it would using a for loop to set each pin separately. In some cases, this might make the difference between your program fitting in flash memory or not!
Arduino e applicazione time-critical

Creare un webservice a partire dal suo wsdl

Vi hanno chiesto di fare un Web Service che rispetti una certa interfaccia wsdl e vi hanno dato solo il file .wsdl?

Niente paura, partite da qui:

1. Aprite il command prompt di visual studio

2. Andate nella directory che contiene il vostro file .wsdl chiamiamolo webservice.wsdl

3. Eseguite il comando

wsdl.exe webservice.wsdl /l:CS /serverInterface

dove /l da il linguaggio da utilizzare (CS=C#, VB=Visual Basic).

Verrà generato il vile .cs da importare nel vostro progetto WebService.

Non dovrete fare altro che andare a dire alla classe del vostro WebService di implementare tale interfaccia.

Buon lavoro!

Creare un webservice a partire dal suo wsdl

Network TAP port

Abbiamo visto come installare Snort su Raspberry Pi e come lanciarlo.

Ma per utilizzare Snort come IDS è necessario servirzi di un hardware dedicato: uno switch che abbia una porta in Mirroring.

Questo tipo di porte vengono anche chiamate TAP o Span port.

C’è chi si costruisce le sue span port “home made”, ma per essere un po’ più industriali e spendere poco possiamo comprare il Netgear GS105E che permette di mettere in mirroriing le porte su di un’altra.

IMG_1250

 

Network TAP port

Sendmail è lento ad inviare email?

Controllate

/var/log/mail.log

Probabilmente troverete qualcosa simile a questo:

Mar 28 16:40:02 kali sm-msp-queue[7565]: My unqualified host name (yourhostname) unknown; sleeping for retry

Aggiornate

/etc/hosts

affinchè la riga con

127.0.0.1 yourhostname localhost ...

sia simile a

127.0.0.1 localhost.localdomain localhost yourhostname

Il gioco è fatto! 😀

Sendmail è lento ad inviare email?

Utilizzare Snort

Se non avete installato Snort, potete leggere questo nostro articolo su come installarlo su Raspberry Pi.

Se lo avete installato con il comando

apt-get install snort

Allora vi basta diminuire solamente il numero di max_tcp e lanciare il comando (vedi sotto)

snort -dev -l ./log -h 192.168.1.0/24 -c /etc/snort/snort.conf

Se lo avete installato compilando i sorgenti invece, la questione diventa più briosa in quanto occorre settare bene lo snort.config come di seguito.

Una volta installato occorre però aggiornarlo.

Seguiamo quindi i passi che ci dice la guida ufficiale su Snort.org allo Step 3:

0. Creare se non esistono le directory
root@kali:~/tmp# mkdir /etc/snort
root@kali:~/tmp# mkdir /etc/snort/rules
1. Community Rules
wget https://www.snort.org/rules/community
tar -xvfz community.tar.gz -C /etc/snort/rules
2. Registered Rules
wget https://www.snort.org/rules/snortrules-snapshot-2962.tar.gz?oinkcode=
wget https://www.snort.org/rules/snortrules-snapshot-2970.tar.gz?oinkcode=
wget https://www.snort.org/rules/snortrules-snapshot-2972.tar.gz?oinkcode=
tar -xvfz snortrules-snapshot-.tar.gz -C /etc/snort/rules
3. Subscriber Rules
... sono a pagamento ...

Creare la directory:

/usr/local/lib/snort_dynamicrules

Ridurre il max_tcp altrimenti il Raspberry non ce la fa… poverone! 😀

# Target-Based stateful inspection/stream reassembly.  For more inforation, see README.stream5
preprocessor stream5_global: track_tcp yes, \
   track_udp yes, \
   track_icmp no, \
   max_tcp 26214, \
   max_udp 131072, \
   max_active_responses 2, \
   min_response_seconds 5

cambiare i file di whitelist e blacklist:

white_list.rules -> whitelist.rule
black_list.rules -> blacklist.rule

# Reputation preprocessor. For more information see README.reputation
preprocessor reputation: \
   memcap 500, \
   priority whitelist, \
   nested_ip inner, \
   whitelist $WHITE_LIST_PATH/whitelist.rule, \
   blacklist $BLACK_LIST_PATH/blacklist.rule  

portarsi nella directory

/etc/snort/rules/etc

e lanciare il comando

snort -d -h 192.168.0.0/24 -l ./log -c snort.conf 

I parametri dipendono ovviamente dal tipo di LAN che volete monitorare.

Per i dettagli leggere il manuale di Snort su Snort.org.

A questo punto per testarlo andiamo a mettere in

/etc/snort/rules/local.rules 

la seguente regola

# $Id: local.rules,v 1.11 2004/07/23 20:15:44 bmc Exp $
# ----------------
# LOCAL RULES
# ----------------
# This file intentionally does not come with signatures.  Put your local
# additions here.

# Test ping
#alert ip any any -> any any (msg: "IP Packet detected"; sid: 8888888)
alert icmp any any -> any any (msg: "TEST PING *** ^^ *** ICMP Packet found"; sid: 888888)

Che testa anche il PING essendo una richiesta echo ICMP.

Lanciamo snort e pinghiamo il nostro gateway:

ping 192.168.0.1

andiamo quindi ad analizzare i nostri alert

more ./log/alert

e vediamo che la nostra regola ha fatto scattare l’allarme!!! 😀

[**] [1:888888:0] TEST PING *** ^^ *** ICMP Packet found [**]
[Priority: 0] 
03/27-21:14:27.294037 A8:20:66:27:D5:F6 -> E0:91:F5:F9:2D:4E type:0x800 len:0x62
192.168.0.6 -> 192.168.0.1 ICMP TTL:64 TOS:0x0 ID:12623 IpLen:20 DgmLen:84
Type:8  Code:0  ID:3591   Seq:0  ECHO
Utilizzare Snort