Неподдерживаемый метод - RuCTF 2012 Quals
Неподдерживаемый метод [ctb] / 400 баллов
Заходим браузером по указанному адресу и видим:
Метод действительно не поддерживается.
Пробуем отправить POST запрос и получаем в ответ:
Понимаем, что сервис ожидал получить данные в XML формате. Обращаем внимание на заголовок Server: BaseHTTP/0.3 Python/2.7.2+ и понимаем, что это XML-RPC.
Пишем скрипт для работы с XML-RPC и запрашиваем список поддерживаемых методов
И получаем в ответ:
Запрашиваем ответ с помощью метода get_answer, но, увы, просто так отдавать нам его не хотят.
С помощью метода get_server_var собираем всю полезную информацию про метод get_answer.
А затем получаем бинарный код функции get_answer.
С помощью библиотеки dis в питоне декомпилируем код функции и получаем: get_answer.txt
Восстанавливаем код и получаем:
Немного математической магии и получаем нужные числа: 66666, 12345, 54321, 31337.
Неподдерживаемый метод.
Порт: 8080
Заходим браузером по указанному адресу и видим:
Error response
Error code 501.
Message: Unsupported method ('GET').
Error code explanation: 501 = Server does not support this operation.
Метод действительно не поддерживается.
Пробуем отправить POST запрос и получаем в ответ:
<?xml version='1.0'?>
<methodResponse>
<fault>
<value><struct>
<member>
<name>faultCode</name>
<value><int>1</int></value>
</member>
<member>
<name>faultString</name>
<value><string><class 'xml.parsers.expat.ExpatError'>:no element found: line 1, column 0</string></value>
</member>
</struct></value>
</fault>
</methodResponse>
Понимаем, что сервис ожидал получить данные в XML формате. Обращаем внимание на заголовок Server: BaseHTTP/0.3 Python/2.7.2+ и понимаем, что это XML-RPC.
Пишем скрипт для работы с XML-RPC и запрашиваем список поддерживаемых методов
<?
$method = 'system.listMethods';
$params = null;
$req = xmlrpc_encode_request($method, $params);
$cont = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: text/xml",
'content' => $req
)));
$data = file_get_contents("http://10.0.0.3:8080/", false, $cont);
print_r(xmlrpc_decode($data));
И получаем в ответ:
Array
(
[0] => get_answer
[1] => get_server_var
[2] => system.listMethods
[3] => system.methodHelp
[4] => system.methodSignature
)
Запрашиваем ответ с помощью метода get_answer, но, увы, просто так отдавать нам его не хотят.
get_answer()
-> get_answer() takes exactly 4 arguments (0 given)
get_answer(1,2,3,4)
-> Wrong parameters
С помощью метода get_server_var собираем всю полезную информацию про метод get_answer.
get_server_var('get_answer')
-> <function get_answer at 0x7fb515d096e0>
get_server_var('get_answer.func_code.co_consts')
-> ('Returns an answer if params are correct', 79011, 'Wrong parameters', 1702257177, 'The answer is %s')
get_server_var('get_answer.func_code.co_varnames')
-> ('a', 'b', 'c', 'd', 'key')
А затем получаем бинарный код функции get_answer.
get_server_var('get_answer.func_code.co_code') ->
fAAAfAEAF2QBAGsDAHIfAHQAAGQCAIMBAIIBAG4AAHwAAHwBAHwCABdrAwByPgB0AABkAgCDAQCC
AQBuAAB8AgB8AwAUZAMAawMAcl0AdAAAZAIAgwEAggEAbgAAdAEAfAAAgwEAdAEAfAEAgwEAF3QB
AHwCAIMBABd0AQB8AwCDAQAXfQQAZAQAfAQAFlM=
С помощью библиотеки dis в питоне декомпилируем код функции и получаем: get_answer.txt
Восстанавливаем код и получаем:
def get_answer(a, b, c, d):
if a + b != 79011:
raise ValueError('Wrong parameters')
if b + c != a:
raise ValueError('Wrong parameters')
if c * d != 1702257177:
raise ValueError('Wrong parameters')
key = (str(a) + str(b) + str(c) + str(d))
return 'The answer is %s' % key
Немного математической магии и получаем нужные числа: 66666, 12345, 54321, 31337.
get_answer(66666, 12345, 54321, 31337)
-> The answer is 66666123455432131337