Jun 02
    Change language to:

 

# Mini howto, IPF
#
# Door Remko Lodder (nightw@root66.org/remko@elvandar.org)
#
# Datum:
# 15 December 2002 (Initiele versie van het document)
# 27 Juni 2003 (2e versie van het document)
#
# Voorkennis:
# Basis kennis TCP/IP
# Basis kennis Unix (incl ifconfig / interfaces )
#
# Dit documentje is geschreven voor de beginnenden ipf’er.
# Het dekt een opbouw van:
# Wat willen we?
# Wat doen we daarmee?
# Hoe wie wat waar? IPF regeltjes
# Wat betekenen die regeltjes eigenlijk?
# Wat zijn verbeter mogelijkheden?
# Hoe ziet een complete ruleset eruit?
# Waar kan ik meer informatie vinden?
#
################################################################################
#
# Hoofdstuk indeling:
# 1. Wat willen we precies?
# 2. Wat gaan we daarmee doen?
# 3. Hoe wie wat waar? IPF regeltjes
# 4. Wat betekenen die regeltjes eigenlijk?
# 5. Wat zijn verbeter mogelijkheden?
# 6. Hoe ziet een complete ruleset eruit?
# 7. Waar kan ik meer informatie vinden?
#
################################################################################
#
# 1. Wat willen we precies?
#
# Allereerst uitleggen wat ipf is:
#
# Ipf is een firewall package voor onder andere NetBSD/FreeBSD en met wat
# aanpassingen ook voor OpenBSD.
#
# Ieders wens is anders. Daarom heb ik gekozen om een voorbeeld te
# geven die ook in het echt gebruikt had kunnen worden.
# Op dit moment gebruik ik in /etc/hosts de naam: ipf-host.
# Die heb ik als volgende gedefinieerd:
#
# 123.456.789.123 ipf-host host ipf
#
# Hierdoor is het ipadres voor ipf herkenbaar als ipf-host
# en hoef je geen ipadressen in je ipf.conf te zetten.
#
# Hierachter wil ik draaien:
# Inkomend:
# 1) een webserver (http)
# 2) een secure webserver (https)
# 3) een mailserver (smtp)
# 4) een dnsserver (dns)
# 5) een ipv6 tunnel (ipv6)
#
# Uitgaand:
# 1) naar dnsserver (dns)
# 2) naar ipv6 tunnel (ipv6)
#
# Overigens gaan we ervanuit dat onze netwerkkaart in dit geval
# xl0 is. Inderdaad, in dit voorbeeld hebben we EEN netwerkkaart.
# in dit geval, maar regels toevoegen is niet erg lastig zoals
# zodadelijk zal blijken
################################################################################
#
# 2. Wat gaan we daarmee doen?
#
# We zullen eerst moeten achterhalen welke poorten en protocollen
# nodig zijn om aan onze wensen te voldoen.
# Dat komt erop neer dat we voor onze services de poorten het
# eerst gaan zoeken:
# Inkomend:
# Service = Poortnr. Protocolnaam
# 1) http = 80 tcp
# 2) https = 443 tcp
# 3) smtp = 25 tcp
# 4) dns = 53 udp
# 5) ipv6 = x ipv6 (voor tunneling!)
#
# Uitgaand:
# Service = Poortnr. Protoclnaam
# 1) dns = 53 udp
# 2) ipv6 = x ipv6 (voor tunneling!)
#
# Nu we de poorten en protocollen weten, kunnen we gaan bepalen
# wat er precies naar binnen mag komen op bovenstaande poorten
# en protocollen en van wie dat geaccepteerd wordt.
#
# In dit voorbeeld hebben we dit beleid:
# Inkomend:
# Service Geaccepteerd van
# 1) http iedereen
# 2) https iedereen
# 3) smtp iedereen
# 4) dns iedereen
# 5) ipv6 niemand
#
# Uitgaand:
# Service Geaccepteerd naar
# 1) dns iedereen
# 2) ipv6 ipv6-tun (xs4all tunnelbroker)
#
# Zo, nu is duidelijk en overzichtelijk wat we precies gaan
# accepteren en welke kant het pakketje opgaat.
# Als je nu denkt, maar alleen inkomend http verkeer? Dat verkeer
# moet toch ook nog terug? Dat klopt. Dat wordt in het volgende
# hoofdstuk uitgelegd hoe dat in zijn werk gaat.
#
################################################################################
#
# 3. Wie wat waar? IPF regeltjes
#
# Om het voorbeeld in het voorgaande hoofdstuk in de praktijk te kunnen brengen
# moeten er firewall regeltjes gemaakt worden.
# Deze hebben nu nog een relatief korte uitleg, maar wees niet
# bezorgd in het volgende hoofdstuk wordt dit regel voor regel
# uitgelegd.
#
# Om bovenstaand beleid ten uitvoer te brengen hebben we de
# volgende regels nodig:
#
# Inkomend:
# Volgorde: smtp - http - https - dns
# pass in quick on xl0 proto tcp from any to ipf-host port 25 keep state
# pass in quick on xl0 proto tcp from any to ipf-host port 80 keep state
# pass in quick on xl0 proto tcp from any to ipf-host port 443 keep state
# pass in quick on xl0 proto udp from any to ipf-host port 53 keep state
#
# Uitgaand:
# Volgorde: dns - ipv6
# pass out quick on xl0 proto udp from ipf-host to any port 53 keep state
# pass out quick on xl0 proto ipv6 from ipf-host to ipv6-tun keep state
#
################################################################################
#
# 4. Wat betekenen die regeltjes eigenlijk?
#
# Oke, nu hebben we functionele regels. Deze regels zullen wel werken, echter
# niet in deze context. Een complete ruleset (voorbeeld) wordt later gegeven
# die wel functioneel is.
#
# Allemaal pass in quick regeltjes, wat doen ze nu precies?
# Dit leggen we uit aan de hand van een voorbeeld:
# pass in quick on xl0 proto tcp from any to ipf-host port 25 keep state
#
# Uitgelegd in woorden:
# accepteer inkomend, controleer niet verder op andere regels, op interface xl0
# protocol tcp, van wie dan ook, naar mijn ip adres, poort 25 (smtp), en houd
# sessie informatie in de gaten.
#
# Maar wat doet het nu precies, want dat keep state ?
# Keep state zorgt ervoor dat een pakketje dat naar binnenkomt ook weer terug
# naar buiten mag. Hierdoor hoeven we niet een aparte regel uitgaand te
# maken, maar kunnen we een dichtere firewall ruleset bouwen. Dit is veiliger.
#
# Uitgaand geldt natuurlijk precies hetzelfde alleen dan de andere kant op
#
################################################################################
#
# 5. Wat zijn verbetermogelijkheden?
#
# Onder IPF kunnen we de dingen soms beter organiseren dan nu.
# Bijvoorbeeld door elke inkomende stroming (verkeer) op elke netwerkkaart (als je er
# meerdere hebt) apart te defineren. Dit doe je dan ook met de uitgaande groep
# Als je dan een log regel krijgt van ipmon (de logdaemon van ipf) kan je zien
# waar het geheel zich ongeveer afspeelt, welke service , of reeks ipadressen
# etc.
# Dit kunnen we implementeren door wat dingen toe te voegen:
#
# We willen een ‘overrulende block’ dat heb ik geimplementeerd door dit te doen
#
# block in log quick on xl0 all head 1
#
# We hebben nu de begin definitie van groep 1 aangemaakt. (Block alles op de
# interface xl0 als het niet in groep 1 valt)
# Aan het einde heb ik een soortgelijk statement staan
#
# block in log quick on xl0 all group 11
#
# Dit is de overrulling block regel voor mij bij mijn interface (xl0)
# Note: Voor de duidelijkheid heb ik zoveelmogelijk netjes onder elkaar staan zodat je
# in 1 oogopslag kan zien wat voor regel het is.
#
# Het blockje komt er dan zo uit te zien:
#
# Inkomend:
# block in log quick on xl0 all head 1
# pass in quick on xl0 proto tcp from any to ipf-host port 25 keep state group 1
# pass in quick on xl0 proto tcp from any to ipf-host port 80 keep state group 1
# pass in quick on xl0 proto tcp from any to ipf-host port 443 keep state group 1
# pass in quick on xl0 proto udp from any to ipf-host port 53 keep state group 1
# block in log quick on xl0 all group 1
#
# Uitgaand:
# block out log quick on xl0 all head 2
# pass out quick on xl0 proto udp from ipf-host to any port 53 keep state group 2
# pass out quick on xl0 proto ipv6 from ipf-host to ipv6-tun keep state group 2
# block out log quick on xl0 all group 2
#
# Daarnaast kunnen we ook nog wat meer veiligheid inbouwen door flags te gebruiken
# Flags zijn alleen toepasbaar op tcp pakketjes. Deze hebben de volgende methode
# voor het opbouwen van een verbinding:
# Syn(S) -> Syn/Ack(S/A) -> Ack(A)
# Dat kan je ook als volgt uitleggen:
# Hoi ben je er? -> Ja ik ben er -> Ok kom maar op met je data
#
# Flags zorgen ervoor dat bijvoorbeeld alleen verbindingen die beginnen met een Syn(S) pakket
# mogen binnen komen. Als er dan keep state bijstaat wordt de rest van
# de tcp verbinding ook doorgelaten
#
# Hoe ziet dat eruit?
#
# # Inkomend:
# block in log quick on xl0 all head 1
# pass in quick on xl0 proto tcp from any to ipf-host port 25 flags S keep state group 1
# pass in quick on xl0 proto tcp from any to ipf-host port 80 flags S keep state group 1
# pass in quick on xl0 proto tcp from any to ipf-host port 443 flags S keep state group 1
# pass in quick on xl0 proto udp from any to ipf-host port 53 keep state group 1
# block in log quick on xl0 all group 1
#
# Uitgaand:
# block out log quick on xl0 all head 2
# pass out quick on xl0 proto udp from ipf-host to any port 53 keep state group 2
# pass out quick on xl0 proto ipv6 from ipf-host to ipv6-tun keep state group 2
# block out log quick on xl0 all group 2
#
#
################################################################################
#
# 6. Hoe zit een complete ruleset eruit?
#
# We hebben net enkele kleine voorbeelden gegeven over wat je allemaal in een
# ruleset kunt zetten. Echter nu hebben we nog steeds geen duidelijk overzicht
# over hoe nu een compleet functionele firewall ruleset eruit zou zien.
# Hieronder zal ik een voorbeeld, echt werkend, geven over hoe mijn firewall
# ruleset eruit zou zien als ik bovenstaand beleid / policy ten uitvoer zou
# brengen.
#
# Voorbeeld ruleset:
#
# # Inkomend lo0
# block in log quick on lo0 head 50
# pass in quick on lo0 all group 50
# block in log quick on lo0 group 50
#
# # Uitgaand lo0
# block out log quick on lo0 head 51
# pass out quick on lo0 all group 51
# block out log quick on lo0 group 51
#
# # Inkomend: xl0
# block in log quick on xl0 all head 1
# pass in quick on xl0 proto tcp from any to ipf-host port 25 flags S keep state group 1
# pass in quick on xl0 proto tcp from any to ipf-host port 80 flags S keep state group 1
# pass in quick on xl0 proto tcp from any to ipf-host port 443 flags S keep state group 1
# pass in quick on xl0 proto udp from any to ipf-host port 53 keep state group 1
# block in log quick on xl0 all group 1
#
# # Uitgaand: xl0
# block out log quick on xl0 all head 2
# pass out quick on xl0 proto udp from ipf-host to any port 53 keep state group 2
# pass out quick on xl0 proto ipv6 from ipf-host to 195.109.5.241 keep state group 2
# block out log quick on xl0 all group 2
#
################################################################################
#
# 7. Waar kan ik meer informatie vinden?
#
# Na deze zeer korte en beknopte uitleg zal je misschien denken:
# Ik wil veel meer weten over ipf en hoe het werkt en dergelijke
# Natuurlijk kan je mij een mailtje sturen met daarin je vraag.
# Wat je echter ook kan doen, is zelf uitzoeken hoe het werkt.
# Dat kan je doen door naar www.ipfilter.org te surfen of
# als die niet werkt: http://coombs.anu.edu.au/ipfilter/
# Dat zijn de officiele pagina’s van Darren Reed (de schrijver van ipf).
# Hier kun je terecht voor FAQ’s, en howto documentatie (engels)
#
# Ik hoop dat je hier van geleerd hebt, en interessante rulesets
# gaat bouwen met IPF.
#
################################################################################
#
# Copyright:
# Dit document is geschreven door Remko Lodder voor o.a
# www.mostly-harmless.nl
#
################################################################################
#
# Mochten er spelfouten/dingen niet duidelijk zijn/ verkeerd zijn
# wordt u verzocht contact op te nemen met Remko Lodder
# (nightw@root66.org of remko@elvandar.org) zodat dit aangepast /
# beter uitgelegd / verbeterd kan worden.
#
################################################################################

