From f87632f56c16f80fec532f13e7624c315e562063 Mon Sep 17 00:00:00 2001
From: Damien Regad <dregad@mantisbt.org>
Date: Mon, 29 Dec 2014 23:05:05 +0100
Subject: [PATCH 1/3] Generate a unique CAPTCHA for a given private key
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Prior to this, the code would be the same but the displayed CAPTCHA
would vary slightly with each call to make_captcha_img.php, allowing an
attacker unlimited attempts to train their OCR software to decode the
image.

By seeding the random number generator, we ensure that the generated
CAPTCHA is always the same for a given private key.

The commit also removes several unnecessary calls to srand().

This issue was reported by Florent Daignière (nextgens).

Fixes #17984
---
 make_captcha_img.php | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/make_captcha_img.php b/make_captcha_img.php
index 2bf3734..28391d3 100644
--- a/make_captcha_img.php
+++ b/make_captcha_img.php
@@ -149,6 +149,8 @@
 
 			function make_captcha( $private_key )
 			{
+				srand( session_get( CAPTCHA_KEY ) );
+
 				if($this->debug) echo "\n<br />-Captcha-Debug: Generate private key: ($private_key)";
 
 				// create Image and set the apropriate function depending on GD-Version & websafecolor-value
@@ -182,17 +184,12 @@
 					if($this->debug) echo "\n<br />-Captcha-Debug: Fill background with noise: (".$this->nb_noise.")";
 					for($i=0; $i < $this->nb_noise; $i++)
 					{
-						srand((double)microtime()*1000000);
 						$size	= intval(rand((int)($this->minsize / 2.3), (int)($this->maxsize / 1.7)));
-						srand((double)microtime()*1000000);
 						$angle	= intval(rand(0, 360));
-						srand((double)microtime()*1000000);
 						$x		= intval(rand(0, $this->lx));
-						srand((double)microtime()*1000000);
 						$y		= intval(rand(0, (int)($this->ly - ($size / 5))));
 						$this->random_color(160, 224);
 						$color	= $func2($image, $this->r, $this->g, $this->b);
-						srand((double)microtime()*1000000);
 						$text	= chr(intval(rand(45,250)));
 						if(count ($this->TTF_RANGE)>0){
 							@ImageTTFText($image, $size, $angle, $x, $y, $color, $this->change_TTF(), $text);
@@ -225,11 +222,8 @@
 				for($i=0, $x = intval(rand($this->minsize,$this->maxsize)); $i < $this->chars; $i++)
 				{
 					$text	= utf8_strtoupper(substr($private_key, $i, 1));
-					srand((double)microtime()*1000000);
 					$angle	= intval(rand(($this->maxrotation * -1), $this->maxrotation));
-					srand((double)microtime()*1000000);
 					$size	= intval(rand($this->minsize, $this->maxsize));
-					srand((double)microtime()*1000000);
 					$y		= intval(rand((int)($size * 1.5), (int)($this->ly - ($size / 7))));
 					$this->random_color(0, 127);
 					$color	=  $func2($image, $this->r, $this->g, $this->b);
@@ -270,11 +264,8 @@
 
 			function random_color($min,$max)
 			{
-				srand((double)microtime() * 1000000);
 				$this->r = intval(rand($min,$max));
-				srand((double)microtime() * 1000000);
 				$this->g = intval(rand($min,$max));
-				srand((double)microtime() * 1000000);
 				$this->b = intval(rand($min,$max));
 			}
 
@@ -283,7 +274,6 @@
 				if(count($this->TTF_RANGE) > 0){
 					if(is_array($this->TTF_RANGE))
 					{
-						srand((float)microtime() * 10000000);
 						$key = array_rand($this->TTF_RANGE);
 						$this->TTF_file = $this->TTF_folder.$this->TTF_RANGE[$key];
 					}
-- 
1.9.1

