Kategorie-Archiv: C

Web Application Security Scanner von Google

Skipfish ist ein in C geschriebenes Kommandozeilen-Tool von Google. Es ermöglicht das Scannen von Webseiten, um mögliche Schwachstellen und Sicherheitslücken früh zu identifizieren. Es geht dabei relativ flott und trotzdem genau zu werke. Der normale Test dauert durchaus einige Stunden, arbeitet trotzdem mit bis zu 2.000 HTTP Anfragen pro Sekunde (dank purem C-Code). Die sehr umfangreiche Testsuite deckt eigentlich alle bekannten Sicherheitsmängel ab und versucht diese in einer Webapplikation zu finden.

Die Software liegt nur als Quellcode vor und muss vor Gebrauch kompiliert werden, hier reicht ein einfaches make unter Linux etc. Falls Fehler auftreten: prüfen ob openssl installiert ist und ob die passenden devel-Pakete dazu vorliegen.

Ein umfangreicher Test prüft dabei auf folgende potentielle Schwachstellen:

  • High risk flaws (potentially leading to system compromise):
    • Server-side SQL injection (including blind vectors, numerical parameters).
    • Explicit SQL-like syntax in GET or POST parameters.
    • Server-side shell command injection (including blind vectors).
    • Server-side XML / XPath injection (including blind vectors).
    • Format string vulnerabilities.
    • Integer overflow vulnerabilities.
  • Medium risk flaws (potentially leading to data compromise):
    • Stored and reflected XSS vectors in document body (minimal JS XSS support present).
    • Stored and reflected XSS vectors via HTTP redirects.
    • Stored and reflected XSS vectors via HTTP header splitting.
    • Directory traversal (including constrained vectors).
    • Assorted file POIs (server-side sources, configs, etc).
    • Attacker-supplied script and CSS inclusion vectors (stored and reflected).
    • External untrusted script and CSS inclusion vectors.
    • Mixed content problems on script and CSS resources (optional).
    • Incorrect or missing MIME types on renderables.
    • Generic MIME types on renderables.
    • Incorrect or missing charsets on renderables.
    • Conflicting MIME / charset info on renderables.
    • Bad caching directives on cookie setting responses.
  • Low risk issues (limited impact or low specificity):
    • Directory listing bypass vectors.
    • Redirection to attacker-supplied URLs (stored and reflected).
    • Attacker-supplied embedded content (stored and reflected).
    • External untrusted embedded content.
    • Mixed content on non-scriptable subresources (optional).
    • HTTP credentials in URLs.
    • Expired or not-yet-valid SSL certificates.
    • HTML forms with no XSRF protection.
    • Self-signed SSL certificates.
    • SSL certificate host name mismatches.
    • Bad caching directives on less sensitive content.
  • Internal warnings:
    • Failed resource fetch attempts.
    • Exceeded crawl limits.
    • Failed 404 behavior checks.
    • IPS filtering detected.
    • Unexpected response variations.
    • Seemingly misclassified crawl nodes.
  • Non-specific informational entries:
    • General SSL certificate information.
    • Significantly changing HTTP cookies.
    • Changing Server, Via, or X-… headers.
    • New 404 signatures.
    • Resources that cannot be accessed.
    • Resources requiring HTTP authentication.
    • Broken links.
    • Server errors.
    • All external links not classified otherwise (optional).
    • All external e-mails (optional).
    • All external URL redirectors (optional).
    • Links to unknown protocols.
    • Form fields that could not be autocompleted.
    • All HTML forms detected.
    • Password entry forms (for external brute-force).
    • Numerical file names (for external brute-force).
    • User-supplied links otherwise rendered on a page.
    • Incorrect or missing MIME type on less significant content.
    • Generic MIME type on less significant content.
    • Incorrect or missing charset on less significant content.
    • Conflicting MIME / charset information on less significant content.
    • OGNL-like parameter passing conventions.

Check My Code – Automatische Codeprüfung für C Programme (online)

Auf der neuen Webseite checkMyCode.org können Programmierer kostenlos und online direkt ihre in C geschriebenen Programme mit Hilfe von einigen Millionen Regeln prüfen lassen. Die Regeln wurden dabei auf Basis einiger tausend Linux Pakete (200 Millionen LOC) erstellt. Findet die Software einen Regelverstoß, so wird dieser farblich hevorgehoben und kurz erklärt.

Praktisch wie ich finde, so kann man sich selber auf die schnelle überprüfen und findet potentielle Bugs noch bevor man das Programm überhaupt kompiliert hat :). Betrieben wird der Dienst übrigens vom Doktoranden Andrzej Wasylkowski und seinem Professor Andreas Zeller der Saarland Universität.

Design Pattern by Gamma und Co.

Jeder gute Programmierer sollte die grundlegenen Design Pattern von Gamma und Co. kennen. Für eine kleine 2-seitige Übersicht ist jetzt mit den Design Pattern Cards gesorgt.