Continue reading »

written by Remko

Jun 02
    Change language to:

 

SQL Injection voor beginners
-door: Mark IJbema (vandread)-

-Doel van deze handleiding

Het doel van deze handleiding is om voor beginners SQL injection duidelijk te
maken.

Voor vragen en opmerkingen: mark@ijbema.xs4all.nl

-Conventies

In een url dient alles tussen accolades uri-encoded (%.. tekens) te
worden, en de accolades zelf niet gebruikt te worden, maar voor de
leesbaarheid is dat in deze tutorial dus niet gedaan (overigens doen een
hoop browsers dit automatisch voor alles behalve het ‘=’ charachter, als
je die even zelf doet (%3D) dan werkt het waarschijnlijk ook al)

-Wat is SQL

SQL is een taal om een database te benaderen. Er zijn zowel opdrachten om dingen
op te vragen als om dingen te wijzigen. Dingen opvragen doe je als volgt:

SELECT <kolommen>
FROM <tabellen>
WHERE <voorwaarden>

Dus bijvoorbeeld:

SELECT naam, beschrijving, prijs
FROM produkten
WHERE naam = ‘128MB RAM’

Waarmee je de prijs opvraagt van 128MB RAM. Omdat je echter vaak maar een
resultaat wil, en een naam niet perse uniek is gebruikt men vaak unieke
ID’s. Dus als het ID van 128MB RAM bijvoorbeeld 12 is, ziet de query (zo heet
een selectie in SQL) er als volgt uit:

SELECT naam, beschrijving, prijs
FROM produkten
WHERE id = 12

Verder heb je ook update’s en dergelijke om gegevens te wijzigen, maar het voert
te ver om er hier dieper op in te gaan.

-Gebruik van SQL vanaf websites

Stel je hebt een webpagina om van een product gegevens weer te geven. Je krijgt
nu als parameter het id van het product voor. De URL van de pagina ziet er als
volgt uit:

http://www.example.com/product.php?id=12

waarna in de PHP code het id in de query wordt verwerkt. Het id staat in $id, en
vervolgens wordt de query als volgt opgebouwd:

$query = “SELECT naam, beschrijving, prijs FROM produkten WHERE id = $id”

hetgeen als $id 12 is resulteert in:

SELECT naam, beschrijving, prijs FROM produkten WHERE id = 12

wat een mooie geldige query is.Maar men is vergeten te checken of $id wel een
nummer is en als we nu in de query 12 vervangen door iets anders wordt dat op de
plaats van 12 geplakt. Dus bijvoorbeeld:

http://www.example.com/product.php?id=onzin

levert

SELECT naam, beschrijving, prijs FROM produkten WHERE id = onzin

op, en waarschijnlijk krijg je nu een error als “onzin is not a number”. Maar je
kan dus ook de SQL aanvullen, bijvoorbeeld:

http://www.example.com/product.php?id={666666 OR id = 13}

levert op:

SELECT naam, beschrijving, prijs FROM produkten WHERE id = 666666 OR id = 13

en je krijgt nu dus produkt 13 te zien (ervan uitgaande dat 666666 geen geldig
id is).

-Union

Een van de belangrijkste technieken bij SQL injection is de UNION operator. In
het vorige voorbeeld kan je aanpassen wat je wilt, maar je krijgt als uitvoer
altijd een naam, een beschrijving en een prijs. Dit is meestal helemaal niet
interessant. Stel nu dat er in dezelfde database ook een lijst usernames,
passwords en ids staan, dan wil je juist die hebben.

Dit kan je doen met de volgende query:

SELECT username, password FROM users WHERE id = 1

er bestaat in SQL de UNION operator om queries aan elkaar te plakken, mits het
aantal kolommen van de beide queries gelijk is en de types van de resultaten ook
paarsgewijs gelijk zijn (string, int, etc.). Dus om de vorige query aan de
produkt-query toe te voegen moet er nog een extra integerkolom bij (ervan
uitgaande dat de prijs als integer in de database staat). De query met de union
erbij komt er dan als volgt uit te zien:

SELECT naam, beschrijving, prijs FROM produkten WHERE id = 12
UNION
SELECT username, password, id FROM users WHERE id = 1

door nu voor 12 een nietbestaand id te gebruiken wordt de eerste query leeg, en
bestaat het resultaat alleen uit de tweede query. Dus:

SELECT naam, beschrijving, prijs FROM produkten WHERE id = 666666
UNION
SELECT username, password, id FROM users WHERE id = 1

We verkrijgen deze query mbv de volgende URL:

http://www.example.com/product.php?id={666666 UNION SELECT username,
password, id FROM users WHERE id = 1}

Zo kunnen we dus van een user het wachtwoord uitlezen. Als je van alle
users het wachtwoord en de username wilt, kan je een scriptje schrijven
dat deze pagina ophaalt voor alle id’s, de pagina parsed, en in een
netjes formaat de output laat zien.

-Strings

Vaak worden in plaats van id’s of andere getallen ook strings
meegegeven, bijvoorbeeld:

http://www.example.com/listusers?name=mark

Geeft de lijst van alle gebruikers weer die mark heten. Dit ziet er
ongeveer zo uit intern

SELECT … FROM … WHERE … AND name=’mark’ AND …

Nu willen we niet alle gebruikers met naam ‘mark’ hebben, maar met
password ‘wachtwoord’. Dus we willen van de query het volgende maken:

SELECT … FROM …
WHERE … AND name=’onzin’ OR password = ‘wachtwoord’ AND …

Hetgeen we krijgen met de volgende url:
http://www.example.com/listusers?name={onzin’ OR password = ‘wachtwoord}

Soms is het echter handiger om het laatste deel te negeren, door er
commentaar van te maken, de query wordt dan:

SELECT … FROM …
WHERE … AND name=’onzin’ OR password = ‘wachtwoord’– AND …

En de url:
http://www.example.com/listusers?name={onzin’ OR password = ‘wachtwoord’–}

-Testen of een site vatbaar is voor SQL Injection

De simpelste manier om te testen of een site kwetsbaar is voor sql
injection is door een enkel quotje in de querystring toe te voegen in
een variabele. Als er hierdoor een database error optreed is de site
kwetsbaar. Als die niet optreedt kan het nog steeds zijn dat de site
kwetsbaar is, maar dan staat waarschijnlijk magic_quotes of iets
dergelijks aan. In dat geval kan je wel SQL injection doen, maar kan je
daarbij geen enkele quotes gebruiken.

-Afsluiting

