Friday, March 16, 2007
Natural language
All existing computer languages are merely tools and not exactly a language. They provide syntax base to implement our ideas. For example, in order to compute the circumference or area of a circle, all we have to know is the formula and technique. We know that circumference of circle in terms of radius is "2 pi r" and area in terms of radius is "pi r square". If I want to express or calculate this using a existing computer language, for example C language, it goes like this:
main
{
float pi = 3.1415;
float radius = 5;
float area, circumference;
circumference = 2 * pi * radius;
area = pi * radius * radius;
printf("Circumference of the circle: %f\n", circumference);
printf("Area of the circle: %f\n", area);
}
or if the value of pi and radius, have to be received from the user:
main()
{
float p, radius, area, circumference;
scanf("%f", &p);
scanf("%f", &radius);
circumference = 2 * p * radius;
area = p * radius * radius;
printf("Circumference of the circle: %f\n", circumference);
printf("Area of the circle: %f\n", area);
}
so, here instead of expressing the idea, I am just implementing it. Otherwise, lets say if I write "scanf("%f", &p);" as "scanf("%f", p);", this is going to result in a big mistake, because this is due to syntax. Hence, when we want to express our ideas using existing languages, we need to know 2 fundamental concepts
1) what to express
2) how to express
But, How actually a language should look like is:
start:
to find circumference of the circle:
assume pi as 3.1415;
receive the radius from the user via console and store it in rad;
receive the diameter from the user via console and store it in dia;
now compute the circumference of the circle;
store this result in circumference;
to find the area of the circle:
assume pi as 3.1415
receive the radius from the user via console and store it in rad;
receive the diameter from the user via console and store it in dia;
now compute the area of the circle;
store this result in area;
display the output:
display the computed circumference and area via console;
end:
you may ask Why I have not put ";" in the end of the line next to "to find the area of the circle:", because there is no syntax in my language. It is all about ideas and expressions !
this is very easy, simple and straightforward, as this only talks about the idea instead of implementation. Though, one way this can be termed as implementation, there is no way you are going to bother about variables, syntax; etc.
To put it otherwise, if you make some mistake, you are going to end up only logical errors instead of logical plus syntax errors !!!
Thursday, March 15, 2007
OpenBSD's IPv6 mbufs remote kernel buffer overflow
Core Security Technologies - CoreLabs Advisory
Vendors contacted: OpenBSD.org
- 2007-02-20: First notification sent by Core.
- 2007-02-20: Acknowledgement of first notification received from the OpenBSD team.
- 2007-02-21: Core sends draft advisory and proof of concept code that demonstrates remote kernel panic.
- 2007-02-26: OpenBSD team develops a fix and commits it to the HEAD branch of source tree.
- 2007-02-26: OpenBSD team communicates that the issue is specific to OpenBSD. OpenBSD no longer uses the term "vulnerability" when referring to bugs that lead to a remote denial of service attack, as opposed to bugs that lead to remote control of vulnerable systems to avoid oversimplifying ("pablumfication") the use of the term.
- 2007-02-26: Core email sent to OpenBSD team explaining that Core considers a remote denial of service a security issue and therefore does use the term "vulnerability" to refer to it and that although remote code execution could not be proved in this specific case, the possibility should not be discarded. Core requests details about the bug and if possible an analysis of why the OpenBSD team may or may not consider the bug exploitable for remote code execution.
- 2007-02-28: OpenBSD team indicates that the bug results in corruption of mbuf chains and that only IPv6 code uses that mbuf code, there is no user data in the mbuf header fields that become corrupted and it would be surprising to be able to run arbitrary code using a bug so deep in the mbuf code. The bug simply leads to corruption of the mbuf chain.
- 2007-03-05: Core develops proof of concept code that demonstrates remote code execution in the kernel context by exploiting the mbuf overflow.
- 2007-03-05: OpenBSD team notified of PoC availability.
- 2007-03-07: OpenBSD team commits fix to OpenBSD 4.0 and 3.9 source tree branches and releases a "reliability fix" notice on the project's website.
- 2007-03-08: Core sends final draft advisory to OpenBSD requesting comments and official vendor fix/patch information.
-
- 2007-03-09: OpenBSD team changes notice on the project's website to "security fix" and indicates that Core's advisory should reflect the requirement of IPv6 connectivity for a successful attack from outside of the local network.
- 2007-03-12: Advisory updates with fix and workaround information and with IPv6 connectivity comments from OpenBSD team. The "vendors contacted" section of the advisory is adjusted to reflect more accurately the nature of the communications with the OpenBSD team regarding this issue.
- 2007-03-12: Workaround recommendations revisited. It is not yet conclusive that the "scrub in inet6" directive will prevent exploitation. It effectively stops the bug from triggering according to Core's tests but OpenBSD's source code inspection does not provide a clear understanding of why that happens. It could just be that the attack traffic is malformed in some other way that is not meaningful for exploiting the vulnerability (an error in the exploit code rather than an effective workaround?). The "scrub" workaround recommendation is removed from the advisory as precaution.
- 2007-03-13: Core releases this advisory.
Release Mode: FORCED RELEASE
Vulnerability Description
The OpenBSD kernel contains a memory corruption vulnerability in the code that handles IPv6 packets. Exploitation of this vulnerability can result in:
1) Remote execution of arbitrary code at the kernel level on the vulnerable systems (complete system compromise), or;
2) Remote denial of service attacks against vulnerable systems (system crash due to a kernel panic)
The issue can be triggered by sending a specially crafted IPv6 fragmented packet.
OpenBSD systems using default installations are vulnerable because the default pre-compiled kernel binary (GENERIC) has IPv6 enabled and OpenBSD's firewall does not filter inbound IPv6 packets in its default configuration.
However, in order to exploit a vulnerable system an attacker needs to be able to inject fragmented IPv6 packets on the target system's local network. This requires direct physical/logical access to the target's local network -in which case the attacking system does not need to have a working IPv6 stack- or the ability to route or tunnel IPv6 packets to the target from a remote network.
Vulnerable Packages
OpenBSD 4.1 prior to Feb. 26th, 2006.
OpenBSD 4.0 Current
OpenBSD 4.0 Stable
OpenBSD 3.9
OpenBSD 3.8
OpenBSD 3.6
OpenBSD 3.1
Thursday, March 01, 2007
Sorting in ASM - Non Optimized snippet
.section .data
list: .long 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
dis: .ascii "\0\0\0\0\0"
newline: .ascii "\n\0"
space: .ascii " \0"
bsm: .ascii "Before sorting ... \n\0"
asm: .ascii "\nAfter sorting ... \n\0"
.section .text
.globl _start
_start:
pushl $bsm
pushl $20
call _printstr
addl $8, %esp
movl $10, %ecx
movl $0, %edi
bs:
cmpl $0, %ecx
je end_bs
movl list(, %edi, 4), %eax
# print the list
# *****************************************
pushl $dis
pushl %eax
call _int2str
addl $8, %esp
pushl $dis
pushl $1
call _printstr
addl $8, %esp
decl %ecx
incl %edi
jmp bs
# ****************************************
# end of print list
end_bs:
pushl $list
pushl $10
call _sort
addl $8, %esp
pushl $asm
pushl $21
call _printstr
addl $8, %esp
movl $10, %ecx
movl $0, %edi
as:
cmpl $0, %ecx
je end_as
movl list(, %edi, 4), %eax
# print the list
# *****************************************
pushl $dis
pushl %eax
call _int2str
addl $8, %esp
pushl $dis
pushl $1
call _printstr
addl $8, %esp
decl %ecx
incl %edi
jmp as
# ****************************************
# end of print list
end_as:
pushl $newline
pushl $1
call _printstr
addl $8, %esp
call _exit
.type _sort, @function
_sort:
pushl %ebp
movl %esp, %ebp
subl $20, %esp
# -4 = outer loop counter, -8 = = inc of 4, -12 = addr1, -16 = addr2, -20 = main loop
movl 12(%ebp), %esi # address of the list
movl 8(%ebp), %edi # number of items
movl $0, -8(%ebp) # incrementer of 4
movl $0, -12(%ebp)
movl %edi, -4(%ebp)
movl %edi, %ecx # outer loop counter
movl %ecx, -20(%ebp) # main loop counter
main_loop:
movl -20(%ebp), %ecx
cmpl $0, %ecx
je end_main_loop
decl %ecx
movl %ecx, -20(%ebp)
movl 12(%ebp), %esi
movl 8(%ebp), %edi
movl %edi, -4(%ebp)
movl %edi, %ecx
movl $0, -8(%ebp)
outer:
movl -4(%ebp), %ecx
cmpl $0, %ecx
#je end_outer
je main_loop
decl %ecx
movl %ecx, -4(%ebp)
movl -8(%ebp), %edx
addl %edx, %esi
movl (%esi), %eax # retrieve data
movl %esi, -12(%ebp) # store addr1
cmpl $0, -4(%ebp)
je yes
addl $4, %esi # next address jump
movl (%esi), %ebx # retrieve next data
movl %esi, -16(%ebp) # store addr2
movl 12(%ebp), %esi # restore base address
cmpl %eax, %ebx
jl less
jmp not_less
less:
xchg %eax, %ebx
movl -12(%ebp), %esi
movl %eax, (%esi)
movl -16(%ebp), %esi
movl %ebx, (%esi)
movl 12(%ebp), %esi # restore base address
not_less:
yes:
movl -8(%ebp), %edx
addl $4, %edx
movl %edx, -8(%ebp)
jmp outer
end_main_loop:
end_outer:
movl %ebp, %esp
popl %ebp
ret
.type int2str, @function
_int2str:
pushl %ebp
movl %esp, %ebp
# store original registers
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
movl 8(%ebp), %eax # original number
movl $0, %ecx # count, for length of the string
movl $10, %edi # the divisor, base
start_conversion:
movl $0, %edx
divl %edi
addl $'0', %edx
pushl %edx
incl %ecx
cmpl $0, %eax
je end_conversion
jmp start_conversion
end_conversion:
movl 12(%ebp), %edx # stores the address of the buffer
start_reversing:
popl %eax
movb %al, (%edx)
incl %edx
decl %ecx
cmpl $0, %ecx
je end_reversing
jmp start_reversing
end_reversing:
movb $0, (%edx) # null terminating character
# retirieve original registers
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %eax
movl %ebp, %esp
popl %ebp
ret
.type printstr, @function
_printstr:
pushl %ebp
movl %esp, %ebp
# store original registers
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
movl $4, %eax
movl $1, %ebx
movl 12(%ebp), %ecx # the string
movl 8(%ebp), %edx
int $0x80
# retirieve original registers
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
movl %ebp, %esp
popl %ebp
ret
.type _exit, @function
_exit:
pushl %ebp
mov %esp, %ebp
pushl %eax
pushl %ebx
movl $1, %eax
movl $0, %ebx
int $0x80
popl %ebx
popl %eax
movl %ebp, %esp
popl %ebp
ret