Friday, June 28, 2013

What SELinux is not!

If you're interested about the benefits of running SELinux, probably you read the some of documentations where was written something like that:

SElinux is not:
- antivirus software
- firewalls
- an all-in-one security solution

But what this exactly means? Where is the beginning and ends the SELinux protection? To better answering those questions I show two examples, where SELinux is work (block) and where is not. This examples is are a buffer overflow and shellcode. But first we must build a test domain where we can test this examples.

Test domain

The test domain has a minimal privileges to run a simple process via normal system user (and SELinux user "user_u"). We will create a new TE domain as a SELinux policy module. This domain is called process_test_t and we run our two codes example - the buffer overflow and shellcode.

File prosess_test.te:

module process_test 0.1;

require {
        type user_t;
        attribute domain,application_domain_type,ubac_constrained_type,file_type,exec_type,entry_type,non_security_file_type,application_exec_type;
        class file { execute entrypoint };
        class process { transition sigchld  };

type process_test_t,

type process_test_exec_t,

type_transition user_t process_test_exec_t:process process_test_t;
role user_r types { process_test_exec_t process_test_t };

allow user_t process_test_t:process transition;
allow process_test_t process_test_exec_t:file entrypoint;

allow process_test_t user_t:process sigchld;

# for terminal
require {
        type user_devpts_t,sshd_t;
        class chr_file { read write getattr };
        class fd { use };
        class process { rlimitinh siginh noatsecure  };

allow process_test_t user_devpts_t:chr_file { read write } ;
allow process_test_t sshd_t:fd { use };
allow process_test_t user_t:fd { use };
allow user_t process_test_t:process { rlimitinh siginh noatsecure } ;

# getchar()
allow process_test_t user_devpts_t:chr_file { getattr } ;

File prosess_test.fc:

/home/test1/process_test/process_test   --      gen_context(system_u:object_r:process_test_exec_t,s0)

This domain is having only such rights:

root@SELinux:~# sesearch --allow -s process_test_t -d
Found 11 semantic av rules:
   allow process_test_t user_devpts_t : chr_file { read write getattr } ; 
   allow process_test_t sshd_t : fd use ; 
   allow process_test_t user_t : process sigchld ; 
   allow process_test_t user_t : fd use ; 
   allow process_test_t process_test_exec_t : file entrypoint ; 
   allow process_test_t process_test_t : process { fork sigchld } ; 
   allow process_test_t process_test_t : file { ioctl read write getattr lock append open } ; 
   allow process_test_t process_test_t : dir { ioctl read getattr lock search open } ; 
   allow process_test_t process_test_t : lnk_file { ioctl read getattr lock } ; 
   allow process_test_t process_test_t : unix_stream_socket { ioctl read write create getattr setattr append bind connect listen accept getopt setopt shutdown } ; 
   allow process_test_t process_test_t : association sendto ;

So it can't do any bad things and user_u:user_r can run it. The program can run via user_u and wait to user type in a character with getchar().

Ok, now we can build the module. On root (unconfined_t) - in his home directory - create a directory mod_process and write there the two module files: process_test.te and process_test.fc. Then we can compile it:

root@SELinux:~/mod_process_test# make -f /usr/share/selinux/default/include/Makefile process_test.pp

I forget, I do this in Debian Squeeze ;) Remember, you must have install SELinux policy development package.
After build you can load this module:

# semodule -i process_test.pp

Now this command work also with you:

# sesearch --allow -s process_test_t -d

As you can see in the file context (process_test.fc) I choose the location on test code in /home/test1/process_test directory. You can choose different localizations, for test I use system user was called 'test1'. If you choose different location you must change the content in process_test.fc file.

Ok! Now I login as test1 user and create the process_test directory in his home directory:

test1@SELinux:~$ id
uid=1001(test1) gid=1001(test1) groups=1001(test1) context=user_u:user_r:user_t:s0
test1@SELinux:~$ ls -lZd process_test/
drwxr-xr-x. 2 test1 test1 user_u:object_r:user_home_t:s0 4096 Jun 25 21:29 process_test/

Now we can begin the first test.

SELinux and buffer overflow

This is a buffer overflow code. Save it into process_test.c file in process_test directory.

     1 #include <stdio.h>
     2 #include <string.h>
     4 #define TEST 
     6 char *get_correct_pass ()
     7 {
     8 return (char*)"5pW1";
     9 }
    11 int auth ( char *pass )
    12 {
    13 int _auth = 0;
    14 char buff[10];
    15 memset( buff,0,10 );
    16 strcpy( buff, pass );
    18 if ( strcmp( buff,get_correct_pass() ) == 0 ) 
    19 _auth = 1;
    21 return _auth;
    22 }
    24 int main ( int argc, char * argv[] )
    25 {
    26 if ( auth( argv[1] ) )
    27 printf ("access\n");
    28 else
    29 printf ("denied\n");
    30 #ifdef TEST
    31 getchar();
    32 #endif
    33 return 0;
    34 }

Now I little describe this code. This program get a one parameter from line command. This parameter is a passwords. If passwords is correct the program print "access" otherwise print "denied". Correct password is defined in line number 8 ("5pW1").

In line 4 we have TEST declaration, if TEST is declared the program will be wait for a key press (line 31).

The most important function is an auth (line 11). In this function first is declared variable _auth. Second variable is a buff, is having lenght 10 characters.

Because variable buff is declared as second it is above in memory than _auth. This is the reason why overwriting the buff can write the _auth variable (line 16). Program give "access" when function auth() return true (line 26) but any value beyond 0 it's mean TRUE. So if you overwrite _auth variable in some character, each of them have diffrent code from 0.

Let's see in a debugger how overwriting it's work, but before we must compile the code:

test1@SELinux:~/process_test$ gcc -g process_test.c -o process_test

Now we check how to the hex value of "E" character, because I use this character for the test as password.

$ echo 'EEEEEEEEEE' | hexdump 
0000000 4545 4545 4545 4545 4545

Now we run this program in gdb, as parameter we type this password "EEEEEEEEEE" (10x'E').

test1@SELinux:~/process_test$ gdb process_test
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
Reading symbols from /home/test1/process_test/process_test...done.
(gdb) list 1
1 #include <stdio.h>
2 #include <string.h>
4 #define TEST
6 char *get_correct_pass ()
7 {
8 return (char*)"5pW1";
9 }
(gdb) list
11 int auth ( char *pass )
12 {
13 int _auth = 0;
14 char buff[10];
15 memset( buff,0,10 );
16 strcpy( buff, pass );
18 if ( strcmp( buff,get_correct_pass() ) == 0 )
19 _auth = 1;
(gdb) break 18
Breakpoint 1 at 0x40066b: file process_test.c, line 18.
(gdb) run EEEEEEEEEE
Starting program: /home/test1/process_test/process_test EEEEEEEEEE

Breakpoint 1, auth (pass=0x7fffffffe979 "EEEEEEEEEE") at process_test.c:18
18 if ( strcmp( buff,get_correct_pass() ) == 0 ) 
(gdb) x/32wx &buff - 0x1
0x7fffffffe636: 0xe9790000 0x7fffffff 0x45450000 0x45454545
0x7fffffffe646: 0x45454545 0x00000000 0xe6700000 0x7fffffff
0x7fffffffe656: 0x06b90000 0x00000040 0xe7580000 0x7fffffff
0x7fffffffe666: 0x00000000 0x00020000 0x00000000 0x00000000
0x7fffffffe676: 0xbc8d0000 0x7ffff7a9 0x00000000 0x00000000
0x7fffffffe686: 0xe7580000 0x7fffffff 0x00000000 0x00020000
0x7fffffffe696: 0x06970000 0x00000040 0x00000000 0x00000000
0x7fffffffe6a6: 0xb6fe0000 0x5e236504 0x0540ad6d 0x00000040
(gdb) x/wx &_auth
0x7fffffffe64c: 0x00000000
(gdb) quit

Ok, in the red we have ten bytes from the buffer (buff). In the green we have four bytes from the _auth. A distance between them is a two bytes. So, enough add 3 characters in the password to overwrite _auth e.g.:

test1@SELinux:~/process_test$ ./process_test EEEEEEEEEEbbX


And we have an bingo. So now we know that the buffer overflow it is works. Ok, the next step is a change the context of this program.

root@SELinux:~# matchpathcon /home/test1/process_test/process_test
/home/test1/process_test/process_test system_u:object_r:process_test_exec_t:s0
root@SELinux:~# ls -lZ /home/test1/process_test/process_test
-rwxr-xr-x. 1 test1 test1 user_u:object_r:user_home_t:s0 9159 Jun 26 17:55 /home/test1/process_test/process_test
root@SELinux:~# restorecon -v /home/test1/process_test/process_test
restorecon reset /home/test1/process_test/process_test context user_u:object_r:user_home_t:s0->system_u:object_r:process_test_exec_t:s0
root@SELinux:~# ls -lZ /home/test1/process_test/process_test
-rwxr-xr-x. 1 test1 test1 system_u:object_r:process_test_exec_t:s0 9159 Jun 26 17:55 /home/test1/process_test/process_test

Now we check whether SELinux work in enforcing mode.

root@SELinux:~# getenforce 

And the last we can run this program in DTE, and thanks getchar() function (line 31) we can see who context have program at running.

$ ./process_test EEEEEEEEEExx1

Don't press the any key and as root type in:

root@SELinux:~# ps -efZ |grep test1
system_u:system_r:sshd_t:s0-s0:c0.c1023 root 1084 1043  0 17:32 ?      00:00:00 sshd: test1 [priv]
system_u:system_r:sshd_t:s0-s0:c0.c1023 test1 1088 1084  0 17:32 ?     00:00:00 sshd: test1@pts/1
user_u:user_r:user_t:s0         test1     1089  1088  0 17:32 pts/1    00:00:00 -bash
user_u:user_r:process_test_t:s0 test1     1163  1089  0 21:48 pts/1    00:00:00 ./process_test EEEEEEEEEExx1
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 1177 1078  0 21:57 pts/0 00:00:00 grep test1

As you can see process_test run in process_test_t domain (DTE). This process is run by test1 user (user_t), but after that it's work in own domain (process_test_t) and user test1 don't have permission to e.g. kill this (own) proces. You can login as test1 user in second shell and try this:

test1@SELinux:~$ ps -A 
  PID TTY          TIME CMD
 1089 pts/1    00:00:00 bash
 1185 pts/2    00:00:00 bash
 1190 pts/2    00:00:00 ps

Even if you get the PID from root shell you still can't kill them:

test1@SELinux:~$ kill -s 15 1163
-bash: kill: (1163) - Permission denied

And you have such log:

# tail /var/log/audit/audit.log
type=AVC msg=audit(1372276812.345:10): avc:  denied  { signal } for  pid=1185 comm="bash" scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:process_test_t:s0 tclass=process

As you can see the process_test_t domain is very confined. user_t can execute them but can't do anything else - only press the key.

But wait the minute, we run this program in enforcing mode with 13 length password and buffer overflow is work even with SELinux protection. Why this possible?

The answer is in the architecture of operating system. Everything what is going during the buffer overflow technique (at running ./process_test) is going in the process space. This technique is not required interactions with the kernel.
The next examples is better explains that.

SELinux and shellcode

This is a shellcode:

char SC[] =   "\xeb\x1d\x5b\x31\xc0\x67\x89\x43\x07\x67\x89\x5b\x08\x67\x89\x43\x0c"\
main (int argc, char **argv)
        int (*ret)();
        ret = (int(*)())SC;

Description of this exploit tells that code execute system function execve(/bin/sh), but how we can check this? We must compile it and run in gdb.
Before we must save this code in shellcode.c.

test1@SELinux:~/process_test$ gcc -g shellcode.c -o shellcode
test1@SELinux:~/process_test$ gdb -q ./shellcode
Reading symbols from /home/test1/process_test/shellcode...done.
(gdb) list 1
1 char SC[] =   "\xeb\x1d\x5b\x31\xc0\x67\x89\x43\x07\x67\x89\x5b\x08\x67\x89\x43\x0c"\
2              "\x31\xc0\xb0\x0b\x67\x8d\x4b\x08\x67\x8d\x53\x0c\xcd\x80\xe8\xde\xff"\
3              "\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x41\x41\x41\x41\x42\x42\x42"\
4              "\x42";
6 int
7 main (int argc, char **argv)
8 {
9        int (*ret)();             
10        ret = (int(*)())SC;
(gdb) disas SC
Dump of assembler code for function SC:
0x00000000006008c0 <SC+0>: jmp    0x6008df <SC+31>
0x00000000006008c2 <SC+2>: pop    %rbx
0x00000000006008c3 <SC+3>: xor    %eax,%eax
0x00000000006008c5 <SC+5>: addr32 mov %eax,0x7(%ebx)
0x00000000006008c9 <SC+9>: addr32 mov %ebx,0x8(%ebx)
0x00000000006008cd <SC+13>: addr32 mov %eax,0xc(%ebx)
0x00000000006008d1 <SC+17>: xor    %eax,%eax
0x00000000006008d3 <SC+19>: mov    $0xb,%al
0x00000000006008d5 <SC+21>: addr32 lea 0x8(%ebx),%ecx
0x00000000006008d9 <SC+25>: addr32 lea 0xc(%ebx),%edx
0x00000000006008dd <SC+29>: int    $0x80
0x00000000006008df <SC+31>: callq  0x6008c2 <SC+2>
0x00000000006008e4 <SC+36>: (bad)  
0x00000000006008e5 <SC+37>: (bad)  
0x00000000006008e6 <SC+38>: imul   $0x414e6873,0x2f(%rsi),%ebp
0x00000000006008ed <SC+45>: rex.B
0x00000000006008ee <SC+46>: rex.B
0x00000000006008ef <SC+47>: rex.B
0x00000000006008f0 <SC+48>: rex.X
0x00000000006008f1 <SC+49>: rex.X
0x00000000006008f2 <SC+50>: rex.X
0x00000000006008f3 <SC+51>: rex.X add    %al,(%rax)
End of assembler dump.
(gdb) q

This is a assembler code. In the blue I mark the code which clear EAX register and set in a 0xb hex value. 0xb in decimal number is a 11. In the red I mark the holy grail of understand when SELinux is work. In assembly language instruction 'int 0x80' is used when program wants invoke a system calls. In other words that is means the interrupt, this happens when a code flow is switch into system mode. Only then - when program interaction with the system - SELinux can control the process actions (the subject).

Below is a definitions of the system call numbers in file root/arch/x86/include/asm/unistd_32.h from kernel source. On the blue mark we have the number of execve() function.

#ifndef _ASM_X86_UNISTD_32_H
#define _ASM_X86_UNISTD_32_H

 * This file contains the system call numbers.

#define __NR_restart_syscall      0
#define __NR_exit    1
#define __NR_fork    2
#define __NR_read    3
#define __NR_write    4
#define __NR_open    5
#define __NR_close    6
#define __NR_waitpid    7
#define __NR_creat    8
#define __NR_link    9
#define __NR_unlink   10
#define __NR_execve   11
#define __NR_chdir   12
#define __NR_time   13
#define __NR_mknod   14
#define __NR_chmod   15
#define __NR_lchown   16
#define __NR_break   17
#define __NR_oldstat   18
#define __NR_lseek   19
#define __NR_getpid   20

The next what we do is a compile the shellcode without a process memory protections.

root@SELinux:~# rm /home/test1/process_test/process_test
test1@SELinux:~/process_test$ gcc -fno-stack-protector -z execstack shellcode.c  -o process_test
root@SELinux:~# restorecon -v /home/test1/process_test/process_test
restorecon reset /home/test1/process_test/process_test context user_u:object_r:user_home_t:s0->system_u:object_r:process_test_exec_t:s0
test1@SELinux:~/process_test$ ls -lZ process_test
total 24
-rwxr-xr-x. 1 test1 test1 system_u:object_r:process_test_exec_t:s0 6657 Jun 27 21:11 process_test
test1@SELinux:~/process_test$ ./process_test 

And we have such logs:

root@SELinux:~# tail /var/log/audit/audit.log
type=AVC msg=audit(1372360361.357:69779): avc:  denied  { search } for  pid=1221 comm="process_test" name="bin" dev=sda1 ino=562 scontext=user_u:user_r:process_test_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=dir
type=SYSCALL msg=audit(1372360361.357:69779): arch=40000003 syscall=11 per=400000 success=no exit=-13 a0=6008e4 a1=6008ec a2=6008f0 a3=7fff3d5bf1f8 items=0 ppid=1057 pid=1221 auid=4294967295 uid=1001 gid=1001 euid=1001 suid=1001 fsuid=1001 egid=1001 sgid=1001 fsgid=1001 tty=pts1 ses=4294967295 comm="process_test" exe="/home/test1/process_test/process_test" subj=user_u:user_r:process_test_t:s0 key=(null)

The process_test runs in process_test_t domain don't have permission to search the /bin directory. Even if it had this permission it don't have permission to execute a bin_t type object and many others permission required to run /bin/sh.


Summary of this two examples it show the SELinux is a kernel security mechanism that work only if the process (subject) must use of the system calls to do bad things.

Furthermore you must understand that if a process which has SELinux permission to e.g. write in to /etc/passwd will be crack with technique which work only in the process space the SELinux protections it's not stop it. SELinux check only if a particular process can call a particular system function, but not check when it do this.

So SELinux is not see a diffrent between a normal system call from proces (the orginaly code flows) and a crack call from process (an attacker changes the orginaly code flows). Of course the policy must allow this action for this process.

Saturday, June 22, 2013

Historia komputerów jakiej nie znałeś

Czy zastanawiałeś się kiedyś nad tym, co właściwie dzieje gdy uruchamiasz swój komputer? Wracasz do domu z pracy bądź szkoły, bierzesz laptopa, wciskasz przycisk "Power" i czekasz, aż załaduje się system. Dziś informatyka kojarzona jest z matematyką, podobno mają ze sobą tak wiele wspólnego. Komputery mają więcej wspólnego z fizyką, a konkretnie z elektroniką. W istocie rzeczy komputery przecież są urządzeniami elektronicznymi. Elektronika powstała na bazie fizyki przy pomocy matematyki, tak samo jak informatyka powstała na bazie elektroniki przy pomocy matematyki. Mniej więcej tak można zdefiniować samą informatykę, ale na pewno informatyka nie powstała dzięki matematyce, taka informatyka mogłaby istnieć tylko na papierze - i istniała. Informatyka to fizyczne wykorzystanie matematycznych reguł przy pomocy elektroniki, równie dobrze mogłaby się nazywać "infortronika". Najlepiej pokazać to na przykładzie historii.

Więc to będzie historia o tym, jak komputery działają, dzięki czemu i komu było możliwe ich zbudowanie. Postaram się również pokazać, w których momentach pomoc matematyki była niezbędna, a w których fizyki. Co ciekawe w tej historii znajdzie się wiele rzeczy na pierwszy rzut oka nie mających nic wspólnego z komputerami, wszak człowiek z małpą też nie ma nic wspólnego.

Ponieważ kompletna historia komputerów jest zbyt dużym zagadnienie, to w tym tekście ograniczyłem się do części informatyki zwanej hardware. Software zostanie tu pominięte, ponieważ to już historia systemów operacyjnych.


W komputerach jest coś, co sprawia iż ożywają. Co ciekawe to samo ożywia ludzkie ciało, to energia elektryczna. Mózg steruje Twoimi mięśniami za pomocą impulsów elektrycznych, a elektrowstrząsy potrafią przywrócić człowieka do życia.
Jak widać mamy więcej wspólnego z komputerami niż nam się wydaje, wszak budujemy je na swoje podobieństwo. Uczymy je tego co sami potrafimy by korzystać z ich szybkości i nieomylności. Jednak ile jest wart Twój komputer bez energii elektrycznej i właściwie czym ona jest?

Dzięki Einsteinowi wiemy, że każdy kawałem materii posiada ogromne zasoby energii. Problem w tym, że nadal do końca nie wiemy jak ją wydobyć. Obecnie najlepiej znanym nam sposobem na wydobyć tej energii jest bomba atomowa. Jednak jak wiadomo energia wydobyta w ten sposób jest "brudna". Wydaje się że obecnie najbardziej znanym nam sposobem na wydobywanie energii jest elektryczność. Ta również nie jest w stu procentach czysta, dlatego obecnie opracowuje się ekologiczne źródła energii. Jednak elektryczność to szczególna forma energii, która występuje w naturalnym środowisku, pod takimi postaciami jak światło i pioruny. Oczywiście, w skali kosmosu energia bomby atomowej również występuje w naturalnej postaci, to np. nasze słońce.

Najważniejsze z tego wszystkiego jest to, aby zrozumieć, iż energia nie jest nowym produktem, tylko inną formą materii. Tak więc posiadamy ogromne zasoby i próbujemy wydobyć z niej energię. Gdyby udało nam się wydobyć chociaż połowę rzeczywistej energii z masy jaką posiada bateria laptopa, to nasz laptop pracowałby jak amerykański lotniskowce wyposażone w dwa reaktory atomowe, które pozwalają mu funkcjonować nawet przez ponad 20 lat.

Początki elektryczności

Elektryczność fascynowała ludzi od dawna, ale przez wieki pozostawała poza ich zasięgiem. Historia ujarzmiania elektryczności zaczyna się w XVIII wieku. Stephen Gray mieszkający w Londynie zbudował w swoim domu szklaną tubę i eksperymentował z elektrycznością statyczną, którą wytwarzał przykładając dłoń do szybko obracanej szklanej tuby. Zaobserwował, że elektryczność można wygenerować przez ruch i potrafi ona poruszać przedmioty. W 1732 opublikował wyniki swoich badań, których efektem były odkrycie przewodników i izolatorów. Do dziś używamy różnych metali jako przewodników i porcelany jako izolatora na słupach elektrycznych.

W 1745 Pieter van Musschenbroek, Holenderski naukowiec szukał sposobu na zgromadzenie elektryczności. Wcześniej wiedziano, że człowiek może ją wytworzyć, ale gdy przestawał to robić, natychmiast znikała. Wpadł na pomysł, aby poprzez metalowy przewód zgromadzić elektryczność wytwarzaną przez obracającą się szklaną tubę w wodzie przechowywanej w szklanym naczyniu. Szklane naczynie postawił na materiale, który miał właściwości izolacyjne. Pewnego razu zapomniał to zrobić i trzymał szklany pojemnik w dłoni, i tak udało mu się zbudować pierwsze urządzenie na świecie potrafiące przechowywać elektryczność. Nazwano je butelką lejdejską i jest ona przodkiem elementów elektrycznych znajdujących się dziś w niemal każdym urządzeniu elektronicznym - to kondensator.

Parę lat później jeden z założycieli Stanów Zjednoczonych Benjamin Franklin dokonał eksperymentu polegającego na naładowaniu butelki lejdejskiej za pomocą piorunu. Do środka butelki włożył trzy metrowy pręt i czekał na burze. Eksperyment powiódł się, jego wynikiem było udowodnienie, że pioruny są tą samo elektrycznością, którą wytwarza człowiek. Benjamin oprócz zrozumienia natury wyładowań elektrycznych wyjaśnił również zasadę działania butelki lejdejskiej i stworzył definicje ładunków elektrycznych opisując fundamentalne własności ładunków dodatnich i ujemnych.

W 1800 roku, włoski fizyk Alessandro Volta zbudował pierwszą baterie, zwaną stosem Volty. Warto podkreślić, iż bateria ta generowała energię z elektrycznych właściwości dwóch różnych metali, bez udziału jakiegokolwiek źródła energii zewnętrznej. Jego wkład w elektryczność był tak ważny, że na jego cześć nazwano jednostkę napięcia jego nazwiskiem. Dziewięć lat później brytyjski chemik Humphry Davy zbudował największą baterię jaką do tej pory widziano i przed publicznością zetkną ze sobą dwa końce kabli podłączone do tej baterii generując po raz pierwszy elektryczne światło wytworzone przez człowieka, które zapowiadało nadejście nowej ery w elektryczności.


Michael Faraday był angielskim samoukiem, który interesował się elektrycznością. Udało mu się dostać pracę na stanowisku asystent w laboratorium Royal Institution of Great Britain. W 1821 roku zbudował pierwsze urządzenie, które jest przodkiem wszystkich obecnych silników elektrycznych. Odkrył, że prąd generuje pole magnetyczne, a jak wiadomo magnetyzm pozwala poruszać przedmioty. To odkrycie było początkiem nowej ery, w której ważniejsze było to, do czego prąd można wykorzystać, niż czym właściwie jest. Faraday odkrył również, że proces ten można odwrócić. Ruch i magnetyzm mógł generować prąd. To właśnie na tej zasadzie działają dzisiejsze elektrownie, dzięki której teraz działa Twój komputer. Faraday odkrył zjawisko zwane indukcją elektromagnetyczną.

Można by się domyśleć, że kolejnym krokiem będzie stworzenie elektrowni i żarówki, jednak najpierw stworzono coś innego, coś co ma więcej wspólnego z komputerem niż by się mogło wydawać.


W 1827 roku Amerykański naukowiec Joseph Henry dopracował elektromagnes. Jego zasadniczą cechą było to, że pole magnetyczne (elektromagnes) można było kontrolować na odległość za pomocą przewodu i prądu. To odkrycie pozwoliło na stworzenie pierwszego urządzenia przydatnego w codziennym ludzkim życiu, telegrafu.
Alfabet Morsa
W 1837 roku Samuel Morse zbudował pierwszy telegraf, który wykorzystywał prosty kod, zwany kodem Morsa. Zakodowanie alfabetu za pomocą tylko dwóch odmiennych sygnałów elektrycznych stanowi kamień milowy dla ówczesnej informatyki.

Poniższy film demonstruje zasadę działania telegrafu.

Od 1850 roku próbowano połączyć za pomocą kabla ówczesne dwa mocarstwa, Anglię i Stany Zjednoczone. Początkowo uważano, że położenie linii telegraficznej pod Atlantykiem jest niewykonywalne, jednak realne zyski zachęciły do prób. Ostatecznie w 1859 roku na środku Atlantyku połączono ze sobą dwa kable, tym samym łącząc ze sobą i po raz pierwszy dwa kontynenty.
Niestety komunikaty były mało zrozumiane, odbiorca nie mógł odróżnić krótkiego sygnału od długiego. Sytuacja okazała się frustrująca. Jakby tego było mało inżynierowie postanowili zwiększyć napięcie, gdyż uważali, że większe napięcie wygeneruje mocniejszy i wyraźniejszy sygnał. Niestety, konsekwencją podniesienia napięcia było zniszczenie kabla. Wtedy jeszcze nie do końca wiedziano nic o fali elektromagnetycznej i jak właściwie prąd płynie przez przewód. Mimo wszystko położenie transatlantyckiego kabla było największym i najdroższym eksperymentem z elektrycznością.

History of the Atlantic Cable

W końcu w 1866 roku położono nowy kabel, który rozwiązywał problem zakłóceń poprzez zastosowanie ekranowania i ponownie przesłano wiadomość. Tym razem sygnał był wyraźny i zrozumiany. Pierwszy raz informacja z Wielkiej Brytanii do Stanów Zjednoczonych docierała niemal natychmiast zamiast dwóch tygodni. Osiągnięcie to było bardziej postępem cywilizacyjnym niż technicznym.


Nad ideą przesyłania głosu za pomocą elektryczność od 1875 roku pracował Alexander Graham Bell i to on złożył pierwszy patent na telefon. Jednak to urządzenie miało wielu współtwórców. W 1876 roku Alexander dokonał pierwszego udanego eksperymentu polegającego na przesłaniu dźwięku: "Mr. Watson come here I want to see you". W kolejnych latach cały czas udoskonalano tą technologię. Pierwszą rozmowę długodystansową  pomiędzy Nowym Jorkiem a Kalifornią wykonano dopiero aż w 1915 roku, ale jedna z pierwszych, a zarazem najbardziej znanych firm telekomunikacyjnych powstała już w 1885 roku, to AT&T (American Telephone and Telegraph Company). AT&T odegra jedną ze znaczących ról w procesie powstawiania komputerów. Teraz już wiesz, skąd wzięła się nazwa Bell Labs, nazwa laboratorium, w które miało wielki wpływ na powstanie komputerów i systemów operacyjnych.

W tym miejscu historia telefonu dopiero się zaczyna, a kolejność następnych odkryć traci liniowość. Wiele kolejnych odkryć było dokonywanych równocześnie, a ich opracowanie i udoskonalanie trwało lata. Postaram się jednak zachować właściwą kolejność dla nowych urządzeń wykorzystujących elektryczność.

Jak pisałem w 1809 roku Humphry Davy po raz pierwszy wygenerował światło, właściwie była to iskra i nie nadawała się do oświetlania domów, ponieważ była zbyt jasna. Pierwsza upowszechniona żarówka pojawiła się dopiero w 1880 roku, stworzył ją Thomas Edison. Nowy rodzaj elektryczności zrewolucjonizował nasze życie. Do tej pory pomieszczenia oświetlano gazem, lampami naftowymi lub zwykłymi świecami.

Dziś trudno to sobie wyobrazić, ale wszystkich odkryć opisanych do tej pory dokonano w pewnym sensie przy świetle świec. Mogliśmy wysyłać już telegramy, ale nadal używaliśmy świec i nadal energia elektryczna nie była powszechnie dostępna.

Dystrybucja energii elektrycznej

Choć Edison nie był jedynym wynalazcą żarówki, to cała chwała przypadła jemu. Jednak kluczem do elektrycznego biznesu było generowanie prądu i jego dystrybucja do jak największej ilości odbiorców. Tylko wtedy w pełni można było zarobić na elektryczności. W tym momencie historia elektryczności przestaje mieć charakter czysto odkrywczy i nabiera czysto ekonomicznych cech.

W 1882 roku Edison w otoczeniu reporterów i bankierów zapowiedział wybudowanie pierwszej elektrowni (ang. power station) na Manhatanie. Stacja została uruchomiona w 1890 roku i generowała prąd stały (DC). Jednak opłacalność takiego systemu była zerowa, ponieważ mogła ona dostarczać energię tylko w obrębie jednej mili, z powodu strat napięcia. System ten był bardzo ograniczony i drogi, a wielka wizja Edisona, w której oświetli on cały Nowy Jork została powstrzymana przez ograniczenia jego systemu.

Wybudowanie elektrowni było wielkim krokiem, pierwszy raz energię można było kupić. Poza tym centralne generowanie pozwalało uzyskać większą efektywności i ciągłą pracę. Jednak problemy z systemem rozprowadzania energii nie pozwalały na ekspansje elektryczności.

AC vs. DC

Rozwiązanie problemu zaproponował nieznany geniusz, był nim Nikola Tesla. Zaproponował zupełnie inne rozwiązanie, było nim generowanie prądu przemiennego (AC) poza miastami i dostarczanie do miasta. Tesla nie skupiał się tylko na generowaniu prądu, opracował cały system jego dystrybucji. Zaletą prądu przemiennego jest to, że można go przesyłać bez znacznych strat na bardzo duże odległości. Jego wadą było to, że wysokie napięcia prądu przemiennego są niebezpieczne.

Jednak sam Tesla nie był znany, ale jego patentem na generowanie prądu przemiennego i jego przetwarzanie na prąd stały zainteresował się George Westinghouse. Odkupił go od Tesla za znaczną kwotę, oraz za stałą opłatę od określonej ilości sprzedanej energii.

War of Currents - Transformator Tesli
Edison zwalczał pomysł Tesla strasząc ludzi, tym jak prąd przemienny jest niebezpieczny. Organizował pokazy, w których zabijał psy, a nawet konie. Wywołało to powszechny strach. Edison reklamował swój produkt jako bezpieczny system. Napięcie było duże, gdyż Thomas Edison i George Westinghouse walczyli o kontrakt na zaopatrzenie Nowego Jorku w prąd. Mieli świadomość tego, że przed zwycięzcą stanie otworem cały rynek.

W odpowiedzi na zabójcze działanie prądu przemiennego Tesla również przygotował pokaz, który sprawił iż ludzie uwierzyli, że prąd przemienny o bardzo dużych napięciach może być bezpieczny. Pokaz Nikola Tesla z 1891 roku zmienił bieg historii. W 1896 roku na wodospadzie Niagara zbudowano pierwszą elektrownię, która parę lat później zasiliła Nowy Jork w energię elektryczną. Dziś wszyscy korzystamy z energii elektrycznej dostarczanej systemem Nikola Tesla. Teraz już wiesz dlatego do komputera potrzebny jest adapter DC.

Jednak historia Nikola Tesla nie kończy się w chwale i bogactwie. Człowiek, który pomógł stworzyć dzisiejszy świat umarł biedny i samotny w hotelowym pokoju, a Edison stał się w pewnym sensie bohaterem Ameryki.

Manhattan nocą zasilany systemem Tesli
NASA - Electromagnetic Spectrum

Michael Faraday w 1846 roku powiedział, iż światło to jedna z form fali elektromagnetycznych. Publiczność go wyśmiała, mimo iż był już wtedy cenionym profesorem. Faraday nie potrafił udowodnić swego twierdzenia, potrzebował kogoś kto by mu pomógł. Po piętnastu latach (1861 r.) profesor James Clerk Maxwell natknął się na ideę Faradaja i uwierzył w nią. Postanowił udowodnić to matematycznie.

W 1887 roku Heinrich Rudolf Hertz przeprowadził eksperymenty, które potwierdziły prawidłowość obliczeń wykonanych przez Maxwell'a. W 1894 roku Oliver Lodge po raz pierwszy zaprezentował urządzenie wykrywające fale elektromagnetyczne. Wydarzenie to rozpoczyna nową erę w komunikacji i nauce.


Nie trudno domyślić się co było następstwem odkrycia fal elektromagnetycznych. Guglielmo Marconi jest najbardziej znanym nazwiskiem z wynalezienia radia. Co prawda nie tylko on rozwijał tą technologię ale to jemu udało się pierwszemu dokonać transmisji przez Atlantyk. Jego pierwsze eksperymenty z radiem miały miejsce w 1895 roku, natomiast pierwsza transatlantycka wiadomość przez Marconiego miała miejsce w 1902 roku.


Skoro to co widzimy jest światłem, a światło jest falą elektromagnetyczną, którymi zaczynano manipulować, to możliwe jest rejestrowanie i przesyłanie obrazu do odbiornika. Tak jak w przypadku telefonu użyto greckiego słowa "tele", które oznacza na odległość. Idea przesyłania obrazu na odległość powstała mniej więcej w tym samym czasie co przesyłanie dźwięku.

Pierwsze urządzenie potrafiące odbierać obraz stworzono w 1906 roku, jednak nie przypominało ono nowoczesnych telewizorów kineskopowych. Dużą rolę w rozwoju telewizji odegrały lampy elektronowe, z których w przyszłości budowano pierwsze komputery. Pierwsze stacje nadawcze, które są dziś jednymi z największych na świecie powstawały na początku lat trzydziestych, ale pierwszy przekaz kolorowego obrazu miał miejsce w 1938 roku.


W 1947 roku w Bell Labs stworzono pierwszy tranzystor. Tranzystor korzysta z fizycznych właściwości krzemu, które nazwano półprzewodnikiem. Zasadę tranzystora można opisać następująco. Wyobraź sobie, że kawałek półprzewodnika (np. krzemu) łączy dwa przewody. Załóżmy, że prąd nie przepływa przez półprzewodnik. Teraz do krzemu przyłączmy trzeci przewód odgrywający rolę kontrolera. Za pomocą kontrolera małym napięciem uruchamiamy przewodnictwo większych napięć, czyli pozostałych dwóch przewodów połączonych z krzemem. Można to porównać do włącznika światła, gdzie przycisk pełni rolę kontrolera.

Zbudowanie elektronicznego przełącznika pozwoliło skonstruować logiczne bramki. Np. przy pomocy kilku tranzystorów można zbudować układy realizujące operacje logiczne, takiej jak AND, OR i NOT. Te proste operacje logiczne wraz z arytmetyką binarną są podstawami dzisiejszych procesorów. Stworzenie tranzystora rozpoczyna erę ówczesnych komputerów oraz całą masę urządzeń elektronicznych.

W 1948 roku Bell Labs opublikował jeden z najważniejszych dokumentów dla dzisiejszej komunikacji w sieci. "A Mathematical Theory of Communication", to matematyczne podstawy kodowania informacji przy pomocy urządzeń elektronicznych.

W 1956 roku John Bardeen, Walter H. Brattain i William Shockley otrzymali nagrodę Nobla z fizyki za wkład w stworzenie tranzystora.

Dolina Krzemowa

Zapewne Dolina Krzemowa kojarzy Ci się z informatyczną mekką, Google, Facebook, Intel, Microsoft i całą reszta wielkich korporacji. Jednak zanim tak się stało miejsce to miało przeznaczenie rolnicze i było pełne owocowych sadów.

W 1953 jedne z konstruktorów tranzystora William Shockley opuścił Bell Labs i założył firmę produkującą tranzystory zwaną Shockley Semiconductor Laboratory. Oczywiście na lokalizacje wybrał wspomniane tereny rolnicze. Kolejną oczywistością jest to, że sam nie mógł zająć się wszystkim, potrzebował współpracowników. Tak więc zebrał najlepszych fizyków, był tam chyba też chemik i matematyk, razem było ich ośmiu (zdradziecka ósemka).

Jeżeli jesteś dociekliwy, pewnie zadajesz sobie pytanie dlaczego zdradziecka? Otóż osoby te miały okazje pracować w pierwszej firmie zajmującej się produkcją półprzewodników i zdobyły tam cenne doświadczenia zawodowe. W tamtych czasach produkcję półprzewodników napędzała zimna wojna,  Shockley Semiconductor Laboratory realizował wiele zleceń dla Armii US. W każdym bądź razie w 1957 roku cała ósemka opuściła dotychczasowego pracodawcę i założyła nową firmę zwaną Fairchild Semiconductor. W 1968 roku dwóch inżynierów ze wspomnianej ósemki stworzyło kolejną firmę, którą na pewno kojarzysz. Robert Noyce i Gordon Moore stworzyli firmę Intel i tak powstała Dolina Krzemowa.

W tym miejscu kończy się historia, którą chciałem przedstawić a zaczyna się historia współczesnej informatyki.


Otóż każda część Twojego laptopa, czy tabletu ma swoich przodków w przedstawionej historii. Ekran, dysk, WiFi, gładzik, zasilacz, bateria, głośniki, kamera, mikrofon, procesor, jednym słowem wszystko. Wszystko to składa się na obecnie jedno z najbardziej złożonych urządzeń elektronicznych zwanych komputerem. Każda z tych części może działać tylko dzięki energii elektrycznej. Obecne komputery nie mogłyby oferować takiej funkcjonalności, gdyby wcześniej nie wynaleziono żarówki, elektrowni, baterii, telefonu, radia, telewizji i w końcu tranzystora. Każdy z tych wynalazków jest częścią historii obecnych komputerów.

Więc, jeżeli zastanawiasz się jak działa WiFi, czy procesor, a tym bardziej jakich innowacji niebawem się doczekasz, to w pewnym sensie pytasz o przyszłość urządzeń elektronicznych, z których zbudowany jest Twój komputer.

Ale tryumf elektryczność nie ogranicza się do zbudowania komputera przez człowieka. Elektryczność, a właściwie nasza umiejętność manipulowania nią zmieniła cały nasz dotychczasowy świat, komputer zaś jest tylko jedna z form tej rewolucji.