Google Apps Script - как войти в систему и получить данные?
Вступление:
Я довольно неопытен, но в последнее время я пытался получить доступ к некоторым данным с веб-сайта с помощью скриптов Google Apps. Однако, чтобы получить доступ к данным, я должен войти на этот сайт. На самом деле раньше было много сообщений о подобных проблемах, но ни одна из них не была очень полезной, пока я не пришел к этому: как получить страницу администратора WordPress с помощью скрипта Google Apps. В принятом ответе был указан способ сохранения файлов cookie и их повторной отправки во втором запросе. Я в основном скопировал и вставил код в свой собственный файл GAS. Поскольку проблема в этом посте заключалась в входе в Wordpress, я сначала попробовал, и это сработало. Мне пришлось удалить оператор if, проверяющий код ответа, потому что возвращалось 200, даже когда я ввел правильную комбинацию. Я не знаю, было ли это просто ошибкой в коде поста или как. В любом случае, я подтвердил, что второй сделанный запрос вернул информацию, как будто я вошел в систему.
Подробности о конкретном сайте:
Фактический веб-сайт, на который я пытаюсь войти, имеет какой-то странный метод хеширования, которого я не видел на других страницах входа. Когда вы нажимаете кнопку отправить, пароль меняется на что-то задолго до перехода на другую страницу. Открывающий тег формы выглядит так:
<form action="/guardian/home.html" method="post" name="LoginForm" target="_top" id="LoginForm" onsubmit="doPCASLogin(this);">
Как видите, у него есть атрибут "onsubmit", который, я думаю, просто запустит "doPCASLogin(this);" когда форма отправлена. Я решил поиграть со страницей, просто введя javascript в адресную строку. Я обнаружил, что выполняю такую команду (после ввода моего имени пользователя и пароля):
javascript: document.forms[0].submit();
не работал Так что я покопался и нашел функцию "doPCASLogin()" в файле JavaScript с именем "md5.js". Я считаю, что md5 - это своего рода алгоритм хеширования, но это не имеет значения. Важная часть doPCASLogin () - это:
function doPCASLogin(form) {
var originalpw = form.pw.value;
var b64pw = b64_md5(originalpw);
var hmac_md5pw = hex_hmac_md5(pskey, b64pw)
form.pw.value = hmac_md5pw;
form.dbpw.value = hex_hmac_md5(pskey, originalpw.toLowerCase())
if (form.ldappassword!=null) {
form.ldappassword.value = originalpw;
}
}
Есть и другие вещи, но я обнаружил, что это не имеет значения для моего логина. Совершенно очевидно, что он просто запускает пароль через другую функцию несколько раз, используя "pskey" (сохраненный в скрытом вводе, различном при каждой перезагрузке) в качестве ключа, и помещает их во входные данные в исходной форме ("dbpw" и "ldappassword" - это скрытые входы, а "pw" - видимый ввод пароля). После этого он представляет. Я нашел эту другую функцию "hex_hmac_md5()", которая на самом деле подключается к целому ряду других функций для хэширования пароля. В любом случае, это не имеет значения, потому что я могу просто вызвать "hex_hmac_md5()" из javascript, который я печатаю в адресной строке. Это рабочий код, который я придумал, я просто разбил строку для удобства чтения:
javascript:
document.forms['LoginForm']['account'].value="username";
document.forms['LoginForm']['pw'].value="hex_hmac_md5(pskey, b64_md5('password');)";
document.forms['LoginForm']['ldappassword'].value="password";
document.forms['LoginForm']['dbpw'].value="hex_hmac_md5(pskey, 'password')";
document.forms['LoginForm'].submit();
Где бы вы ни увидели "имя пользователя" или "пароль", это просто означает, что я ввел свое имя пользователя и пароль в этих местах, но, очевидно, я их удалил. Когда я обнаружил, что это работает, я написал небольшое расширение для Chrome, которое автоматически регистрирует меня при входе на веб-сайт (процесс входа в систему странный, поэтому Chrome не запоминает мои имя пользователя и пароль). Это было хорошо, но это не было моей конечной целью.
Дилемма:
После обнаружения всего этого о хешировании я попытался просто вставить все эти значения в полезную нагрузку HTTP в моем файле GAS, хотя я скептически относился к тому, что это сработает. Это не так, и я подозреваю, что это потому, что значения просто читаются как строки, а javascript фактически не запускается. Это имело бы смысл, потому что запуск реального JavaScript, вероятно, был бы проблемой безопасности. Однако, почему это будет работать в адресной строке? Как примечание, я получаю обратно код ответа 200, и также кажется, что cookie-файл также отправляется обратно, хотя он может быть недействительным. Когда я читаю фактический ответ, это просто страница входа снова.
Я также подумал о том, чтобы попытаться воспроизвести всю функцию в моем собственном коде, увидев следующее: Как программно войти на сайт?, но так как "pskey" отличается при каждой перезагрузке, я думаю, что хеширование должно быть выполнено с новым ключом на втором UrlFetch. Поэтому, даже если я скопировал все функции в мой файл GAS, я не думаю, что смог бы успешно войти в систему, потому что мне нужно было бы знать "pskey", который будет сгенерирован для определенного запроса, ДО фактической отправки запроса, который было бы невозможно. Единственный способ это сработало бы, если бы я мог каким-то образом поддерживать одну страницу и читать ее перед отправкой данных, но я не знаю, как бы я это сделал с помощью GAS.
РЕДАКТИРОВАТЬ: я нашел другой вход, названный "contextData", который совпадает с "pskey", когда страница загружена. Однако, если я войду в систему один раз и посмотрю на запрос POST, сделанный с помощью инструментов Chrome Developers, я смогу скопировать все входные значения, включая "contextData", и могу отправить еще один запрос во второй раз. Используя javascript в адресной строке, это выглядит так:
javascript:
document.forms['LoginForm']['account'].value="username";
document.forms['LoginForm']['pw'].value="value in field that browser sent once";
document.forms['LoginForm']['ldappassword'].value="password";
document.forms['LoginForm'['dbpw'].value="value in field that browser sent once";
document.forms['LoginForm'['contextData'].value="value in field that browser sent once";
document.forms['LoginForm'].submit();
Я могу заходить на сайт столько раз, сколько захочу, независимо от того, что такое "pskey", потому что я отправляю все напрямую, а хеширование не выполняется. Тем не менее, это все еще не работает для меня, так что я застрял. Я должен отметить, что я проверил другие скрытые поля ввода, и я все еще могу успешно войти в систему с помощью JavaScript выше, даже после очистки каждого ввода в форме.
ВОПРОСЫ:
- Правильно ли я предположил, что код, который я отправлял, интерпретировался как строка?
-Почему новый код ниже, который я недавно написал, не работает?
-для дальнейшего использования, как я буду использовать GAS для входа на сайт, такой как Google, где случайно сгенерированная строка отправляется в форме входа в систему и должна быть отправлена обратно?
function getData() {
var loginURL = 'login page';
var dataURL = 'page with data';
var loginPayload = {
'account':'same as in previous code block',
'pw':"same as in previous code block",
'ldappassword':'same as in previous code block',
'dbpw':"same as in previous code block",
"contextData":"same as in previous code block",
};
var loginOptions = {'method':'post','payload':loginPayload,'followredirects':false};
var loginResponse = UrlFetchApp.fetch(loginURL,loginOptions);
var loginHeaders = loginResponse.getAllHeaders();
var cookie = [loginResponse.getAllHeaders()["Set-Cookie"]];
cookie[0] = cookie[0].split(";")[0];
cookie = cookie.join(";");
var dataHeaders = {'Cookie':cookie};
var dataOptions = {'method':'get','headers':dataHeaders};
var dataResponse = UrlFetchApp.fetch(dataURL,dataOptions);
Logger.log(dataResponse);
}
0 ответов
какой-то странный метод хеширования, которого я не видел ни на каких других страницах входа
Этот логин использует хорошо известный алгоритм хеширования MD5 из пароля в кодировке base-64 (обратите внимание, что он использует тот же пароль, но в нижнем регистре, что похоже на доступ к базе данных.dbpw
и имеет возможность отправить текстовую (!) версию пароля для входа в LDAP).
знать "pskey", который будет сгенерирован для конкретного запроса, ДО фактической отправки запроса, что было бы невозможно
pskey
просто хранит ключ, используемый при вычислении подписи HMAC. Ничто не мешает вам жестко закодировать его, прочитать с диска, сгенерировать его или получить с удаленного компьютера в любое время и в любом месте (очевидно, перед вычислением).
запуск фактического javascript, вероятно, будет проблемой безопасности
Хотя запуск ненадежного кода JavaScript действительно является проблемой безопасности, в вашем случае это совсем не то, что произошло. См. Следующий пункт для подробного объяснения причин. Что вам нужно было сделать, так это запустить функции хеширования (в 2020 г.Utilities
сервис предоставляет все необходимое в этом отношении), прежде чем назначать ихloginPayload
свойства.
Правильно ли я предполагал, что отправленный мной код интерпретируется как строка?
Все, что вы заключили в кавычки (одинарные или двойные), рассматривается как последовательность символов. Google Apps Script работает не так, а именно так разработан ECMAScript (на котором он основан). Чтобы выполнить функции "внутри" строки, вам нужно использоватьeval
, но, пожалуйста, никогда не делайте этого.
В 2020 году мне потребовалось время, чтобы вспомнить, что javascript:
протокол имел ввиду. Это единственная причина, по которой ваш код выполняется в первую очередь - вы явно сказали браузеру, что далее следует выполнить код JavaScript. Если кто-то увидит это: пожалуйста, больше не используйте это.
Скрипт Google Apps - это серверный код, который не выполняется в среде браузера, поэтому, даже если бы вы использовали протокол, он не возымел бы эффекта, потому что оценка не проводилась.
почему новый код ниже, который я недавно написал, не работает?
По всем причинам, описанным выше.
для справки в будущем, как мне использовать GAS для входа на такой сайт, как Google, где случайно сгенерированная строка отправляется в форме входа и должна быть отправлена обратно?
Если вы говорите о протоколе аутентификации OAuth / OAuth2.0, вот официально одобренная библиотека, предназначенная именно для этой цели.