Измените URL-адрес на другой URL-адрес с помощью mitmproxy

Я пытаюсь перенаправить одну страницу на другую, используя mitmproxy и Python. Я могу запустить свой встроенный скрипт вместе с mitmproxy без проблем, но я застреваю, когда дело доходит до изменения URL-адреса на другой URL-адрес. Например, если бы я зашел на google.com, он бы перенаправил на stackoverflow.com.

def response(context, flow):
        print("DEBUG")
        if flow.request.url.startswith("http://google.com/"):
            print("It does contain it")
            flow.request.url = "http://stackoverflow/"

Теоретически это должно работать. Я вижу http://google.com/ в графическом интерфейсе mitmproxy (как GET), но print("It does contain it") никогда не запускается.

Когда я пытаюсь просто поставить flow.request.url = "http://stackoverflow.com" прямо под print("DEBUG"), это тоже не сработает.

Что я делаю не так? Я также пробовал if "google.com" in flow.request.url, чтобы проверить, содержит ли URL-адрес google.com, но это тоже не сработает.

Спасибо


person MortenMoulder    schedule 09.05.2016    source источник
comment
(1) Вы видите вывод «DEBUG»? (2) Ваш запрос на самом деле http:// или https://?   -  person Vasiliy Faronov    schedule 09.05.2016
comment
@VasiliyFaronov Я вижу вывод DEBUG да (у меня есть отдельная функция печати, которая записывает в файл, который я затем tail -f включаю, поскольку графический интерфейс mitmproxy заполняет весь терминал). Это http://, и я тщательно скопировал и вставил весь URL-адрес из графического интерфейса mitmproxy, так что он совпадает на 100%. Очевидно, что google.com и stackoverflow.com — это просто наполнители.   -  person MortenMoulder    schedule 09.05.2016
comment
Альтернативный ответ здесь: stackoverflow.com/questions/24886372/   -  person Dr. Jekyll    schedule 25.07.2016


Ответы (3)