Dit zijn grofweg wel de basistechnieken, er valt echter een heleboel
meer te doen, maar een heleboel is afhankelijk van je eigen creativiteit
en de meest handige dingetjes zijn vaak server afhankelijk (vanuit
MS-SQLServer kan je bijvoorbeeld (afhankelijk van hoe die is
geconfigureerd) emails versturen. Ik hoop dat dit voldoende is om je op
weg te helpen, de rest zou moeten lukken met genoeg creativiteit in
combinatie met scriptingskills (om dingetjes te automatiseren). Ook
interessante database specifieke eigenschappen zijn tabellen waarin de
metainformatie staat (tabelnamen, kolomnamen, etc.).

-Bronnen

http://www.hackinthebox.org/print.php?sid=6899


Continue reading »

written by Remko

Jun 02
    Change language to:

 

——————————-
Leren Programmeren met Python
——————————-

Datum: 29/08/2003
Versie: 1.0
Auteur: Vincent “gorny” Berg

Onderdeel van de Mostly-Harmless Knowledge Base

Dit document mag vrijelijk verspreid worden op voorwaarde dat de informatie
hierin niet wordt gewijzigd.

- Voorwoord
- Introductie
- Opzet van een programmeertaal
- Beginselen van het programmeren
- “Flow control”
- Functies in Python
- Je vriendjes
- Afsluiting
- Literatuur

- Voorwoord

Dit document handelt over de beginselen van het programmeren en is vooral geschikt voor mensen die totaal geen programmeerervaring hebben. Eenieder die echter al veel ervaring heeft zal met dit document toch snel de basis dingen van Python onder de knie hebben om vervolgens snel grote scripts en/of applicaties te gaan ontwikkelen in deze prachtige taal.
Python is een “agile” programmeertaal. Dit betekent volgens het woordenboek dat het snel, lichtgewicht is en er betrekkelijk makkelijk veranderingen in aan te brengen zijn. Door de betrekkelijk eenvoudige syntaxis wordt een beginnende programmeur niet afgeleidt met “onnodige” zaken en kan deze snel functionele dingen leren. [1]
Ik hoop dat de lezer veel plezier heeft aan dit document. Voor vragen, opmerkingen en/of aanvullingen kan er altijd contact met mij worden gezocht via het Mostly-Harmless forum of het IRC-kanaal.

- Introductie

Veel introducties tot het programmeren beginnen simpelweg met een zogeheten “Hello World” programma. Het enige wat dit doet is het laten zien van de tekst “Hello World” op het scherm. Echter mijn tekst is (nog) niet meteen gericht op het programmeren, maar heeft tot doel de lezer de edele kunst van het programmeren beter te laten begrijpen.
De meeste (conventionele) programeertalen zijn opgebouwd volgens een vaste structuur. Ze bestaan allemaal uit syntaxtische en grammaticale regels waaraan voldaan moet worden door de programmeur. Dit is lang niet zo moeilijk als het klinkt. Bij de syntaxis gaat het (simpel gezegd) om de opbouw van de “woorden” waaruit de programmeercode bestaat. Vergelijk het met de Nederlandse taal. Daarbij moet het woord “appel” ook geschreven worden als “appel” en niet als “appul”.
De grammatica van een programmeertaal zijn een verzameling van regels die beschrijven hoe de “zinnen” in een programmeertaal worden opgebouwd. Ook hierbij is weer mooi de parallel te trekken met de Nederlandse taal. “Hee meneer, doe mij maar een zak met appels!” is grammaticaal correct, terwijl een “He meneer, doe ik een zak maar met appels!” grammaticaal incorrect is. Voor de groenteboer is het dan ook moeilijk te begrijpen wat de klant wil indien hij/zij geen zinnen maakt die niet voldoen aan de grammaticale en syntaxis-regels van de Nederlandse taal.
De metafoor voor het programmeren (de communicatie met de groenteboer) moet nu wel duidelijk zijn. Het verschil bij het programmeren is dat men meestal communiceert met een “compiler” of een “interpreter”. Deze controleren de code van de programmeur op fouten in de syntaxtische en grammaticale regels. Een “compiler” (lees: vertaler) zal de programmeercode daarna omzetten naar een “executable” zodat de gebruiker dat bestand kan uitvoeren, terwijl een “interpreter” de code interpreteert en meteen uitvoerd.
Om weer even terug te komen op Python; het is een geinterpreteerde taal. Er zijn wel manieren om executables van je code te maken, maar die werken erg slecht en maken je programma enorm traag en veel groter dan nodig is. Dus om in Python te kunnen programmeren heb je eigenlijk alleen maar de “interpreter” nodig en die is beschikbaar voor (bijna) elk platform. [2]

- Opzet van een programmeertaal

Programmeren bestaat uit het in een editor (VIM, emacs, UltraEdit, joe) typen van programmeercode. Deze code bestaat uit allerlei bewerkingen, veelal op variabelen. Variabelen zijn niets meer dan een stukje geheugen waarin een bepaalde waarde kan worden geplaatst. Net als de groenteboer die plastic zakjes gebruikt om het fruit en de groente in te doen zal de programmeur dus variabelen gebruiken om zijn dingen in te stoppen.
Er zijn echter verschillende soorten variabelen. Zo zijn er “chars” die ruimte hebben om precies 1 karakter (ASCII) in op te slaan. Dan zijn er “ints” (integers of reals) waarin een geheel (!!) getal tussne 0 en 2^32 kan worden geplaatst. Bij “floats” kan de programmeur een getal met decimalen achter de komma op slaan en dan zijn er natuurlijk ook nog de “strings” die gewoon een opeenvolging van karakters bevat. Een “string” die je zou kunnen opslaan zou deze zin bijvoorbeeld kunnen zijn. Vaak kan een programmeur eigen datatypes gebruiken ( vooral bij het object-georienteerde programmeren) is dat handig. Dit is voorlopig nog niet aan de orde aangezien dit document echt over de beginselen van het programmeren handelt.
De opzet van vele programmeertalen is om code te kunnen hergebruiken. Een programmeur wil niet bijvoorbeeld tien keer een x aantal regels typen om een bepaalde actie te kunnen verrichten. Vergelijk dit met de groenteboer. Deze heeft ook niet 10 kassa’s voor 10 verschillende klanten met daarachter 10 kassameisjes. De groenteboer zorgt heeft gewoon 1 kassa met 1 kassameisje en die wordt gebruikt door alle klanten. Dit kun je weer zien als een metafoor met het programmeren. Een stuk code (de kassa) wordt door verschillende andere stukken code (de klanten / het kassameisje) gebruikt.
In de programmeertaal noemt men zo’n stuk code ook wel een functie. Vaak worden er “variabelen” meegegeven aan een functie (zoals je het zakje met fruit aan het kassameisje geeft zodat die het weegt). Nadat dat gebeurd is zal de interpreter verder gaan waar ze gebleven was.

- Beginselen van het programmeren

Als het goed is hebben we nu een beetje een idee hoe een programeertaal is opgebouwd. Om ervoor te zorgen dat onze code wordt uitgevoerd moet deze syntaxtisch en grammaticaal correct zijn. Om er bovendien voor te zorgen dat we data kunnen opslaan hebben we dus variabelen en functies nodig. We zullen nu (eindelijk) eens wat dingen gaan proberen in Python. Hierbij wordt ervan uitgegaan dat de lezer Python heeft geinstalleerd [2] en de interpreter heeft opgestart. Dit wijst zich erg vanzelf. Onder Windows wordt alles automatisch geinstalleerd en kun je Python gewoon opstarten door in het Startmenu te kijken. Voor elke *nix is het echter anders en dat zal ik niet gaan behandelen. De informatie op de website is redelijk duidelijk en bovendien heeft bijna elke distributie Python standaard geinstalleerd of het is heel makkelijk om dat met het desbetreffende package-managementsysteem te installeren.
Als men de interpreter opstart krijgt men als het goed is een “prompt” voor de neus. Hierin kan je allerlei commando’s typen. Zodra je echt grotere programma’s gaat schrijven is het makkelijker om de meegeleverde Python editor (IDLE) te gebruiken waarin je alles op kan slaan als een file zodat je niet alles elke keer overnieuw hoeft te typen.

gorny@sethanon:~$ python
Python 2.1.3 (#1, Sep 7 2002, 15:29:56)
[GCC 2.95.4 20011002 (Debian prerelease)] on linux2
Type “copyright”, “credits” or “license” for more information.
>>> x = 2
>>> print x
2
>>>

Zoals men ziet heb ik hier een variabele gemaakt genaamd “x”. Deze variabele geef ik de waarde 2. Let op! Het werkt dus anders dan bij de wiskunde waarbij een a = b betekent dat a gelijk is aan b. In het programmeren wordt er bedoeld dat in de variabele x (het plastic zakje dus) de waarde 2 (appels?) wordt gestopt. Met het commando print x wordt dan de waarde getoond. Hieronder zullen nog wat voorbeelden gegeven worden van de andere soorten variabelen.

>>> x = 1.345
>>> print x
1.345
>>> x = ‘A’
>>> print x
A
>>> x = ‘appels zijn het lekkerst van de groenteboer’
>>> print x
appels zijn het lekkerst van de groenteboer
>>>

Zoals we zien heb ik eerst een “float” gecreeerd en daarna een “char”. De code eindigt met maken van een “string”. Het mooie van Python is dat het “dynamisch getypeerd” is. Zoals we zien hebben we niet elke keer mee moeten geven aan de variabele x WAT we erin gaan stoppen (een groenteboer vertelt ook niet aan het zakje dat hij er appels in gaat stoppen). Bovendien kan je later gewoon iets totaal anders in de variabele stoppen (zo werkt elke zichzelfrespecterende plastic zak immers ook). Let op! Bij de strings in Python (en de chars) is het ook mogelijk om ze te omgeven met een ” in plaats van een ‘. Dit heeft echter verder totaal geen effect. De variabelenaam x noemen we een “identifier”. De interpreter identificeert hiermee de variabele. Alles moet een naam hebben omdat we het anders niet zo makkelijk kunnen gebruiken.

>>> x = t
Traceback (most recent call last):
File “<stdin>”, line 1, in ?
NameError: name ‘t’ is not defined

Wat gebeurd er nu? We hebben geprobeerd aan x de variabele t toe te wijzen. Maar aangezien we de variabele t nog niet gedefinieerd hebben kan de interpreter hier niets mee.

>>> t = 3
>>> x = 2
>>> print t, x
3 2
>>> x = t
>>> print t, x
3 3

Ook dit stukje code is erg simpel. We hebben twee plastic zakjes genaamd x en t. In x zitten 2 appels en in t zitten 3 appels. Nu zorgen we ervoor dat er evenveel appels in x als in t komen te zitten.

>>> x = 3
>>> t = 5
>>> x + t
8
>>> print x
3
>>> x = x + t
>>> print x
8

Ook dit is erg duidelijk. We hebben twee variabelen genaamt x en t en die tellen we bij elkaar op. Bij de eerste keer optellen komt er 8 uit maar de variabelen x en/of t worden niet veranderd. Bij de tweede keer tellen we echter x en t bij elkaar op en dat resultaat wordt in x gestopt. De interpreter werkt dus van rechts naar links. Bij de wiskunde zou dit heel anders werken. Dan zou er uit volgen; x = x + t –> x-x = t –> 0 = t –> t = 0.

- “Flow control”

We gaan ons nu met iets anders bezig houden. Zoals we weten begint de interpreter bovenin het bestand en voert daarna alles rechttoe rechtaan uit. Maar met de technieken die vallen onder de “Flow control” oftewel de controle over hoe het programma uitvoert (flowed) kunnen we dit wat aanpassen. Hiervoor gebruiken we bijvoorbeeld de if/else/while/for “statements”. Een statement is in feite niets meer dan een bewering die door de interpreter wordt uitgevoerd.
Bij het programmeren worden echter ook expressies gebruikt. Deze kunnen maar twee waardes hebben genaamd True of False (sommige programmeertalen hebben ook booleans waaronder Python die zo’n type representeren). Voor True of False (lees: Waar / Niet-Waar) worden ook vaak de waarden 1 en 0 gebruikt. Dit kunnen we illustreren met het volgende voorbeeld.

>>> print x
3
>>> x == 3
1
>>> x == 2
0

Let op! Er wordt nu een dubbele = gebruikt. Met 1 “isgelijkteken” zouden we immers de variabele x een nieuwe waarde toe gaan wijzen en dat was niet de bedoeling. Zoals we zien valideert de eerste expressie. x heeft namelijk de waarde drie en dus is die expressie gelijk aan 1 (waar). De tweede expressie valideert niet want x is NIET gelijk aan 2 maar aan 3 en dus is die expressie gelijk aan 0 (niet-waar). Het is dus zaak altijd erg goed op te letten waarna je met een expressie bezig bent of met een statement aangezien het rare fouten op kan leveren als je het verkeerde aantal isgelijktekens gebruikt.

>>> x = 4
>>> if x == 4:
… print ‘er zitten 4 appels in de zak’
… else:
… print ‘er zitten meer of minder dan 4 appels in de zak’

er zitten 4 appels in de zak

Bij het voorgaande stukje code wordt het inspringen bij de “print” statements gedaan door de TAB toets. Let hierbij op. Python kent niet, zoals andere talen, haakjes of accolades om “blokken” af te sluiten. Door naar het aantal TABS te kijken weet de interpreter (of de programmeur) welk stukje code waarbij hoort. Dus alles dat naar het eerste “if” statement komt en begint met een TAB behoort nog onder dat if-statement en zal dus uitgevoerd worden als de expressie “x == 4″ wordt gevalideert (dus waar is). We kunnen echter ook andere tekens gebruiken zals <, > en !=. De eerste staat voor kleiner dan, de tweede voor groter dan en de derde voor “isongelijkaan”.

>>> x = 6
>>> if x > 4:
… print “x is meer dan 4″
… elif x < 2:
… print “x is minder dan 2″
… elif x != 3:
… print “x is ongelijk aan 3″

x is meer dan 4

Let op! Het “elif” statement staat alleen maar voor de afkorting van “else if”. Hierdoor kan je dus meerdere condities valideren met een serie van if statements. Maar waarom wordt er niet geprint dat x ongelijk is aan 3? Dat komt omdat de if en de 2 elifs bij elkaar horen. Zodra er 1 expressie als WAAR wordt geevalueerd dan zal de interpreter de rest van het blok overslaan en verder gaan waar hij gebleven was.

>>> x = 6
>>> if x > 4:
… print “x is meer dan 4″
… elif x < 2:
… print “x is minder dan 2″
… if x != 3:
… print “x is ongelijk aan 3″

x is meer dan 4
x is ongelijk aan 3

Zoals we zien wordt er nu een nieuw if-blok gemaakt waardoor de interpreter het nu wel mee zal nemen en dus wordt het bericht dat x ongelijk aan drie is ook getoond. Er kan bij een if-blok altijd maar 1 ifstatement gebruikt worden, waarna er een (in theorie) oneindig aantal elif statements kan volgen met als afsluitend een else statement. Dit hoeft echter niet. Een if-statement kan ook gewoon op zichzelf staan.

>>> i = 5
>>> while i > 0:
… print i
… i = i - 1

5
4
3
2
1

Dit is een voorbeeld van het gebruik van een while-lus. Deze voert eigenlijk net zolang alles in het while-blok uit zolang de expressie i > 0 geldt. Hierbij moet je dus erg oppassen. Zou je de “i = i - 1″ vergeten dan zou de interpreter eeuwig in het blok blijven zitten en continu 5 op het scherm printen en nooit meer verder gaan met de rest van het programma. Het is dus belangrijk om er voor te zorgen dat je altijd uit de lus kan “springen”.

>>> for i in range(0, 5):
… print i

0
1
2
3
4

Een ander voorbeeld is de for-lus. Hierbij hoeft de i niet eerst gedeclareerd te worden. Dit doet de range() functie voor je. Het enige wat er hier gebeurd is dat de range begint bij 0 en daarna 5 stappen doet. Hierdoor wordt het getal 5 ook niet op het scherm geprint. 0-4 zijn immers vijf getallen.

>>> for i in range(0, 4, 2):
… print i

0
2

Met de for-lus en de range functie kun je ook de grootte van de stapjes aangeven die gedaan moeten worden. Het werkt eigenlijk erg intuitief en makkelijk. De for-lus werkt op deze manier wel anders dan in andere programmeertalen maar dat heeft met het objectgeorienteerde karakter van Python te maken. Voor de beginner is dit voldoende om te weten en hij/zij kan dan ook genoeg met deze lussen uitvoeren.

- Functies in Python

We gaan het nu eindelijk hebben over functies. De eerste zijn we al tegengekomen (de range() functie) die twee of drie variabelen aankan. Het is nu handiger om een editor te gebruiken (notepad is al voldoende) omdat we nu wat meer code gaan produceren. Het bestand waarin je alles getypt hebt sla je op en voer je daarna uit door iets ala: “gorny@sethanon:~$ python file.py” te typen. Voor Windows gebruikers is het een kwestie van het bestand opslaan met de extentie .py en daarna erop te dubbelklikken. De mensen die IDLE (van harte aanbevolen, draait onder bijna elk platform) gebruiken kunnen gewoon de code bewerken, op slaan en dan op Control-F5 drukken om hun code uit te voeren.
Functies hebben in Python, net zoals variabelen een bepaalde “identifier” oftewel een naam. Deze naam moet (net zoals bij variabelen) uniek zijn. Bovendien zit er een verschil tussen hoofd- en kleine letters. Een functienaam mag ook niet hetzelfde zijn als een variabelenaam. Doet de programmeur dit toch dan zal op dat moment de naam naar de functie verwijsen en niet meer naar de variabele. In het omgekeerde geval geldt precies hetzelfde. Een functie in Python definieer je met het “keyword” def. Deze sleutelwoorden (net zoals if/else) mogen natuurlijk niet als functienaam of variabelenaam gebruikt worden anders zou de interpreter het enorm moeilijk krijgen om de code nog uit te voeren.

>>> def telop(a, erbijop):
… return a + erbijop

>>> print telop(2, 3)
5

Wat doet dit stukje code? Het roept de functie telop aan. Zoals te zien is accepteert de telop() functie twee verschillende variabelen genaamd a en erbijop. De functie telt “a en erbijop” op en retouneert dat getal. Het print statement doet niets meer dan het print van het “antwoord”. De waardes die aan telop() worden meegegeven worden in de variabelen a en erbijop geplaatst. Een functie in Python hoeft echter niet expliciet te returnen. Als dat niet gebeurd (of er staat een return statement met verder geen waarde erachter) dan retouneert de functie simpelweg None.

>>> def test(start=1, end=5):
… for i in range(start, end):
… print i

>>> test()
1
2
3
4
>>> test(2, 3)
2
>>> print test(0, 0)
None

In dit voorbeeld gebruiken we een functie test die de waarden in de range van “start” tot “end” afdrukt. Het mooie van Python is dat we standaard (”default”) waarden mee kunnen geven. Zodra we dus geen variabelen meegeven aan de functie test() dan zal deze gewoon de standaard waarden voor start en end nemen en daarmee rekenen. De allerlaatste regel laat zien wat test() retouneert, namelijk None.

- Je vriendjes

Elke programmeur heeft vriendjes. Veel vriendjes. Daaronder valt onder andere je editor, maar natuurlijk ook je compiler (of interpreter), je favoriete browser en je lievelings besturingssysteem. Maar de (beginnende) programmeur heeft nog een vriendje. Deze vriend heet “array”. De array is een enorm handig verschijnsel dat je zal helpen bij vele problemen die je anders moeilijk op kan lossen.
Neem bijvoorbeeld een programma dat veertig verschillende getallen bij elkaar moet optellen. Het zou een beetje een heel erg gedoe zijn om nu allemaal variabelen met namen als a0, a1 tot en met a39 te gaan declareren. In de praktijk is dit niet te doen en je programma moet meteen weer volledig aangepast worden wil je 50, 60 of zelfs 1000 getallen bij elkaar optellen. Niet te doen dus. Daarvoor bestaat de array. Een array is niets meer dan een verzameling datatypen die een gezamenlijke “identifier” hebben.
Bij de meeste programmeertalen is een array gebonden aan een bepaald type (dus een array van het type float of van het type char), maar aangezien Python dynamisch getypeerd is hoef je daar geen rekening mee te houden. Een array kan dus tegelijkertijd integers en strings bevatten.
Om toch onderscheid te kunnen maken tussen de verschillende elementen van een array wordt er een “index” gebruikt. Dit is niets meer dan een geheel, positief getal (beginnend bij 0) waarmee een bepaald element in de array wordt aangeduidt.

>>> t = []
>>> print t
[]
>>> t = [4, 1, 9]
>>> print t
[4, 1, 9]
>>> print t[0], t[1], t[2]
4 1 9

Allereerst declareren we een lege array t. Zoals te zien is wordt een Array in Python met blokhaken aangegeven. Daarna maken we een een array aan met 3 elementen (4, 1 en 9). Zoals te zien is wordt de eerste keer de volledige array geprint terwijl bij het tweede print-statement alle elementen (met een index van 0 tot 2) afzonderlijk worden geprint.
Het mooie van Python is dat de grootte van arrays ook dynamisch is. Bij andere talen declareert de programmeur vaak een array van een bepaalde grootte waardoor er niet meer dan een bepaald aantal elementen in de array gestopt kan worden. Bij Python gaat dit allemaal veel makkelijker.

>>> t.append(6)
>>> print t
[4, 1, 9, 6]
>>> t[2] = 11
>>> print t
[4, 1, 11, 6]

Met de notatie .append() wordt er een element toegevoegd aan de array. Deze notatie volgt uit het Object-geOrienteerde Programmeren en dat zal in dit document niet behandelt worden. Het is voor jullie genoeg om te weten dat er simpelweg iets meegegeven kan worden aan de .append() call om iets toe te voegen aan de array.
De waardes van de dingen in de array kunnen simpelweg worden verandert op dezelfde manier zoals de waarde van een normale variabele wordt verandert. Let wel altijd op het index teken. Dit is voor beginners vaak een bron van verwarring. Elke, zichzelfrespecterende programmeertaal begint bij alles met tellen bij 0 en zo Python dus ook. Bij t[2] wordt dan ook het derde element in de array bedoeld, zoals ook te zien is aangezien de 9 dan in een 11 is veranderd.

>>> t.pop()
6
>>> print t
[4, 1, 11]
>>> t.pop(1)
1
>>> print t
[4, 11]

Met .pop() kunnen er elementen uit de array verwijdert worden. Standaard verwijdert pop() het laatste element en retouneert dat ook (waarom het ook op de standaard uitvoer wordt geprint). Er kan echter ook een index meegegeven worden zodat het element met die specifieke index uit de array wordt verwijderd. [3]

- Afsluiting

Ik hoop dat je nu wat meer duidelijk is over de edele kunst van het programmeren. Let wel, dit was echter een introductie tot de schamele basis van het programmeren. Bovendien is er nog niets verteld over het Object Georienteerde Programmeren. Dit is haast onmisbaar om volledig met de (uitgebreide) Python Bibliotheken te kunnen werken, maar ik vond het niet geschikt om meteen daarover al te beginnen. Een vervolg document zou misschien dus wel een goed idee zijn :).
Voor verdere vragen kan je altijd contact met mij opnemen via email of IRC, of ze stellen op het Mostly-Harmless forum [4]. Suggesties en andere op- of aanmerkingen zijn ook van harte welkom.

Vincent “gorny” Berg

- Literatuur

[1] Why Python? — Eric S. Raymond
http://www.linuxjournal.com/article.php?sid=3882

[2] Officiele Python Website
http://www.python.org

[3] Arrays in Python
http://users.ox.ac.uk/~sann1276/python/handbook/node39.html

[4] Mostly-Harmless Forums
http://www.mostly-harmless.nl/forums/

* EOF *


Continue reading »

written by Remko

Jun 02
    Change language to:

 

Titel: IPtables, een firewall voor linux
Schrijver: Arn Vollebregt
Versie: 1.0
Op de planning: Toevoeging over logfiles.

Index
0.1 Voorwoord
0.2 Benodigheden
0.3 Packet forwarding
1.0 Hoe zit IPtables in elkaar
1.1 De bediening van IPtables
1.2 Rekening houden met IPtables ’slechte’ geheugen
1.3 Een simpele firewall
1.4 Een statefull firewall
1.5 Een DMZ
1.6 De firewall policy
1.7 Tips voor het gebruik van IPtables
1.8 Nawoord

0.1 Voorwoord
Waarom heb je een firewall nodig?
Het risico van een aanval op een van je computers is met de afgelopen jaren flink toegenomen.
Met de dag worden er beveiligings gaten gevonden in Operating Systems, danwel de software die daarop draait.
En met de dag worden er ook kant en klare tools en exploits op het internet gezet die het leven van een potentiele aanvaller
een stuk makkelijker maken. Als je altijd met je computers bezig bent zijn ze natuurlijk volledig up-to-date, en wordt de
kans een stuk kleiner dat je systeem gehacked zal worden. Doch ben je ook dan nog niet volledig veilig voor 0days[1].
Een firewall helpt je het risico van een hack op een van jou computers te verkleinen. Dit door ten eerste het aantal
toegangswegen naar jou computers drastisch te verkleinen, en ten tweede door computers die vanaf het internet bereikbaar
moeten zijn in een apart netwerk te stoppen, welke los staat van je normale netwerk.

[1] Beveiligingsgaten die nog maar net ontdekt zijn en waarvoor nog geen patch bestaat.

0.2 Benodigheden
Deze text gaat ervan uit dat je beschikt over het volgende:
1) Een linux Operating System waar je volledige controlle (root) over hebt.
2) IPtables dient geinstalleerd te zijn.
3) 2 NIC’s[1] (als je geen publieke services gaat draaien).
4) 3 NIC’s (als je een publieke service gaat draaien, bijvoorbeeld een webserver).
5) Basis kennis van linux (weten hoe je bestanden moet bewerken, en hoe je moet navigeren).
6) Basis kennis van netwerken (protocolen en porten).

