JComScanner - сканер Joomla компонентов

Discussion in 'Уязвимости' started by R0nin, 29 Feb 2012.

  1. R0nin

    R0nin Member

    Joined:
    11 Jul 2010
    Messages:
    261
    Likes Received:
    24
    Reputations:
    8
    ОБНОВЛЕНИЕ: Актуальная версия 1.1
    (http://forum.antichat.ru/showpost.php?p=3043631&postcount=4)

    JComScanner v1.0
    Этот сканер представляет из себя простой Python скрипт, возможно есть способы написать его проще, или улучшить функциональность сканера. Именно на Python я программирую только неделю, так что без претензий господа. Это не сканер безопасности, и не программа для взлома, этот скрипт скажет вам какие именно компоненты установлены на сайте.

    [​IMG]

    Вы должны указать скрипту файл со списком Joomla компонентов, он будет читать по одному и проверять. Простое использование:

    Code:
    ./jscan.py  http://joomla.org  ./mycomponent_list.txt
    или есть возможность запустить с таймаутом, т.е. между подключениями к серверу должно будет пройти определенное время:

    Code:
    ./jscan.py  http://joomla.org  ./mycomponent_list.txt  10
    Перед названием сайта должно быть http://, иначе библиотека urllib2 начнет ругаться. Путь к файлу может быть релативный или абсолютный. Таймаут не обязателен. Аргументы должны задаваться в таком порядке в каком я здесь написал, и никак подругому. Скрипт простой, и там нету каких либо крутых проверок входных данных, т.к. для этого скрипта они в принципе и не нужны.


    Code:
    #!/usr/bin/env python
    
    import sys, time, os
    import urllib2 as u2
    
    if len(sys.argv) < 3 or len(sys.argv) > 4:
    	print "Usage:"   + sys.argv[0] + " <http:url> <component_database.txt>"
    	print "Example:" + sys.argv[0] + " http://joomla.org  ./db.txt"
    	exit()
    
    
    if not os.access(sys.argv[2], os.F_OK):
    	print(  "File " + sys.argv[2] + " does not exist or "
    		+ "you are not permitted to access to the file")
    	exit()
    
    print "[Joomla components scanner by R0nin]\n"
    print "[+] Host:", sys.argv[1], "\n\n"
    with open(sys.argv[2]) as comfile:
    	for line in comfile:
    		line = line.strip("\r\n")
    		req = u2.Request(sys.argv[1] + "/components/" + line)
    		try:
    			u2.urlopen(req)
    		except u2.HTTPError as hr:
    			if hr.code == 404:
    				print "Component: " + line.ljust(50,' ') + "[Not found]"
    		except u2.URLError as ur:
    			print "URL error:", ur.args
    			exit()
    		except ValueError as vr:
    			print "Value error:", vr.args
    			exit()
    		except KeyboardInterrupt as kierr:
    			print "\nInterrupted by user: (CTRL+C or Delete)"
    			exit()
    		except:
    			print "Uknown exception: exit..."
    			exit()
    		else:
    			print "Component: " + line.ljust(50,' ') + "[OK]"
    		try:
    			if len(sys.argv) == 4:
    				time.sleep(int(sys.argv[3]))
    		except KeyboardInterrupt as kierr:
    			print "\nInterrupted by user: (CTRL+C or Delete)"
    			exit()
    


    Скачать базу с названиями компонент: http://pastebin.com/uGGR31LU
    На данный момент база с компонентами состоит из 217 разных компонентов. На самом деле существуют их намного больше, поэтому если решите обновить базу залейта его куда нибудь и скиньте ссылка в этой теме

    !!! Формат файла с названиями очень простой - на каждой строке пишем одно названием компонента.

    Исходник скрипта на PasteBin: http://pastebin.com/VjA5y5HE


    Что планируется:
    - возможность туннелирования
    - более продвинутый механизм сканирования (чтобы не спалить хату) :))
     
    #1 R0nin, 29 Feb 2012
    Last edited: 1 Mar 2012
    3 people like this.
  2. m00c0w

    m00c0w Banned

    Joined:
    25 Dec 2011
    Messages:
    104
    Likes Received:
    14
    Reputations:
    5
    Я такое многопоточным делал, но проверка только по бажным компонентам)
    ---
    "Перед названием сайта должно быть http://, иначе библиотека urllib2 начнет ругаться"

    Что мешает добавлять в самом скрпите, если не стоит 'http://'
    простая проверка :)
     
    #2 m00c0w, 29 Feb 2012
    Last edited: 29 Feb 2012
  3. R0nin

    R0nin Member

    Joined:
    11 Jul 2010
    Messages:
    261
    Likes Received:
    24
    Reputations:
    8
    Год назад, такой многопоточный сканер писал на C, исходники потерял. Многопоточность без использования прокси окажется слишком подозрительной)

    upd:
    Мешает то, что в скрипте будет еще одно не обязательное условие.
     
    #3 R0nin, 29 Feb 2012
    Last edited: 29 Feb 2012
  4. R0nin

    R0nin Member

    Joined:
    11 Jul 2010
    Messages:
    261
    Likes Received:
    24
    Reputations:
    8

    Обновление v1.1

    Changelog!: Программа прошла полной переработкой. Ограничения вставленные на входящие аргументы (имеется ввиду порядок записи или обязательный префикс http) уже не действительны. Добавлены новые функция. Работа с аргументами изменена:​
    Code:
    optional arguments:
      -h, --help  show this help message and exit
      -u U        Remote site URL
      -f F        Joomla components list file
      -t T        Timeout (sec)
      -T T        Randomization timeout (from 0 to N)
      -p P        HTTP Proxy server (PROXY:PORT)(example: 127.0.0.1:1080)
    
    Объясню только один аргумент (остальное и так понятно): -T - это новая функция, таймаут с рандомизацией, т.е. вы задаете число N а скрипт генерирует случайное число от 0 до N и использует как таймоут.​

    Что нового
    1. Поддержка Proxy сервера. К сожалению поддерживается только HTTP прокси (без аутентификации).
    2. Новая функция рандомизации таймаута

    Screenshot
    [​IMG]
    Code:
    #!/usr/bin/env python
    
    import os
    import time
    import random
    import urllib2  as u2
    import argparse as ap
    
    
    sub_url = "/components/"
    #------------------------------------------------------
    # Args set
    def add_args():
    	p = ap.ArgumentParser()
    	p.add_argument("-u", help = "Remote site URL")
    	p.add_argument("-f", help = "Joomla components list file")
    	p.add_argument("-t", help = "Timeout (sec)")
    	p.add_argument("-T", help = "Randomization timeout (from 0 to N)")
    	p.add_argument("-p", help = "HTTP Proxy server (PROXY:PORT)(example: 127.0.0.1:1080)")
    	return p.parse_args(), p
    #------------------------------------------------------
    
    #------------------------------------------------------
    # Timeout
    def timeout(args):
    	if args.T:
    		time.sleep(random.randint(0, int(args.T)))
    	elif args.t:
    		time.sleep(int(args.t))
    		
    #------------------------------------------------------
    #------------------------------------------------------
    # Scan through HTTP server
    def scan_through_proxy(args, com_name, op):
    	try:
    		url = args.u + sub_url + com_name
    		op.open(url)
    	except:
    		raise
    	return True
    #------------------------------------------------------
    #------------------------------------------------------
    # Scan directly
    def scan(args, com_name):
    	try:
    		url = args.u + sub_url + com_name
    		req = u2.Request(url)
    		u2.urlopen(req)		
    	except:
    		raise
    	return True
    #------------------------------------------------------	
    
    a, p = add_args()
    if not a.u or not a.f:
    	p.print_usage()
    	p.exit()
    else:
    	if a.u.find("http://") < 0 and a.u.find("HTTP://") < 0:
    		a.u = "http://" + a.u
    
    if not os.access(a.f, os.F_OK):
    	print "File {} does not exit or permission denied".format(a.f)
    	exit()
    
    
    print "[Joomla components scanner by R0nin]\n"
    print "[+] Host:", a.u
    try:
    	if not a.p:
    		with open(a.f) as com_file:
    			for line in com_file:
    				line = line.strip("\r\n")
    				try:
    					scan(a, line)
    				except u2.HTTPError as he:
    					if he.code == 404:
    						print "Component: " + line.ljust(40,' ') + "[Not found]"
    				except u2.URLError as ue:
    					print "Exception: " + ue.reason
    				else:
    					print "Component: " + line.ljust(40,' ') + "[OK]"
    				timeout(a)
    	else:
    		if a.p.find("http://") < 0 and a.p.find("HTTP://") < 0:
    			a.p = "http://" + a.p
    		prx = u2.ProxyHandler({"http":a.p})
    		op  = u2.build_opener(prx)
    		u2.install_opener(op)
    		
    		print "[Scan via HTTP proxy {}]\n".format(a.p)
    		with open(a.f) as com_file:	
    			for line in com_file:
    				line = line.strip("\r\n")
    				try:
    					scan_through_proxy(a, line, op)
    				except u2.HTTPError as he:
    					if he.code == 404:
    						print "Component: " + line.ljust(40,' ') + "[Not found]"
    				except u2.URLError as ue:
    					print "Exception: " + ue.reason
    				else:
    					print "Component: " + line.ljust(40,' ') + "[OK]"
    				timeout(a)
    except KeyboardInterrupt:
    	print "\nInterrupted by user (CTRL+C or Delete)"
    	exit()
    except:
    	print "Uknown exception: exit..."
    	exit()
    else:
    	print "\n[Sucess]\n"
    	exit()
    

    Скачать исходник с PasteBin:http://pastebin.com/hFGNCFtL
     
    #4 R0nin, 1 Mar 2012
    Last edited: 1 Mar 2012
  5. Lilo

    Lilo Banned

    Joined:
    10 Mar 2009
    Messages:
    462
    Likes Received:
    784
    Reputations:
    313
    бесполезная штука//вручную проще
    за старание +
     
    2 people like this.
  6. R0nin

    R0nin Member

    Joined:
    11 Jul 2010
    Messages:
    261
    Likes Received:
    24
    Reputations:
    8
    Сколько людей столько мнений)


    p.s. оказывается допустил логическую ошибку, там где должно было быть
    Code:
    if exp [b]and[/b] exp: ...
    написал
    Code:
    if exp [b]or[/b] exp: ...
    .
    Ошибку исправил, код перезалил.