Следующий скрипт mitmproxy будет

  1. Перенаправить запрос с mydomain.com на newsite.mydomain.com
  2. Измените путь метода запроса (предположительно, что-то вроде /getjson? на новый `/getxml
  3. Изменить схему хоста назначения
  4. Изменить порт целевого сервера
  5. Перезаписать заголовок запроса Host, чтобы он претендовал на происхождение

    import mitmproxy
    from mitmproxy.models import HTTPResponse
    from netlib.http import Headers
    def request(flow):
    
        if flow.request.pretty_host.endswith("mydomain.com"):
                mitmproxy.ctx.log( flow.request.path )
                method = flow.request.path.split('/')[3].split('?')[0]
                flow.request.host = "newsite.mydomain.com"
                flow.request.port = 8181
                flow.request.scheme = 'http'
                if method == 'getjson':
                    flow.request.path=flow.request.path.replace(method,"getxml")
                flow.request.headers["Host"] = "newsite.mydomain.com"
    
person loretoparisi    schedule 26.07.2016
comment
у вас есть URL / документация для mitmproxy, как использовать пользовательские модули, подобные этому? - person Ashfaque Ali Solangi; 25.10.2016


Установка атрибута url вам не поможет, так как он просто создается из базовых данных. [EDIT: я был неправ, см. ответ Максимилиана. Однако остальная часть моего ответа все еще должна работать.]

В зависимости от того, чего именно вы хотите добиться, есть два варианта.

(1) Вы можете отправить клиенту настоящий HTTP-ответ перенаправление. Предполагая, что клиент понимает перенаправления HTTP, он отправит новый запрос на указанный вами URL-адрес.

from mitmproxy.models import HTTPResponse
from netlib.http import Headers

def request(context, flow):
    if flow.request.host == 'google.com':
        flow.reply(HTTPResponse('HTTP/1.1', 302, 'Found',
                                Headers(Location='http://stackoverflow.com/',
                                        Content_Length='0'),
                                b''))

(2) Вы можете автоматически перенаправить тот же запрос на другой хост. Клиент этого не увидит, он будет считать, что все еще разговаривает с google.com.

def request(context, flow):
    if flow.request.url == 'http://google.com/accounts/':
        flow.request.host = 'stackoverflow.com'
        flow.request.path = '/users/'

Эти фрагменты были адаптированы из примера, найденного в собственном репозитории mitmproxy на GitHub. . Там есть еще много примеров.

По какой-то причине я не могу заставить эти фрагменты работать в Firefox при использовании с TLS (https://), но, возможно, вам это не нужно.

person Vasiliy Faronov    schedule 09.05.2016
comment
Спасибо за ответ! Все, что мне нужно, это сделать содержимое X похожим на содержимое Y. Поэтому, если я введу website.com на подключенном устройстве, оно должно показать содержимое another-website.com. Изменение хоста, как написано в другом вашем примере, не сработает, так как мне нужно изменить весь URL-адрес. google.com/account работает, а stackoverflow.com/account нет. Понимаете, что я имею в виду? Мне нужно заменить весь URL-адрес на другой URL-адрес. - person MortenMoulder; 09.05.2016
comment
Метод @Snorlax (2) заменяет хост в каждом запрошенном URL-адресе. Это работает для меня. Я использую example.com и stackoverflow.com, и когда я перехожу к http://example.com/users в Firefox, я действительно вижу страницу пользователей Stack Overflow с (относительными) ссылками, указывающими на другие example.com страницы. Может быть, вы можете сказать, какие сайты вы используете? Например, если ваш stackoverflow.com зависит от файлов cookie, способ (2) может не сработать, потому что браузер не будет отправлять stackoverflow.com файлы cookie на google.com, но я не думаю, что вы можете что-то с этим поделать. - person Vasiliy Faronov; 09.05.2016
comment
О, вы имеете в виду, что вам нужно изменить путь в дополнение к хосту? Это легко, просто установите flow.request.path на все, что хотите. - person Vasiliy Faronov; 09.05.2016
comment
Проблема с заменой flow.request.host заключается в том, что пути должны быть точно такими же. Я не хочу этого. Я хочу иметь возможность сказать if url == "example.com": url = "new-example.com. Я знаю, что это возможно, я просто не знаю, как. - person MortenMoulder; 09.05.2016
comment
Все еще недостаточно хорошо. Мне нужно изменить ТОЧНЫЙ URL-адрес на другой ТОЧНЫЙ URL-адрес. anything-goes-here.com/anything-123.html -> google.com/account например. - person MortenMoulder; 09.05.2016
comment
@Snorlax Запрос HTTP/1.1 (к серверу) не включает полный URL-адрес. У него есть хост и путь по отдельности. Если вам нужен способ разделить http://google.com/account на хост и путь, используйте urlparse.urlparse. - person Vasiliy Faronov; 09.05.2016
comment
Таким образом, в основном я бы проверил, равен ли flow.request.host.get_url() моему URL-адресу X, затем я бы установил хост и путь после этого, что по сути похоже на X->Y? - person MortenMoulder; 09.05.2016
comment
@Снорлакс Точно. Но, как я уже сказал, в зависимости от сайта могут быть предостережения, такие как файлы cookie, localStorage, запросы XHR, которые становятся перекрестными и т. д., которые могут помешать правильному отображению результирующей страницы. - person Vasiliy Faronov; 09.05.2016
comment
Это не будет проблемой. Все, что мне в основном нужно сделать, это изменить одну страницу JSON (file.json) на другую страницу JSON, но это немного сложнее, чем просто сделать это, так как мне нужно сделать это на основе пользователя. - person MortenMoulder; 09.05.2016
comment
О да, я обязательно это сделаю, но мне нужно переустановить мой сервер. По какой-то причине mitmproxy продолжает лажать. Как будто я не могу найти mitmproxy.models. Я сделал sudo pip install mitmproxy, но, думаю, мне придется пойти и скомпилировать все это из исходников. Пока я думаю, что это звучит как рабочий план! Вы знаете, что --hypasswd работает? Я заставил его работать и все такое, но вы знаете, как читать имя пользователя? Нравится if username == "something": set path to something else - person MortenMoulder; 09.05.2016
comment
Оно работает! Большое спасибо за помощь! Знаете ли вы, возможно ли заставить текущего пользователя отправить запрос? - person MortenMoulder; 09.05.2016
comment
@Snorlax Я предлагаю вам опубликовать это как отдельный вопрос, эта ветка комментариев уже слишком длинная. - person Vasiliy Faronov; 09.05.2016
comment
Я согласен. Спасибо вам за помощь. - person MortenMoulder; 09.05.2016