[1] NIC staat voor Network Interface Card, oftewel een netwerk kaart.

0.3 Packet forwarding
Voordat we de firewall regels gaan bouwen, zullen we eerst moeten zorgen dat de firewall data pakketen door kan geven naar
computers achter de firewalls.
Dit process zal per Operating System verschillend zijn, aangezien ik zelf alleen Redhat draai bij deze een uitleg voor
Redhat;
Open ‘/etc/sysctl.conf’ in een editor, en verander ‘net.ipv4.ip_forward = 0′ in
‘net.ipv4.ip_forward = 1′.

1.0 Hoe zit IPtables in elkaar
Hoe IPtables precies in elkaar zit doet er op dit moment niet zoveel toe, maar het is handig om het volgende te weten;
IPtables is opgebouwd uit verschillende tabellen (tables), waar iedere tabel ook weer is onder verdeeld in zogenaamde
ketenen (chains):

tables
+————+————+
| filter | nat |
+————+————+
| INPUT | PREROUTING |
chains +————+————+
| FORWARD |POSTROUTING |
+————+————+
| OUTPUT | OUTPUT |
+————+————+

Er is nog een derde table genaamd ‘mangle’ maar daar gaan we ons niet mee bezig houden in deze text.

Verkeer welke door de firewall heen gaat, zal op de volgende manier door deze tabellen heenlopen:

