Fisrt all,这不是广告。我尝试在铁路车票http://booking.uz.gov.ua/en/的网站上发出POST请求,以了解当前日期是否有门票。但是......有问题。我正在使用VBScript发出请求。要知道在网站上发送的HTTP标头和POST请求,我使用的是Chrome内置开发工具。
这是我的剧本:
Dim URL
Dim URL2
Dim URL3
Dim sRequest
Dim sCookies
'This is web page where I need to enter information.
URL = "http://booking.uz.gov.ua/en/"
'This is path that Chrome shows to send POST request.
URL2 = "http://booking.uz.gov.ua/en/purchase/search/"
'Optional URL, Chrome shows this link near of URL2. I think this is .js that works on info I enter on web site (URL).
'URL3 = "http://booking.uz.gov.ua/i/js/common.138.js"
'POST request that Chrome shows to send.
sRequest ="station_id_from=2200001&station_id_till=2208001&station_from=Kyiv&station_till=Odesa&date_ dep=09.19.2013&time_dep=00%3A00&search="
'Here I'm using GET request to retrieve Set-Cookie Header (SessionID first of all) to reuse in my second POST request.
sCookies = GetSetHeader(URL)
'Here I'm calling function to make POST request.
Result = HTTPPost(URL2, sRequest)
Function GetSetHeader(URL)
Set objhttp = CreateObject("Microsoft.XmlHttp")
objhttp.open "GET", URL, FALSE
objhttp.Send
'I'm getting only SessionID + other cookies that Chrome shows.
GetSetHeader = Left (objhttp.getResponseHeader("Set-Cookie"), 38) & " " & "HTTPSERVERID=server1; _gv_lang=en; __utma=31515437.675496133.1376934004.1376934004.1376934004.1; __utmb=31515437.2.10.1376934004; __utmc=31515437; __utmz=31515437.1376934004.1.1.utmcsr= (direct)|utmccn=(direct)|utmcmd=(none)"
End Function
Function HTTPPost(URL2, sRequest)
'Header I just took from Chrome.
Set objhttp = CreateObject("Microsoft.XmlHttp")
objHTTP.open "POST", URL2, false
objHTTP.setRequestHeader "Connection", "keep-alive"
objHTTP.setRequestHeader "Host", "booking.uz.gov.ua"
objHTTP.setRequestHeader "Connection", "keep-alive"
objHTTP.setRequestHeader "Content-Length", "Len(Request)"
objHTTP.setRequestHeader "GV-Token", "64214392f178b9f91e3b61a069915cd1"
objHTTP.setRequestHeader "Origin", "http://booking.uz.gov.ua"
objHTTP.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objHTTP.setRequestHeader "GV-Unique-Host", "1"
objHTTP.setRequestHeader "GV-Ajax", "1"
objHTTP.setRequestHeader "GV-Screen", "1366x768"
objHTTP.setRequestHeader "GV-Referer", "http://booking.uz.gov.ua/en/"
objHTTP.setRequestHeader "Accept", "*/*"
objHTTP.setRequestHeader "Referer", "http://booking.uz.gov.ua/en/"
objHTTP.setRequestHeader "Accept-Encoding", "gzip,deflate,sdch"
objHTTP.setRequestHeader "Accept-Language", "ru-RU,ru;q=0.8,en- US;q=0.6,en;q=0.4"
'Here I use cookies retrieved with first GET request.
objHTTP.setRequestHeader "Cookie", "sCookies"
objHTTP.send sRequest
'I use this msg to check that right cookies send with POST request.
WScript.Echo sCookies
HTTPPost = objHttp.responseText
'Write answer to TXT file.
Set FSO = CreateObject("Scripting.FileSystemObject")
Set oFile = FSO.OpenTextFile("D:\Results.txt", 2, True)
oFile.Write(objHttp.responseText)
oFile.Close
Set oFile = Nothing
Set FSO = Nothing
end Function
我不能让我的脚本工作。如果我使用URL2发送请求,我会得到空的TXT文件。如果我使用URL3 - Chrome向我显示的脚本路径 - 发送请求,我只会在TXT文件中收到common.138.js的内容。但我希望收到JSON类型的信息,如Chrome响应中所示。
我注意到了什么, 首先,如果刷新网站,并尝试重新发送旧请求,我给我一个错误:
NetworkError:400错误请求 - http://booking.uz.gov.ua/en/purchase/search/“
可能是因为SessionID发生了变化。
其次,我不能简单地写站名,我需要从下拉列表中选择它(当在UI模式下使用此站点时)。或者我收到错误 - 从下拉列表中选择一个出发点。
第三,如果尝试通过简单地点击网站上的按钮来发送请求进行搜索,我会收到错误状态代码:400 Bad Request。我认为SessionID的时间已过期。
有一个使用InternetExplorer.Application系统对象的工作脚本,但它没有决定权。我希望通过发送请求来使其工作。将来想尝试在php上做(作为学习过程的一部分)。
也许这是像我这样的人的某种防御?有一种方法可以使我的脚本工作吗?也许SessionID在GET和POST请求之间发生变化?或者也许VBScript无法解决它,我需要PHP,例如???
我不知道如何解决这个问题。请帮帮我。无法入睡。不能吃。非常感谢。
答案 0 :(得分:5)
您收到“400”,因为您向UZ网站发送了错误的 GV-Token 标头。 最终 GV-token 是某个会话相关变量的md5(会话通过 _gv_sessid Cookie识别)。
此令牌在JavaScript中进行模糊处理,并驻留在页面正文中,如
...
$$_.$_=($$_.$_=$$_+"")[$$_.$_$]+($$_._$=$$_.$_[$$_.__$])+($$_.$$=($$_.$+"")[$$_.__$])+((!$$_)+"")[$$_._$$]+($$_.__=$$_.$_[$$_.$$_])
...
评估为
之类的内容localStorage.setItem('gv-token',4619709a341b4ffdacce3dafd2f85af3)
然后进行所有UZ Ajax请求。
所以我希望你快乐反混淆:))(不适合弱者)
PS还要确保通过应用配置或反射打开.NET useUnsafeHeaderParsing 。
UPD:正如我所看到的,这个话题仍然存在,所以我制作了反混淆代码 - 它似乎是基本的正则表达式&字符串搜索和替换就足够了。假设您在 pageHTML 中有UZ起始页HTML,那么为了让您的工作变得有用,您需要在C#中使用(无效的检查):
混淆代码包含一些标记,每个标记的计算结果为0到F的十六进制数,它们可以直接替换。这是一本对应词典:
var subsitutes = new Dictionary<string, string>
{
{"$$_.$$$", "7"},
{"$$_.$$$$", "f"},
{"$$_.$$$_", "e"},
{"$$_.$$_", "6"},
{"$$_.$$_$", "d"},
{"$$_.$$__", "c"},
{"$$_.$_$", "5"},
{"$$_.$_$$", "b"},
{"$$_.$_$_", "a"},
{"$$_.$__", "4"},
{"$$_.$__$", "9"},
{"$$_.$___", "8"},
{"$$_._$$", "3"},
{"$$_._$_", "2"},
{"$$_.__$" ,"1"},
{"$$_.___", "0"},
};
然后通过使用正则表达式,我们得到了混淆了我们在
中所涉及的代码的一部分var scramble = Regex.Match(pageHTML, @"\$\$_\.\$\(\$\$_\.\$\((.*)\)\(\)\)\(\);");
并将上述令牌替换为其真实含义
var keysSorted = subsitutes.Keys.OrderByDescending(key => key.Length);
var halfBakedDeobfuscated = keysSorted.Aggregate(scramble.Groups[1].Value, (current, key) => current.Replace(key, subsitutes[key]));
几乎完成了,切掉了一些垃圾
var start = Regex.Escape(new string(new[] { '"', '\\', '\\', '\\', '"', ',', '\\', '\\', '"', '+' }) + "4+0+" + new string(new[] { '\"', '\\', '\\', '\\', '\"', '\"', '+' }));
var end = Regex.Escape(new string(new[] { '+', '"', '\\', '\\', '\\', '"', ')' }));
var core = Regex.Match(halfBakedDeobfuscated, start + "(.*)" + end).Groups[1].Value;
现在核心包含几乎干净的gvToken版本,例如7+0+f+a+7+7+9+8+5+7+e+b+3+3+a+8+3+c+7+8+3+b+d+d+e+f+4+8+7+7+f+7
最后一步是删除这些+
符号
var gvToken = string.Join(string.Empty, core.Split('+'));
最后, gvToken 包含您需要提供给UZ网站的内容 - 类似70fa779857eb33a83c783bddef4877f7
的字符串。
没有JS库,当然也不需要InternetExplorer。
答案 1 :(得分:1)
你在这里弄错了:
objHTTP.setRequestHeader“Content-Length”,“Len(Request)”
应该是:
objHTTP.setRequestHeader“Content-Length”,Len(请求)
答案 2 :(得分:0)
有趣的是,需要使用 InternetExplorer.Application ,例如list powershell代码:
$erroractionpreference = "Continue"
$ie = New-Object -ComObject "InternetExplorer.Application"
$ie.navigate("http://booking.uz.gov.ua/en/")
$ie.visible = $true
sleep 5
while($ie.ReadyState -ne 4) {start-sleep -m 100}
$ie.document.getElementByID("station_id_from").Value = "2200001"
$ie.document.getElementByID("station_id_till").Value = "2208001"
$ie.document.getElementsByName("station_from").Item(1).Value = "Kyiv"
$ie.document.getElementsByName("station_till").Item(1).Value = "Odesa"
$ie.document.getElementByID("date_dep").Value = "12.26.2014"
$ie.document.getElementByID("time_dep").Value = "00:00"
$ie.document.getElementByID("search").Click()
Cookie,包括 GV-Token ,在这种情况下无需转让。我认为,有一种方法可以在没有 InternetExplorer.Application 的情况下编写,但可以使用您的代码模拟浏览器。需要探索它。