Solche Pattern (Muster) helfen Probleme schnell und sauber zu lösen. Man kann sich damit sicher sein, eine gute Lösung zu nutzen und greift auf die langjährige Erfahrung einer ganzen Community zurück. Also, jeder sollte 5-10 Pattern kennen und auch anwenden können, ihr haltet damit euren Code wesentlich sauberer und besser wartbar!

Minimaler TCP Server & TCP Client in C

Ich habe mal einen minimalen Server in C geschrieben, mit dem passenden Client dazu. Es gibt wirklich nur die grundlegende ASCII Kommunikation, kein Protokoll oder ähnliches. Natürlich läuft die Verbindung intern über TCP/IP etc. Es gibt jedoch kein Protokoll auf Netzwerk-Ebene 5. Dieses müsste bei Bedarf selber entwickelt werden, bzw. auf ein bereits bestehendes sollte dann Zurückgegriffen werden.

Der Server:

#include <sys/types.h>    // für socket()
#include <sys/socket.h>   // für socket()
#include <netinet/in.h>   // für socket()
#include        // für assert()
#include        //für calloc()
#include         // für getprotobyname()
#include        // für close()
#include <arpa/inet.h>    //für inet_ntop()
#include <netinet/in.h>   //für INET_ADDRSTRLEN
#include        // für memset()
#include 
 
int main(void) {
	/* Socket erstellen - TCP, IPv4, keine Optionen */
	int lsd = socket(AF_INET, SOCK_STREAM, 0);
 
	/* IPv4, Port: 1111, jede IP-Adresse akzeptieren */
	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(1111);
	saddr.sin_addr.s_addr = htons(INADDR_ANY);
 
	/* Socket an Port binden */
	bind(lsd, (struct sockaddr*) &saddr, sizeof(saddr));
 
	/* Auf Socket horchen (Listen) */
	listen(lsd, 10);
 
	while(1) {
		/* Puffer und Strukturen anlegen */
		struct sockaddr_in clientaddr;
		char buffer[10];
		bzero(buffer, sizeof(buffer));
 
		/* Auf Verbindung warten, bei Verbindung Connected-Socket erstellen */
		socklen_t clen = sizeof(clientaddr);
		int csd = accept(lsd, (struct sockaddr*) &clientaddr, &clen);
 
		/* Vom Client lesen und ausgeben */
		int bytes = recv(csd, buffer, sizeof(buffer), 0);
		printf("Der Client hat folgenden String gesendet: %s\n", buffer);
		printf("Es wurden %d Bytes empfangen\n", bytes);
 
		/* Verbindung schließen */
		close(csd);
	}
 
	close(lsd);
	return EXIT_SUCCESS;
 
}

Der Client:

#include <sys/types.h>    // für socket()
#include <sys/socket.h>   // für socket()
#include <netinet/in.h>   // für socket()
#include        // für assert()
#include         // für getprotobyname()
#include        // für close()
#include <arpa/inet.h>    //für inet_ntop()
#include         //für getaddrinfo()
#include          // für memset()
#include  
#include 
#include 
 
int main(void) {
	/* Socket erstellen */
	int socks = socket(AF_INET, SOCK_STREAM, 0);
 
	/* Verbindungsziel festlegen, Port und IP-Adresse des Servers angeben */
	struct sockaddr_in serveraddr;
	bzero(&serveraddr, sizeof(serveraddr));
	inet_pton(AF_INET, "127.0.0.1", &(serveraddr.sin_addr));
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(1111);
 
	/* Verbindung aufbauen */
	connect(socks, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
 
	/* Puffer mit Text füllen */
	char buffer[5];
	strcpy(buffer, "test");
 
	/* "test" String an Server senden */
	int bytes = send(socks , buffer, sizeof(buffer), 0);
 
	/* Ausgabe was gesendet wurde */
	printf("Sende String: %s\n", buffer);
	printf("Es wurden %d Bytes gesendet\n", bytes);
 
	/* Verbindung beenden */
	close(socks);
 
	return EXIT_SUCCESS;
}

Die Ausgabe der beiden C Programmie sieht so aus:

VM-Ubuntu:~/Desktop$ gcc -Wall -o server TCPServer.c
VM-Ubuntu:~/Desktop$ gcc -Wall -o client TCPClient.c
VM-Ubuntu:~/Desktop$ ./server
Der Client hat folgenden String gesendet: test
Es wurden 5 Bytes empfangen

VM-Ubuntu:~/Desktop$ ./client
Sende String: test
Es wurden 5 Bytes gesendet

Das Ganze ist, wie man sieht, sehr minimalistisch gehalten, aber so kann man denke ich am besten verstehen was passiert und wie die Netzwerkprogrammierung in C funktioniert. Falls ihr die Programme selber kompilieren wollt, benötigt ihr den aktuellen gcc (oder ähnlichen C Compiler) und die passenden Bibliotheken (unter Ubuntu build-essentials installieren)!