Pull to refresh

Анонимный браузер своими руками или Hide your ass yourself

Reading time 4 min
Views 14K
Вступление

Этот небольшой топик расскажет о том, как просто и быстро сделать свой браузер, с небольшими добавками, которые помогут нам остаться анонимным в сети. Всю черную работу за нас сделает Qt, а именно его модуль QtWebKit. Мы лишь добавим в нужные места строки, подменяющие http-заголовки наших http- запросов. Это позволит оставаться анонимными при пассивном анализе http-запросов. Также переопределим navigator, что позволить оставаться анонимными для javascript-ов при активной идентификации. Для определенности обозначим основные параметры, с помощью которых нас можно идентифицировать в сети – вот именно их мы и будем подменять. Первое – это конечно IP адрес, тут все просто – используем прокси. Второе – любые заголовки http-запроса (user-agent будет наиболее интересен: его значение нужно подменять как в заголовках http-запросов, так и в проверке javascript-ами). Также реализуем возможность редактировать и подставлять свои сookies для определенных сайтов, раз уж есть такая возможность. И дополним все это встроенным редактором для подменяемых параметров с возможностью их сохранения для последующего использования.

За основу нашего браузера возьмем класс QWebView, который возьмет на себя работу по загрузке и отображению любых web-страниц.

QWebView* pView = new QWebView;
pView->load(url);


Чтобы иметь доступ ко всем запросам, которые формирует pView, определим свой класс QBotNetworkAccessManager наследуемый от QNetworkAccessManager, создадим объект этого класса и установим его в качестве NetworkManager для pView.

m_NetManage = new QBotNetworkAccessManager;
pView->page()->setNetworkAccessManager(m_NetManage);


Устанавливаем прокси через который будет работать NetworkManager и, соответственно, наш браузер:

//pProxiEdit – поле для ввода прокси в виде IP:Port
QRegExp rx("^\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}:\\d{2,}$")
QString sProxiIP, sPRoxiPort, sTmp;
sTmp = pProxiEdit->text();
if(rx.indexIn(sTmp, 0) != -1) {
int pos = sTmp.indexOf(":");
sProxiIP = sTmp.mid(0, pos);
sPRoxiPort = sTmp.mid(pos + 1, sTmp.size() - pos - 1);
QNetworkProxy* proxy = new QNetworkProxy(QNetworkProxy::HttpProxy, sProxiIP, sPRoxiPort.toUInt());
m_NetManage->setProxy(*proxy);
}


Изменение заголовков http-запросов

Доступ к http-запросам, формируемым нашим браузером, есть в функции

QNetworkReply * QNetworkAccessManager::createRequest ( Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0 ) [virtual protected]

которую нам и нужно переопределить в своем классе QBotNetworkAccessManager.
Переопределяем ее так:

QNetworkReply * QBotNetworkAccessManager::createRequest ( Operation op, const QNetworkRequest & req, QIODevice * outgoingData) {
QNetworkRequest myReq(req);// копируем исходный QNetworkRequest & req
// изменяем необходимые http-заголовки на свои значения
myReq.setRawHeader("User-Agent", sUA.toUtf8());
// и почие заголовки ...
return QNetworkAccessManager::createRequest( op, myReq, outgoingData);
}


Этим способом можно реализовать подмену любых заголовков http-запросов, отсылаемых нашим браузером, на необходимые нам заголовки.
Теперь, нужно чтобы javascript-ами наш браузер тоже определялся нужным образом. Для этого перед загрузкой очередной страницы подредактируем javascript изменив его таким образом, что бы он отправлял на сервер нужную нам информацию. Для этого при смене вида страницы – переопределим navigator как показано ниже, выполнив javascript:

QString sUA = "MY_USER_AGENT";
...
connect(pView, SIGNAL(urlChanged(const QUrl&)), this, SLOT(OnUrlChanged(const QUrl&)));
...
void MainWindow::OnUrlChanged(const QUrl& url) {
QString jScript = QString("var navigator = new Object; navigator.appName = '%1';").arg(sUA);
pUrlEdit->setText(url.toString());
pView->page()->mainFrame()->evaluateJavaScript(jScript);
}


Эту же функцию выполняем перед загрузкой страницы:

...
OnUrlChanged(url);
pView->load(url);
...


Теперь javascript-ом мы видимся также как и при анализе http-заголовков.
image

Работа с cookie

Сохранять cookie и прочую информацию (в данном случае будут только cookie и user-agent) будем в виде вектора структур, определенного ниже:

struct SDataArhive {
QByteArray BaseItemText;
QMap<QByteArray, QByteArray> ChItemText;
};
QVector vDataArhive;

Сохранение cookie и user-agent-а для текущей ссылки происходит следующим образом:

QList ListCookies;
// получаем список cookie для текущей ссылки
ListCookies = pView->page()->networkAccessManager()->cookieJar()->cookiesForUrl(pView->url());
QByteArray sByteAr = "";
SDataArhive strTmp
// преобразуем список cookie в QByteArray,
// для удобства отображения и редактирования
for(int i = 0; i < ListCookies.size(); i++) {
sByteAr += ListCookies[i].name();
sByteAr += "=";
sByteAr += ListCookies[i].value();
if(i < (ListCookies.size() - 1)){
sByteAr += "\n";
}
}
strTmp.ChItemText.insert("cookie", sByteAr);
//----------------------------------------
// User-Aget
sByteAr = sUA.toUtf8();
strTmp.ChItemText.insert("user-agent", sByteAr);
//--------------------------------------
vDataArhive.append(strTmp);

Так же реализуем встроенный редактор cookie и остальной сохраненной информации. Описывать подробно не буду, вид показан на рисунке.
image

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

// получаем текущий QByteArray cookie
QByteArray tmp = vDataArhive[IdxTop].ChItemText[dataIdx];
// преобразуем QByteArray в список cookie
QList ListData = tmp.split('\n');
QList ListCookies;
if(!ListData.isEmpty()) {
for(int i = 0; i < ListData.size(); i++) {
QList cooka = ListData[i].split('=');
if(cooka.size() == 2) {
ListCookies.push_back(QNetworkCookie(cooka[0], cooka[1]));
}
}
if(!ListCookies.isEmpty()){
// устанавливаем cookie для текущей ссылки
pView->page()->networkAccessManager()->cookieJar()->setCookiesFromUrl(ListCookies ,pView->url());
}
}
// установка нового user-agent
sUA = vDataArhive[IdxTop].ChItemText["user-agent"];

Вот и все: наш анонимный браузер готов.

P.S. Идея подобного браузера была подсказана сайтом www.free-lance.ru
, а реализовать помогло чтение документации Qt и форума www.prog.org.ru.
Tags:
Hubs:
+47
Comments 34
Comments Comments 34

Articles