———-
/ \
| internet |
\ /
———-
|
V
|
+————+————+
| table | chain |
+–<—<—+————+————+—>—>–+
| | nat | PREROUTING | |
V +————+————+ V
| |
data voor de server zelf data voor computers achter de server
| |
+————+————+ +————+————+
| table | chain | | table | chain |
+————+————+ +————+————+
| filter | INPUT | | filter | FORWARD |
+————+————+ +————+————+
| |
V V
| |
+————+————+ +————+————+
| table | chain | | table | chain |
+————+————+ +————+————+
| nat | OUTPUT | | filter | OUTPUT |
+————+————+ +————+————+
| |
V V
| |
+————+————+ |
| table | chain | V
+————+————+ |
| filter | OUTPUT | |
+————+————+ V
| |
| |
V V
| +————+————+ |
| | table | chain | |
+–>—>—+————+————+—<—<–+
| nat |POSTROUTING |
+————+————+
|
V
|
———-
/ \
| netwerk |
\ /
———-

Dit ziet er waarschijnlijk complex uit op dit moment, maar dit is een handig plaatje om naar terug te kunnen grijpen,
aangezien het belangrijk is om te weten welke weg data zal bewandelen als je hier een firewall regel voor wilt aanmaken.

1.1 De bediening van IPtables
Alhoewel je natuurlijk alles uit de man[1] pagina’s kunt halen, zal ik hier toch een paar basis dingen uitleggen. Alle
commando’s staan tussen quotes, maar dienen natuurlijk zonder quotes via de commandline ingevoerd te worden.

Onderstaan commando laat de huidige regelset uit de tabel ‘nat’ zien;

‘iptables -t nat -L -n -v’

‘iptables’ = het commando om iptables aan te roepen.
‘-t’ = ‘table’
‘nat’ = de table die je wilt zien. Opties; ‘filter’, ‘nat’ en ‘mangle’.
‘-L’ = ‘list’, een lijst van de regels die in deze table zitten.
‘-n’ = ‘numeric’, netjes alles in nummertjes (IP’s, ranges, etc).
‘-v’ = ‘verbose’, een uitgebreidere weergave.

Onderstaan commando voegt een firewall regel toe voor SSH[2];

‘iptables -A INPUT -p tcp –dport 22 –sport 0/0 -j ACCEPT’

‘iptables’ = het commando om iptables aan te roepen.
‘-A’ = ‘append’, een regel toevoegen.
‘INPUT’ = de ‘chain’ waar de regel in komt.
‘-p’ = ‘protocol’, het gebruikte protocol.
‘tcp’ = het protocol waar deze regel voor geldt.
‘–dport’ = ‘destination port’, de poort op de machine.
‘22′ = de poort waar deze regel voor geldt.
‘–sport’ = ’source port’, de poort op de client.
‘0/0′ = Iedere client poort wordt geaccepteerd.
‘-j’ = ‘jump’ wat er moet gebeuren met de data.
‘ACCEPT’ = de data wordt geaccepteerd.

Aangezien in bovenstaand voorbeeld geen ‘-t’ switch is meegegeven wordt deze regel aan de
standaard tabel toegevoegd, ‘filter’.

[1] ‘man’ staat voor manual, de handleiding.
[2] ‘SSH’ staat voor Secure Shell Header, een versie van telnet die gebruikt maakt van encryptie.

1.2 Rekening houden met IPtables ’slechte’ geheugen
Alhoewel nieuwe regels die worden ingevoerd via de commandline meteen van kracht zijn, zal IPtables deze regels weer
‘vergeten’ zijn zodra de computer danwel de service weer opnieuw opgestart wordt.
Aan de ene kant is dit handig (zeker in deze beginne), aangezien je een cruciale fout makkelijk kan verhelpen door de
computer of de service weer opnieuw op te starten. Aan de andere kant is dit natuurlijk vermoeiend zodra je een goede
regelset (ruleset) hebt geproduceerd; Je wilt niet iedere keer weer opnieuw alle regels aan de firewall toevoegen.
Ten eerste heeft IPtables een tweetal handige tools die je hierbij gaan helpen;
‘iptables-save’ en ‘iptables-restore’.
‘iptables-save’ slaat alle huidige regels van IPtables voor je op, en schrijft zo ook naar je scherm toe. Als je
‘iptables-save > regels.txt’ via de commandline uitvoert worden bovendien al je firewall regels opgeslagen in een textfile,
zodat je verschillende versies kunt opslaan. Wil je vervolgens een van deze regelsets gebruiken dan voer je simpelweg
‘iptables-restore < regels.txt’ uit. Vervolgens voer je ’service iptables restart’ uit, en de firewall wordt geladen met je
eigen regelset.

1.3 Een simpele firewall
Onderstaand vind je een setup voor een simpele firewall. Text waar een # voor staat is uitleg en dient niet ingevoerd te
worden.

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# ‘lo’ staat voor ‘loopback’ (IP 127.0.0.1). Bovenstaande regels zijn nodig als je een X windows systeem wilt
# draaien.
iptables -A OUTPUT -o eth0 -s 0/0 -d 0/0 -m state –state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -s 0/0 -d 0/0 -m state –state RELATED,ESTABLISHED -j ACCEPT
# Bovenstaande regels staan dataverkeer van binnen naar buiten toe (eth0 is over het algemeen
# de externe adapter die naar het internet gaat). Nieuw is de regel
# ‘-m state –state, hierover zometeen meer uitleg.
iptables -A OUTPUT -o eth1 -s 0/0 -d 0/0 -j ACCEPT
iptables -A INPUT -i eth1 -s 0/0 -d 0/0 -j ACCEPT
# Deze regels maken dataverkeer van en naar het lokale netwerk mogenlijk op interface eth1.
# Je ziet hier 0/0 verschijnen omdat het niet veel uitmaakt waar de data heengaat danwel
# vandaan komt zolang je geen publieke services draait (zie hiervoor ‘1.6 Een DMZ’).
# ‘-i’ specificeerd de ‘input’, de adapter waarop het verkeer binnen komt.
# ‘-o’ specificeerd de ‘ouput’, de adapter van waaruit het verkeer verstuurd wordt.
# Aangezien er geen protocol is gespecificeerd worden alle protocolen toegelaten.
iptables -A FORWARD -i eth0 -o eth1 -s 0/0 -d 0/0 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -s 0/0 -d 0/0 -j ACCEPT
# Deze regels maken dataverkeer mogenlijk tussen eth1 (het lokale netwerk) en eth0 (het internet)

1.4 Een statefull firewall
‘-m state –state NEW,RELATED,ESTABLISHED’ roept met ‘-m’ een module aan, in dit geval de ’state’ module.
Zoals je ziet zijn er 3 opties (parameters) mogelijk bij deze module, zijnde ‘NEW’, ‘RELATED’ en ‘ESTABLISHED’.
Wat deze module doet is connecties van en naar de firewall bijhouden. Zoals je ziet in bovenstaande firewall regels zijn er
geen enkele regels voor verkeer naar de firewall toe, alleen maar regels voor dataverkeer welke vanaf de firewall ergens
anders heen gaan. De state module zal een relatie leggen tussen uitgaand en inkomend verkeer.

Een voorbeeld;
PC1 achter de firewall maakt een connectie met PC2 op het internet:
1) PC1 stuurt een data pakket naar poort 80 van PC2, en gebruikt daarvoor de lokaal poort 2724.
2) PC2 stuurt data vanaf poort 80 naar PC1 op poort 2724.
3) PC2 stuurt data naar poort 22 van PC1.
De state module zal ervoor zorgen dat ondanks het feit dat er geen firewall regel is voor verkeer vanaf het internet met als
source port 80, dat de data vanaf PC2 toch naar PC1 zal kunnen worden gestuurd door de firewall. PC1 heeft namelijk eerst
data gestuurd naar poort 80 van PC2, dus de firewall zal dataverkeer vanaf poort 80 van PC2 als gerelated (related) zien.
Het dataverkeer naar poort 22 vanaf PC2 naar PC1 wordt echter niet doorgelaten, aangezien de firewall nog geen data heeft
gezien vanaf poort 22 van PC1 naar PC2. De state module maakt het leven dus een stuk simpeler, aangezien je niet apart
allemaal regels aan hoeft te maken voor streaming audio en video, ICQ, MSN, websurfen, etc. Het enige nadeel is dat je geen
totale controlle hebt over wat computers achter de firewall doen , maar dat is meer iets voor een professioneel/bedrijfs
netwerk, voor een thuis netwerk maakt dit niet zoveel uit. Als je toch bepaalde verkeer niet wilt toelaten kun je dit ook
expliciet tegenhouden (blocken) in je firewall regels.

