PowerShell и ЖЖ: аутентификация с «cookie», интерфейс «XML-RPC»

Feb 18, 2023 03:08

Ранее в этой серии постов:
...
17. PowerShell и ЖЖ: аутентификация с «cookie», интерфейс «flat»
18. PowerShell: улучшаю преобразование данных из XML-RPC в хеш-таблицу
19. PowerShell: улучшаю преобразование данных из хеш-таблицы в XML-RPC

Окружение: операционная система «Windows 10», программа-оболочка «PowerShell» версии 7.

0. Подготовка вспомогательных функций

Преобразование хеш-таблицы с параметрами в формат XML-RPC ( подробнее)

function toXMLScalar($val) {
$type = $val.GetType().Name
if ($type -eq "Int32") {$type = "int"} else {
$type = "string"
$val = $val -replace '&', '&'
$val = $val -replace '<', '<'
}
"<{0}>{1}" -f $type, $val
}
function toXMLValue($val) {
$val = if ($val -is [System.Array]) {
toXMLArray $val
} elseif ($val.GetType().Name -eq "Hashtable") {
toXMLStruct $val
} else {
toXMLScalar $val
}
"{0}" -f $val
}
function toXMLArray($arr) {
$values = foreach ($elem in $arr) { toXMLValue $elem }
$values = -join $values
"{0}" -f $values
}
function toXMLMember($key, $val) {
$val = toXMLValue $val
"{0}{1}" -f $key, $val
}
function toXMLStruct($hashT) {
$members = foreach ($key in $hashT.Keys) {
if ($key -ne "mode") {
toXMLMember $key $hashT[$key]
}
}
$members = -join $members
"{0}" -f $members
}
function toXML($hashT) {
$xml = -join @(
''
"LJ.XMLRPC.{0}"
"

{1}"
)
$value = toXMLValue $hashT
$xml -f $hashT["mode"], $value
}

Извлечение данных из формата XML-RPC в хеш-таблицу ( подробнее)

function toHashTable($strXml, $xpath) {
$arr = (Select-Xml -Content $strXml -XPath $xpath).node
$hash = @{}
$res = $arr | ForEach-Object { $hash[$_.name] = $_.value.FirstChild."#text" }
return $hash
}

Получение хеш-суммы строки по указанному алгоритму

function getHash($str, $alg) {
$stringAsStream = [System.IO.MemoryStream]::new()
$writer = [System.IO.StreamWriter]::new($stringAsStream)
$writer.write($str)
$writer.Flush()
$stringAsStream.Position = 0
(Get-FileHash -InputStream $stringAsStream -Algorithm $alg).Hash.ToLower()
}

1. Получение «cookie» от веб-сервера ЖЖ (начало сессии)

$body = @{
mode = "getchallenge"
}
$body = toXML($body)
$Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/xmlrpc" `
-Body $body -Method "POST"
$xpath = "/methodResponse/params/param/value/struct/*"
$params = toHashTable $Response.Content $xpath
$hPass = getHash "пароль" "MD5"
$hResp = getHash ($params["challenge"] + $hPass) "MD5"
$body = @{
mode = "sessiongenerate"
username = "vbgtut"
auth_method = "challenge"
auth_challenge = $params["challenge"]
auth_response = $hResp
}
$body = toXML($body)
$Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/xmlrpc" `
-Body $body -Method "POST"
$xpath = "/methodResponse/params/param/value/struct/*"
$params = toHashTable $Response.Content $xpath
$ljsession = $params["ljsession"]
$ljsession

v2:u31363138:s296:avxfFYeUo73:g95e7b87fd292eb786d17af3490a69d8d1a5c3ebf//1

2. Рабочая часть сессии (на примере получения одного поста журнала)

$body = @{
mode = "getevents"
username = "vbgtut"
auth_method = "cookie"
selecttype = "one"
itemid = 148
ver = 1
}
$body = toXML($body)
$headers = @{
"X-LJ-Auth" = "cookie"
Cookie = "ljsession=$ljsession"
}
$Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/xmlrpc" `
-Body $body -Method "POST" -Headers $headers
$xpath = "/methodResponse/params/param/value/struct/member/value/array/data/value/struct/*"
$params = toHashTable $Response.Content $xpath
$params["url"]

https://vbgtut.livejournal.com/37952.html

3. Завершение сессии, инициированное веб-клиентом

3.1. Завершение сессии по ее идентификатору

$res = $ljsession -match '^.+:.+:.(.+):.+:.+$'
$body = @{
mode = "sessionexpire"
username = "vbgtut"
auth_method = "cookie"
expire = @($Matches[1]) # в массиве можно указать ряд идентификаторов сессий
}
$body = toXML($body)
$headers = @{
"X-LJ-Auth" = "cookie"
Cookie = "ljsession=$ljsession"
}
$Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/xmlrpc" `
-Body $body -Method "POST" -Headers $headers

Нет смысла извлекать данные HTTP(S)-ответа, так как при успешном выполнении удалённой функции «sessionexpire» возвращается пустая хеш-таблица (struct). Проверить, действительно ли завершилась сессия, можно, повторив шаг 2 (рабочую часть сессии), на котором, если сессия завершилась, будет получено сообщение о неправильном пароле.

3.2. Завершение всех открытых сессий для указанного пользователя

$body = @{
mode = "sessionexpire"
username = "vbgtut"
auth_method = "cookie"
expireall = "true" # не массив в отличие от предыдущего блока кода
}
$body = toXML($body)
$headers = @{
"X-LJ-Auth" = "cookie"
Cookie = "ljsession=$ljsession"
}
$Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/xmlrpc" `
-Body $body -Method "POST" -Headers $headers

Нет смысла извлекать данные HTTP(S)-ответа, так как при успешном выполнении удалённой функции «sessionexpire» возвращается пустая хеш-таблица (struct). Проверить, действительно ли завершилась сессия, можно, повторив шаг 2 (рабочую часть сессии), на котором, если сессия завершилась, будет получено сообщение о неправильном пароле.

4. Пример проверки того, что определенная сессия завершена (повтор шага 2)



$ljsession

v2:u31363138:s296:avxfFYeUo73:g95e7b87fd292eb786d17af3490a69d8d1a5c3ebf//1

$body = @{
mode = "getevents"
username = "vbgtut"
auth_method = "cookie"
selecttype = "one"
itemid = 148
ver = 1
}
$body = toXML($body)
$headers = @{
"X-LJ-Auth" = "cookie"
Cookie = "ljsession=$ljsession"
}
$Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/xmlrpc" `
-Body $body -Method "POST" -Headers $headers
$xpath = "/methodResponse/fault/value/struct/*"
$params = toHashTable $Response.Content $xpath
$params["faultString"]

Invalid password

В этом посте - только код и короткие пояснения. Основная часть пояснений уже дана для работы через протокол «flat» в одном из предыдущих постов (принципиально работа через разные интерфейсы ничем не отличается, разница есть в ряде мелочей и в формате отправляемых и получаемых данных).

Инструмент, Образование, Сайтостроение, Программирование, ЖЖ

Previous post Next post
Up