1.5 Een DMZ
DMZ staat voor De-Militarized Zone.
Een DMZ is een apart lokaal netwerk welke los staat van je normale lokale netwerk. Dit betekend dat er in principe geen
dataverkeer mogenlijk is vanaf je LAN naar je DMZ en andersom. De lol hiervan is, dat zelfs als een publieke service die je
beschikbaar stelt via internet een beveiligingsgat bevat waardoor men de hele computer kan overnemen, men nog steeds niet bij
de rest van de computers kan om deze ook over te nemen. Het opzetten van een DMZ is gedeeltelijk hetzelfde als de
bovenstaande opzet, maar wat verder ingeperkt;

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# X-Windows data verkeer.
iptables -A OUTPUT -o eth0 -s 0/0 -d 0/0 -m state –state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -s 0/0 -d 0/0 -m state –state RELATED,ESTABLISHED -j ACCEPT
# Verkeer van en naar het internet.
iptables -A INPUT -i eth1 -s ! 10.0.0.0/24 -d 192.168.0.0/24 -j ACCEPT
iptables -A OUTPUT -o eth1 -s 192.168.0.0/24 -d ! 10.0.0.0/24 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -s ! 10.0.0.0/24 -d 192.168.0.0/24 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -s 192.168.0.0/24 -d ! 10.0.0.0/24 -j ACCEPT
# Zoals je ziet is er verkeer op je LAN toegestaan, zolang het maar niet van en naar 10.0.0.0/24
# gaat, wat de IP range is van de DMZ in dit voorbeeld.
iptables -A INPUT -i eth2 -p tcp –dport 80 -d 10.0.0.2 -s ! 192.168.0.0/24 -j ACCEPT
iptables -A OUTPUT -o eth2 -p tcp –sport 80 -s 10.0.0.2 -d ! 192.168.0.0/24 -j ACCEPT
# Hier zie je een regel die verkeer naar en van IP 10.0.0.2 poort 80 toelaat op eth2 (de adapter
# waar de DMZ op zit) zolang dit verkeer maar niet van en naar het gewone lokale netwerk gaat.
iptables -A FORWARD -i eth0 -o eth2 -p tcp –dport 80 -d 10.0.0.2 -s ! 192.168.0.0/24 -j ACCEPT
iptables -A FORWARD -i eth2 -o eth0 -p tcp –sport 80 -s 10.0.0.2 -d ! 192.168.0.0/24 -j ACCEPT
# En een forwarding rule voor dataverkeer tussen de netwerk adapters.
# Verkeer van en naar IP 10.0.0.2 poort 80 wordt netjes geforward, zolang het maar niets te
# maken heeft met het normale lokale netwerk.
iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j DNAT –to 10.0.0.2
# deze regel zorgt ervoor dat alle data die op poort 80 via adapter eth0 binnen komt doorgegeven zal
# worden naar IP 10.0.0.2

1.6 De firewall policy
Het is je mischien al opgevallen dat hoewel je firewall regels heb aangemaakt er nog steeds ander verkeer wordt doorgelaten
door de firewall welke niet in deze regels voorkomt. Dit is toe te schrijven aan de policy die de firewall voert.
De policy is de standaard actie die de firewall zal uitvoeren als data verkeer door de firewall heen probeert te komen. Op
veel standaard installaties staat deze policy standaart op ACCEPT. De opties die voor de policy aanwezig zijn zijn ‘ACCEPT’,
‘DENY’ en ‘DROP’.
ACCEPT zal al het verkeerd door laten, inclusief verkeer welke niet vermeld staat in de firewall regels.
DENY zal alleen verkeer doorlaten welke in de firewall regels beschreven staat, doch verkeer welke niet in deze regels staat
zal netjes afgewimpeld worden met een foutmelding.
DROP zal alleen verkeer doorlaten welke in de firewall regels beschreven staat, doch verkeer welke niet in deze regels staat
Zal verdwijnen in een zwart gat, zonder dat de computer waar het verkeer vandaan komt een foutmelding zal krijgen. Iedere
policy heeft een eigen voor- en nadeel, dus je zult moeten bekijken welke policy het beste bij je past.
Als je een policy wilt veranderen voor een chain in een table, dan doe je dit als volgt:
iptables -t nat -P POSTROUTING DROP

1.7 Tips voor het gebruik van IPtables
Bij het configureren van IPtables kan men wel eens struikel blokken tegen komen, bij deze een paar tips zodat je daar alvast
voor kunt uitkijken:
1) Sla altijd de huidige firewall regels op voordat je deze gaat veranderen, zodat je altijd nog terug kunt gaan als je een
fout hebt gemaakt. Doe dit door op de commandline in te typen:
iptables-save > file
Het maakt niet uit naar wat voor een file je de regels schrijft, ikzelf gebruik namen als test.txt en current.txt.
Als je deze opgeslagen regels weer wilt gebruiken type je:
iptables-restore < file
2) Doe zoveel mogenlijk op de firewall zelf, het is aardig frustrerend (en soms zelfs lastig als je de firewall hebt opgezet
zonder monitor en keyboard) als je via SSH bent ingelogd en per ongeluk een regel weggooid waardoor je SSH sessie ook
wegvalt.
3) Test altijd je firewall regels, gebruik hiervoor een sniffer en een gratis shell account waarbij je gebruik kunt maken van
telnet. type op de commandline:
telnet IP Poort
Als er een connectie gemaakt kan woorden naar de poort, dan is er ergens wat fout gegaan. Doe dit niet alleen als je met je
firewall hebt opgezet, maar ook als je grote veranderingen hebt aangebracht in je firewall regels. Het kan namelijk zijn dat
de volgorde van de firewall regels zo is veranderd dat er opeens dataverkeer mogelijk is op een poort die je wilt verbieden.
4) Laat een bekende een nmap en/of nessus scan op je IP doen, zodat je een gedetaileerd beeld krijgt van wat er nu wel en
wat er nu niet open staat naar de buitenwereld. Als je niemand kent die dit voor je kan doen, of je wilt niet wachten, zoek
dan een online service op die gebruik maakt van nmap.
5) Denk niet dat je hele netwerk nu zo veilig is als de computers van de NSA. Alhoewel je nu netwerk verkeer beperkt hebt zul
je de applicaties en services die je draait ook goed moeten configureren, en logs files moeten bijhouden van hun
activiteiten. Als een database server bereikbaar is van internet en geen (of een standaard) wachtwoord heeft, dan helpt een
firewall je niet.
6) Zorg dat je een backup/image maakt van de firewall, en dat je deze weer kunt terug zetten vanaf cd of harde schijf (denk
bijvoorbeeld aan ghost). Mocht er iets vreselijk fout gaan tijdens een update, of heb je ergens een configuratie bestand
veranderd welke je niet meer kunt terug vinden, dan heb je altijd nog een werkende versie van je firewall achter de hand.
7) Draai nooit services op een firewall. Iedere service die op je firewall draait is een potentiel probleem op het moment dat
deze applicatie een beveiligings lek heeft. Als iemand via deze service toegang weet te krijgen op je firewall dan heeft deze
toegang tot je hele netwerk. Draai dus nooit services op een firewall.

1.8 Nawoord
Alhoewel ik deze text heb geschreven aan de hand van een draaiende firewall, kan het toch voorkomen dat ik slordigheids
fouten heb gemaakt. Verder ben ik geen expert op het gebied van IPtables, dus het is goed mogelijk dat ik wellicht bepaalde
concepten niet goed of onvolledig heb uitgelegt. Mocht je aan- danwel opmerkingen hebben op mijn text dan stel ik het op
prijs als je deze naar mij verstuurd per email, zodat ik eventuele fouten kan verbeteren en/of opmerkingen mee kan nemen in
een volgende versie van deze text. Ik ben te bereiken via het volgende e-mail adres: arn@mostly-harmless.nl
Bij voorbaat dank.

Gebruikte bronnen: http://www.siliconvalleyccie.com/linux-hn/iptables-intro.htm


Continue reading »

written by Remko

Jun 02
    Change language to:

 

“Ik verving alleen maar de index.html”
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Het lijkt erop dat de scriptkiddies die websites defacen geen idee hebben
waarom hun gerommel zo’n gewelddadige reactie uitlokt van de bedrijven die ze
aanvallen. Dit korte artikel zal een aantal van de gebeurtenissen achter de
schermen op een rijtje zetten die voorvallen na de “onschuldige” vervanging van
de index.html door onze geliefde politieke activisten.

1. Het bedrijf wordt op de hoogte gebracht, meestal door een klant, dat hun
website is veranderd. De server beheerder, webmaster, of wie dan ook
verantwoordelijk is voor de inhoud is meestal de eerste die van de
gebeurtenis op de hoogte wordt gebracht, omdat het bedrijf waarschijnlijk
geen rampenplan heeft.

2. De beheerder schijt zeven kleuren stront en vertelt het zijn manager. De
beheerder, bang om zijn baan kwijt te raken, is de klos en vertelt zijn
chef dat het bedrijf is “gehacked”. Hij is nu waarschijnlijk bang dat de
aanvaller binnen is gekomen daar zijn zwakke wachtwoord, of door een van
zijn dozen die hij een half jaar terug had moeten upgraden.

3. Zodra hij dit hoort schijt de chef zeven kleuren stront. De afdelingschef
vreest nu voor zijn baan en wetend dat de toorn van het bestuur op zijn
schouders zal vallen voor het niet beveiligen van het systeem. Hij probeert
wanhopig te bedenken aan wie hij dit kan vertellen, zonder dat diegene hem
op slaande voet zal ontslaan. Hij belt zijn chef (meestal een vice president
type) en vertelt haar het nieuws.

4. Wanneer ze dit hoort flipt ze en schijt zeven kleuren stront. De vice
president belt Human Resources, Legal, Security (indien aanwezig) en de
bestuurder van Engineering of een andere ubergeek. De groep besluit
gezamenlijk of de site offline moet worden gehaald of niet. Er wordt een
telefoontje gepleegd naar de directeur om hem op de hoogte te brengen van de
situatie. Na een kort consult met de bedrijfsraad wordt de beslissing
genomen of contact moet worden gezocht met de politie of het OM. Meestal
staan de managers in aanvalshouding en willen ze de cracker “koste wat kost”
aggresssief vervolgen.

5. Gedurende het hele proces is de overwerkte beheerder bezig het systeem te
doorzoeken naar sporen die wijzen op hoe de hacker binnen is gekomen. Hoewel
de hacker zegt dat ie “alleen maar de index.html heeft vervangen” wil de
chef van de chef van de beheerder dat ELK systeem wordt gecheckt en
mogelijke gaten worden gedicht. De beheerder probeert nu een uitvoerige
security audit te doen in een uur.

6. De opperbazen van marketing proberen uit te vogelen hoe ze om moeten gaan
met de impact die dit heeft op het imago van het bedrijf. Nog nooit eerder
met een dergelijke situatie geconfronteerd besluit de directeur van
marketing al haar medewerkers bijeen te roepen voor een brainstormsessie om
te besluiten hoe ze met de situatie om moeten gaan.

7. Het systeem word waarschijnlijk gebackupped, uitgeschakeld, vervangen door
een nieuwe doos of in ieder geval zwaar geupgrade (daarbij nieuwe bugs
introducerend). Dit neemt voor de beheerder het grootste deel van de dag in
beslag. Normaal zou hij dit in een paar uur kunnen doen, maar omdat hij weet
dat de Vice President en de managers hem op de vingers kijken verzekert hij
zich ervan dat alles perfect wordt uitgevoerd.

8. Als het politie en/of OM zijn ingeschakeld dan zijn zij nu bezig met de
beheerders en advocaten te bekijken of ze een zaak hebben (waarschijnlijk
niet, omdat het meeste bewijs per ongeluk is gewist door de beheerder in de
eerste vier uur na het voorval).

9. De managers verordenen dat de systemen beveiligd zullen worden en dat iets
dergelijks nooit meer zal voorvallen. Het is waarschijnlijk dat er een
gevestigde consultant erbij wordt gehaald van E200+/uur om het bedrijf te
schatten en adviezen te geven om de site’s beveiliging te verbeteren. Omdat
de beheerder al bezig is met zijn dagelijkse werk, implementeert het
consultancy bedrijf hun aanbevelingen +voor E200+/uur).

10.Na een paar weken loopt alles weer zijn gangetje. Het bedrijf heeft nieuwe
ACLs, een nieuwe firewall, en misschien een nieuw beleid.

Nu dan, dit alles overziend kan men zien hoeveel personeel hierbijk betrokken
is en hoeveel tijd er in wordt geinvestaard om iets “onschuldigs” als het
defacen van de index.html . Ik heb het nog niet eens over de bijkomende
gevolgen wanneer de beheerder een trojan of ongeauthoriseerde toegang tot
handelsggeheimen van het bedrijf ontdekt. Dit is alleen nog maar het eenvoudige
geval.

“Maar de aanvaller zei in zijn ‘bericht’ dat hij de index.html had
gebackupped. Ze hoefden allen maar het origineel terug te zetten!” Nee, domme
sukkel, nee. De aanvaller heeft het bedrijf publiekelijk vernederd, heeft de
wereld getoond dat de beveiliging van de site niet afdoende is en heeft
persoonlijke verwarring veroorzaakt voor 5 of meer mensen.

Voorts, als ik thuis kom en de voordeur is open met een briefje erop geplakt
maar op staat “Hoi. Ik heb bij je ingebroken. Ik heb allen wat spul
verplaatst. Ik heb niks meegenomen. Groetjes, |)13|=”, en ik moet dat geloven?
Zou jij het geloven? Als het betreffende bedrijf publiek verhandeld wordt, dan
zijn ze legaal _verplicht_ om het uit te zoeken en maatregelen te nemen om
dergelijke voorvallen te voorkomen. Als ze dat niet doen kunnen de
aandeelhouders hen vervolgen voor nalatigheid.

Nu, ik kan onmogelijk de tientallen milljoenen die bedrijven claimen in zaken
zoals Mitnick en anderen rechtvoordigen - dat is waanzin. Maar ik hoop dat na
het bovenstaande te hebben gelezen duidelijk wordt dat er significant veel tijd
en geld wordt besteed aan het opruimen van dergelijke “simpele” aanvallen.

– Anoniem, 14-5-1999
vertaald door Mark IJbema


Continue reading »

written by Remko

Jun 02
    Change language to:
# Introductie in C programmeren
# door po0h
# voor Mostly-Harmless

#####   Woordje Vooraf #####

- geschiedenis van c
- werking van een source code
- werking van een compiler
- gebruik van een compiler

#####   Het Begin   #####

Bij het programmeren in C beginnen we met het declareren van zogenaamde
"header" files.
Header files bevatten koppelingen naar library files waar de instructies
staan voor functies
die later in het programma weer gebruikt worden. Het klinkt misschien erg
ingewikkeld, maar
hier hoef je je nog even niet druk over te maken.

Het declareren van header files kan er zo uitzien: "#include <stdio.h>". de
"#" voor "include" staat voor een preprocessor directive. Dit betekend dat
het als eerste verwerkt wordt in het programma. Hierna komt meestal de
"main" functie van een programma. Deze kan eruit zien als: "int main()". De
"int" voor de main()  betekend dat als de main() verwerkt is, dat het dan
terug keert als een integer variable om te vertellen hoe het programma is
be-eindigd. Daarom moet je ook altijd: "return 0" aan het einde van de
main() zetten. Dit geeft dan aan het besturingsysteem door dat het programma
normaal is uitgevoerd. Soms wordt er ook gebruik gemaakt van: "void main()".
Deze heeft dan geen return adres en zal ook werken, maar is niet gelijk aan
de
ANSI standaard dus zal ik die hier ook niet bespreken.

Dit brengt ons naar het volgende simpele programma:

----- 01. start code prog1.c -----

#include <stdio.h>

int main()
{
	printf("Ik doe geen hallo wereld!");
    	return 0;
}

----- 01. einde code prog1.c -----

"#include <stdio.h>" en "int main()" moeten nu een beetje duidelijk zijn.
Het nieuwe dat je als eerste tegenkomt zal de "{" zijn. De "{" staat voor
begin en "}" staat voor eind. Dit is nodig om in dit geval
aan te geven dat de functie "main()" uit meerdere instructies bestaat. Zo
ziet de compiler dat alle regels tussen de "{" en de "}" bij de functie
"main()" horen. Het volgende nieuwe is de "printf" functie. Functies
zijn bij elkaar gegroepeerde programmacode. De programmertaal C bevat bevat
standaard dus een aantal functies, maar deze zijn ook makkelijk zelf te
schrijven. Hier komen we later op terug. Je moet goed onthouden dat functies
altijd afgesloten moeten worden met een ";". Maar dit zul je in het begin
toch tig keer vergeten :) (dit was bij mij het geval tenminste).

Door de functie "printf()" wordt er "Ik doe geen hallo wereld!" getoond bij
het uitvoeren van het programma.
In "printf()" kun je verschillende escape sequences zetten. Dit zijn een
soort hulpmiddelen bij het weergeven
van een output. Een tabel van de meest gebruikte escape sequences:

        \a              Maakt een interne piep
        \b              Geeft een backspace
        \n              Nieuwe lijn (enter)
        \r              Carriage return (Zet de cursor aan het begin van de
lijn)
        \t              Tab
        \v              Verticale tab (Cursor verplaatst 1 lijn)
        \\              Backslash
        \'              Apostrophe
        \"              Dubbele quotes
        \?              Question mark
        \0              Null byte (is een 0)
        \O              Octale nummers (base 8)
        \xH             Hexadecimale nummers (base 16)

----- 02. start code prog2.c -----

#include <stdio.h>

int main()
{
	printf("Dit is regel1\nDit is regel2\n");
    	return 0;
}

----- 02. einde code prog2.c -----

Geeft als output:

[po0h@mabel c]$ ./prog1
Dit is regel1
Dit is regel2
[po0h@mabel c]$

#####   Variablen   #####

Een variable is een bepaald gebied in het geheugen van de computer waarin je
tijdelijk een waarde kunt opslaan. Ik denk dat dit goed uit te leggen is met
het volgende rekensommetje:

a=2
b=3

a+b=c

hoeveel is c?

Dit zullen jullie allemaal wel herkennen. Je onthoudt dat a de waarde 2
bevat, daarna onthoud je dat b de waarde 3 bevat. Als je dit doet staat er
eigenlijk 2+3 waarbij de uitkomst (c) dus 5 is. Zo werken variablen
eigenlijk ook. Bij programmeertalen kun je niet alleen een nummer in een
variable zetten, maar ook bijvoorbeeld een letter of een zin. Er bestaan dus
verschillende variablen.

Een veel voorkomende variable is het Integer variable (in c aangegeven als
"int"). Hier kun je getallen in stoppen die je later weer kunt verwerken in
bijvoorbeeld een rekensom (wat we eigenlijk hierboven gedaan hebben). Zo is
er ook een variable waarbij je een letter, woord of zin in kan zetten. Deze
wordt "char"
genoemd. Je zou hier ook een getal in kunnen zetten, maar de computer ziet
dit dan als een karakter. Hiermee zou je bijvoorbeeld dan niet kunnen
rekenen. Hier even een lijstje met de meest voorkomende variablen

	naam:		type:				bereik:
	--------	------------------------	---------------------------------
	char		karakter			alle karakters en cijfers (worden als een string gezien)
	double		dubbele pressisie float		ver achter de komma
	float		pressisie float			kan een getal met waardes achter de komma aan
	int		getal(len)			-2147483648 tot 2147483647
	long		lange integer			-2147483648 tot 2147483647
	short		korte integer			-32768 tot 32767

Als je een variable wilt gebruiken moet je deze eerst declareren. Hierbij
geef je eerst op wat voor type variable je wilt gebruiken met daarachter de
naam. Dit zou er dus zo kunnen uitzien: "int a;". Hier staat dus
dat variable "a" een integer variable is. Hierna kun je de variable een
waarde geven door: "a = 1" in te
voeren. Nu zouden we dus ons rekensommetje hierboven na kunnen spelen met
het programmeren:

#include <stdio.h>

int main()
{
	int a;
	int b;
	int c;

	a = 2;
	b = 3;
	c = a + b;

	return 0;
}

Dit is allemaal wel leuk en aardig, maar zo kunnen we de uitkomst niet op
het scherm zien. Daarvoor moeten we weer beroep doen op de functie
"printf()". Om de waarde van de variable weer te geven met "printf()" maak
je gebruik van "conversion characters". Dit zijn de %i, %f en %c in het
volgende programma. bij conversion characters gebruik je een elke keer als
je een variable declareerd een komma om de namen van de variablen te
onderscheiden. Als er 1 variable moet worden weergegeven met de functie
"printf()" moet je dit zo doen:

  printf("Dit is een voorbeeld van het gebruik van %i variable", een);

Hier zal voor de plaats %i het integer variable komen die de naam "een"
heeft

Om weer door te gaan op ons rekensommetje hierboven heb ik het volgende
programma geschreven:

#include <stdio.h>

int main()
{
	int a, b, c;

	a = 2;
	b = 3;
	c = a + b;

	printf("De waarde van variable c is nu %i\n", c);

	return 0;
}

Je ziet hier weer iets nieuws namelijk: "int a, b, c;". Dit is een manier om
sneller een aantal variablen met hetzelfde type te declareren.

Een voobeeld van het gebruik van meerdere (typen) variablen:

#include <stdio.h>

int main()
{
    	int   x;
    	float y;
    	char  z;

    	x = 1;
    	y = 1.234;
    	z = 'A';

    	printf("Mijn verschillende type variablen: %i, %f, %c \n",x,y,z);

    	return 0;
}

----- einde code prog3.c -----

Geeft als output weer:

[po0h@mabel c]$ ./prog3
Mijn verschillende type variablen: 1, 1.234000, A
[po0h@mabel c]$

Hier een lijstje met veel voorkomende conversion karakters:

	conversion char		type variable
	----------------	------------------
        %c              	Single character
        %d              	decimal numbers
        %e              	Floating point in scientific notation
        %f              	Floating point
        %lf             	Double
        %Lf             	Long double
        %g              	Uses either %e or %f, based on which is shorter
        %i              	Integer
        %o              	Unsigned octal integer
        %s              	String of text
        %u              	Unsigned integer
        %x              	Unsigned hexadecimal integer

Je kunt ook aangeven hoevel spaties het getal mag bevatten. Dit kun je doen
door middel van
een getal tussen de "%" en het type variable te plaatsen.

----- 04. begin code prog4.c -----

#include <stdio.h>

int main()
{
        int   x = 2;
        int   y = 1000;
        float z = 1.12345;

        printf("%5d, %1d, %.1f\n", x,y,z);

        return 0;
}

----- 04. einde code prog4.c ----

Hier zeg je dat het decimale variable x tenminste 5 spaties moet bevatten.
Om af te ronden achter de komma
kun je bv: "%.1f\n" gebruiken. Hier geef je aan dat de variable z maar
maximaal 1 getal achter de komma mag
bevatten. Als het getal groter is dan de aangegeven spaties negeerd het
programma de spatie. Bij het afkappen
van getallen die ook waardes achter de komma bevatten worden deze getallen
wel afgekapt.

TIP: Je ziet hier dat ik voor variables gebruik maak van letters. Doe niet
in een "serieus" programma vooral niet! Gebruik duidelijk namen zodat je
gelijk herkend waarvoor dat variable staat. Ik zal ook verder in de
documentatie "duidelijke" namen gebruiken.

Voor het gebruiken van user input kun je de functie "scanf()" gebruiken. Je
kunt dan de user input als een
variable opslaan.

	char naam[20];
	scanf("%s", &naam);

Hier zet "scanf()" de user input in de varaible "naam". Je zou dus hierna de
user input weer kunnen weergeven met "printf()". De "&naam" wil zeggen dat
het de input moet worden opgeslagen op de locatie waar het variable "naam"
is opgeslagen.

----- 05. begin code prog5.c -----

#include <stdio.h>

int main()
{
	char naam[21];
	printf("Wat is je naam?\n");
	scanf("%20s", &naam);
	printf("Dus je naam is %s\n", naam);

	return 0;
}

----- 05. einde code prog5.c -----

Dit zal dus als output weergeven:

[po0h@mabel c]$ ./prog5
Wat is je naam?
Twan
Dus je naam is Twan
[po0h@mabel c]$

Je ziet in de code dat ik 21 karakters heb gereserveerd voor variable "naam"
en daarna "%20s" doe. Dit wil zeggen dat ik dat ik 20 karakters van de
ingevoerde karakters gebruik en de rest afkap. Dit doe ik, omdat er anders
een stack-overflow kan ontstaan (met dank aan ilja en Quux :). Als je hier
meer informatie over wilt hebben kun je de documentatie over buffer
overflows raadtplegen. De mensen die opletten zullen merken dat er een
verschil zit tussen 21 en 20. Dit is omdat het afgesloten wordt met een NULL
byte.

##### Operators en Operands #####

Hier zal ik beginnen met een voorbeeld van een programma die getallen bij
elkaar optelt.

----- 06. begin code prog6.c

#include <stdio.h>

int main()
{
        int getal1;
        int getal2;
	int uitkomst;

        printf("Getal 1 is: ");
        scanf("%d", &getal1);
        printf("Getal 2 is: ");
	scanf("%d", &getal2);

        uitkomst = (getal1+getal2);

        printf("De som van %d en %d is %d\n", getal1, getal2, uitkomst);

        return 0;
}

----- 06. einde code prog6.c -----

Hier worden eerst 3 integer variablen aangemaakt. Daarna wordt de user input
gescanned en in variable
"getal1" en "getal2" gezet. Door middel van "getal1" en "getal2" wordt de
uitkomst berekend door:

	uitkomst = (getal1+getal2);

en daarna wordt de uitkomst weergegeven door de functie "printf()".

In C kun je makkelijk getallen latten op- en aflopen. Dit kun je doen door
bijvoorbeeld het
variable getal zo te gebruiken:

	getal++

Dit staat gelijk aan getal=getal+1. Zo zijn er ook nog een paar operators
die sommen verkorten:

	Gebruik		Staat gelijk aan
	-------- 	------------------
        x += 5;         // x = x + 5;
        x -= 5;         // x = x - 5;
        x *= 5;         // x = x * 5;
        x /= 5;         // x = x / 5;

##### IF ... ELSE struktuur #####

Het mooiste met programmeren is natuurlijk het vergelijken van waardes. Zo
kun bijvoorbeeld gegevens invoer
controleren en controleren op fouten. Je bent bijvoorbeeld een spelletje aan
het spelen waarbij je een auto moet besturen. Als je op de rechter pijl
drukt gaat die auto (zou je in ieder geval verwachten) naar rechts.
zo zou je de if structuur ongeveer kunnen zien.

De structuur van if ... else ziet er in c zo uit:

        if( condition ) statement1;
        else statement2;

Om meerdere statemants in de "if" te zetten moet je een begin een einde
declareren.
Dit kan zo gedaan worden:

        if( condition )
        {
                statement1;
                statement2;
        }
        else statement3;

Door de "{" en de "}" geef je een begin een einde aan voor de lus.

Een voorbeeld van een programma die de if ... else lus gebruikt:

----- 07. begin code prog7.c ------

#include <stdio.h>

int main()
{
	int getal1;
	int getal2;

	getal2 = (3);

	printf("Voer het getal 3 in: ");
	scanf("%d", &getal1);

	if (getal2==getal1)
	  printf("Dit was goed!\n");
	else
	  printf("Dit was fout!\n");

	return 0;

}

----- 07. einde code prog7.c -----

In dit programma wordt getal2 vergeleken met de invoer van de gebruiker
(getal1). Als deze aan elkaar gelijk is ("==") wordt er "Dit was goed!"
weergegeven. Is deze niet gelijk aan elkaar dan wordt er "Dit was fout!"
weergegeven. Er staat dus letterlijk:

Als getal2 gelijk is aan getal1, print dan "Dit was goed!".
Anders print "Dit was fout!".

De output van het programma kan dus zijn:

[po0h@mabel c]$./prog7
Voer het getal 3 in: 3
Dit was goed!
[po0h@mabel c]$

Hier is een overzicht met de symbolen die gebruikt kunnen worden om
statemants te vergelijken:

	symbool		betekenis
	-------		-----------
	<		kleiner dan
	>		groter dan
	<=		kleiner dan of gelijk aan
	>=		groter dan of gelijk aan
	==		gelijk aan
	!=		niet gelijk aan

Hier is een programma die de invoer getallen met elkaar vergelijkt:

----- 08. begin code prog8.c -----

#include <stdio.h>

int main()
{
	int getal1;
	int getal2;

	printf("Voer het eerste getal in: ");
	scanf("%d", &getal1);

	printf("Voer het tweede getal in: ");
	scanf("%d", &getal2);

	if (getal1==getal2)
	  printf("De getallen zijn gelijk aan elkaar\n");
	else if (getal1>getal2)
	  printf("Getal %d is groter dan getal %d\n", getal1, getal2);
	else if (getal1<getal2)
	  printf("Getal %d is kleiner dan getal %d\n", getal1, getal2);

	return 0;
}

----- 08. einde code prog8.c -----

Hier wordt het getal dat als eerste ingevoerd wordt door de gebruiker
(getal1) vergeleken met
het tweede getal (getal2). Een uitvoer van het programma zou kunnen zijn:

[po0h@mabel c]$ ./prog8
Voer het eerste getal in: 3
Voer het tweede getal in: 2
Getal 3 is groter dan getal 2
[po0h@mabel c]$

##### FOR ... loop #####

De for loops worden gebruikt om een bepaalde functie of functies een aantal
keer te
herhalen. Een for loop ziet er zo uit:

        for( initialize; while this is true; do this )
                statement;

Meestal wordt eerst een waarde aan het variable gegeven ("initialize").
Daarna wordt er een
voorwaarde op gegeven. Als deze voorwaarde juist is dan gaat de loop door.
Wordt deze onjuist
zal de loop stoppen. Als derde wordt er aangegeven wat er met het variable
moet worden gedaan.

----- 09. begin code prog9.c -----

#include <stdio.h>

int main()
{
	int i;

	for(i=0;i<10;i++)
	  printf("De waarde is nu %d\n", i);

	return 0;
}

----- 09. einde code prog9.c -----

Door dit programma kun je goed zien wat er nou gebeurd. Aan de variable "i"
wordt de waarde van "0"
gegeven. In het begin van de for loop is "i" dus "0". Zolang "i" kleiner is
dan "10" wordt de functie
"printf()" uitgevoerd. Als deze 1 keer is uitgevoerd wordt variable "i"
steeds met 1 verhoogd. Je
krijg dus dit als output:

[po0h@mabel c]$ ./prog9
De waarde is nu 0
De waarde is nu 1
De waarde is nu 2
De waarde is nu 3
De waarde is nu 4
De waarde is nu 5
De waarde is nu 6
De waarde is nu 7
De waarde is nu 8
De waarde is nu 9
[po0h@mabel c]$

##### WHILE ... loops #####

Het principe van de while loop is eigenlijk hetzelfde als de for loop. De
loop gaat door als de statement
waar is en anders stopt het programma. Hier een simpel programmatje waarbij
je zelf kunt bepalen hoe vaak
je een bepaalde zin wil afdrukken:

----- 10. begin code prog10.c -----

#include <stdio.h>

int main()
{
	int i;

	printf("Aantal herhalingen: ");
	scanf("%d", &i);

	while(i--)
	  printf("allemaal aapjes!\n");

	return 0;
}

----- 10. einde code prog10.c -----

Hier geef je dus eerst een waarde aan variable "i". De while lus zal stoppen
als de waardo van "i" "0" is.
Elke keer als de functie in de while loop wordt uitgevoerd wordt variable
"i" met 1 verkleind.

written by Remko

Jun 02
    Change language to:

Het bloeit op teer en asfalt
Het komt en het gebeurt
In zenderruis en testbeeld
En maandagochtendsleur
Dan wendt het zich tot mij
Mijn beide handen vrij

Het glinstert op de golven
Je schrijft het in het zand
Soms grijnst het in de wolken
Dan zie ik het verband
Wanneer ik het bereik
Mijn beide handen vrij

Dan hoor ik oeh, oeh

Het overbrugt de afstand
De weg van jouw naar mij
En wanneer ik je bereik
Mijn beide handen vrij

En ik hoor oeh, oeh

Dan wendt het zich tot mij
Mijn beide handen vrij

Dan hoor ik oeh, oeh
Continue reading »

written by Remko

Jun 02
    Change language to:

Je wordt wakker in hetzelfde bed, dezelfde straat, dezelfde stad.
En wat gister zo werkelijk leek is in je slaap tot illusie teruggebracht.
Je hebt gezegd dat je je koffers pakt voor een reis naar het midden van je hart.
Ver weg van hier waar je moet geven en je tot nu toe slechts de klappen hebt gehad.
Je staat er niet middenin, je leeft maar wat van opzij.
Waar is de vriend of vriendin, die jou daar op wijst?
De kans komt

written by Remko

Jun 02
    Change language to:

Telkens weer iedere keer
Het haalt me neer
Niemand ziet wat ik zie in jou
Ooh het sluipt om me heen
Het ziet zijn kans als ik jou niet krijg

Ooh, nu doet het pijn
Nu doet het pijn

Telkens weer iedere keer
Wil ik meer
Zonder strijd geef ik toe aan jou
Ooh ik kijk om me heen
Daar staan ze weer. Maar niemand weet wat ik wil van jou

Ooh, nu doet het pijn
Ooh, nu doet het pijn
Ooh, nu doet het pijn
Continue reading »

written by Remko

Jun 02
    Change language to:

je ogen rood, je hoofd gebogen
het woord viel op je neer
je hoeft niet meer je stem gebroken
het kwam zo snel, zomaar uit het niets

of wanneer je bent verstoten
door het leven keer op keer
de waarheid je heeft voorgelogen
het leek zoveel, daar sta je dan met niets

zou het uit de hoogte klinken
je het onbescheiden vinden als ik je vraag
wil je mijn held zijn?
in harnas met schild tegen de pijn
wil je mijn held zijn
vanavond, vannacht

daar ga je weer, het moest niet mogen
gewoon van vooraf aan
terwijl je alles hebt doorlopen
je kwam zover, het leidde je tot niets

of alle schuld op jou geschoven
oude wonden stinken weer
als je weerstand is gebroken
je gaf zoveel, nemen kon je niet

zou het uit de hoogte klinken
je het onbescheiden vinden als ik je vraag
wil je mijn held zijn
in harnas met schild tegen de pijn
wil je mijn held zijn
vanavond vannacht?
Continue reading »

written by Remko