1つのaspxサイトを解析するストーリー

背景



私の若い男性が仕事をしなければならない顧客の要求を処理するためのオンラインシステムが1つあります。 このシステムはおそらく機能的で、管理者に適し、管理などで効率的ですが、日常的に使用するのはどれほど不便です!

  1. ログイン、パスワード、都市を覚えていません。その結果、入力後、デフォルトの都市からすべてのアプリケーションがダウンロードされるのを待ってから、自分のアプリケーションに切り替える必要があります。
  2. すべての必要な情報がアプリケーションの一般的なリストから入手できるわけではありません。 その一部として、アプリケーションの内部を見る必要があり、それぞれが新しいウィンドウで開きます(javascriptがあり、通常のhref属性さえありませんか?)。
  3. この魅力はASPで作成されたため、遷移のたびに、ネットワーク上でそのビューステートを駆動します。
  4. さて、1000ポイントのある1.5のサイトの最小幅は喜びを与えません。


作業の詳細により、携帯電話やモバイルインターネットからシステムにログインすることがあります。

そして、私が彼女と一緒に働いたなら、何も起こらなかったでしょう-私はそれに慣れて、適応しました、そして実際、ボスは熱心です...



物語



私は実際にタイプセッターです。 そして、ウェブ開発者ですが、この方向ではスキルはそれほど高くないので、ワードプレスでまともなウェブサイトを作ります。 あらゆる種類の過酷なcurlリクエストで、これまでに遭遇したことはありません。 そして、aspxサイトでも。

しかし、それは面白いです!

(PHPを使った1か月の夜と眠れぬ夜が数回ありました。そしてもちろん、とても楽しかったです)



最初は、javascriptを使用したクロスドメインクエリの試みがありましたが、何も起こりませんでした。

次に、ti病な発掘調査とファントムjsおよびその他のユーザー行動のエミュレーションを除きます。 しかし、それでも私はまだjsスキルが不足していることがわかりました。

その結果、PHPページからのcurl要求ですべてが機能します。



情報を受け取る


承認は十分に速く、問題なく多かれ少なかれ獲得しました。

最も厄介な問題は、間違ったパスワードエントリの数の制限でした。2回-管理者に連絡して、アクセスを復元します



しかし、目的の都市への移行は頑固に失敗しました。 移行は行われましたが、POST要求はすべてのルールに従って実行されましたが、どこか間違った方向にありました。

preg_matchは非常に多くの文字では正しく機能しないことが判明しました。

ディレクティブはこれからあなたを救います



ini_set("pcre.backtrack_limit", 10000000);
      
      





まず、ページの初期状態を取得し(まだログインしていないため、ログインページに移動します)、そこからビューステートを取り出します。



  $url = 'http://***/Default.aspx'; $content = curlFunction($url); preg_match_all("/id=\"__VIEWSTATE\" value=\"(.*?)\"/", $content, $arr_viewstate); $viewstate = urlencode($arr_viewstate[1][0]);
      
      





ここで、実際のページステータスのキャストを手元に用意して、ユーザー名とパスワードを入力します。

(postdataはページへのリクエストのPOSTパラメーターです。同じfirebugで覗くことができます)。



  $url = 'http://***/Default.aspx?ReturnUrl=%2fHome%2fRoutes.aspx'; $postdataArr = array( '__LASTFOCUS=', '__EVENTTARGET=', '__EVENTARGUMENT=', '__VIEWSTATE='.$viewstate, 'ctl00$cphMainContent$loginBox$loginBox$UserName='.$login, 'ctl00$cphMainContent$loginBox$loginBox$Password='.$password, 'ctl00$cphMainContent$loginBox$loginBox$LoginButton=', ); $postdata = implode('&',$postdataArr); $content = curlFunction($url, $postdata); preg_match_all("/id=\"__VIEWSTATE\" value=\"(.*?)\"/iu", $content, $arr_viewstate); $viewstate = urlencode($arr_viewstate[1][0]);
      
      





最初のリンクはリダイレクトで発行され、curlには設定があるため



 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //   
      
      





ビューステートの結果として必要なページを取得します。



この時点でpreg_replaceを無効にすると問題が発生しましたが、 Habrのおかげで解決策が見つかりました。

あります! これで、目的の都市のアプリケーションに切り替えて解析を行うことができます。



  $url = 'http://***/Home/Routes.aspx'; $postdataArr = array( '__EVENTTARGET=ctl00$cphMainContent$ddlCityID', '__EVENTARGUMENT=', '__LASTFOCUS=', '__VIEWSTATE='.$viewstate, 'ctl00$cphMainContent$ddlCityID='.$city, 'ctl00$cphMainContent$tbConnectionDate='.$date, ); $postdata = implode('&',$postdataArr); $content = curlFunction($url, $postdata);
      
      





あなたがやっていることを最終的に理解したら、すべてが非常に簡単です。最後のステップでビューステートを受け取ったリンクをクリックする必要があります。



情報処理


わかりました、解析を開始します。

最初の経験は正規表現でした。 残念ながら、ホスティングのphpは、複数行の式で何らかの形で非常に奇妙に機能し、どのように説得しようとしても(すべてがLANで機能した)、完全に選択(すべてのオプション)を破りませんでした。



次のステップは、 Simple Html Domライブラリーです。 すべて順調です。リンクをクリックして情報を解析します。1ページの取得には0.9秒かかり、ページ上の5つの入力から同じデータを取得するにはさらに5秒かかります。 このような9つのリンクにアクセスする必要がある場合、すべてが非常に悲しくなります。



グーグル、私たちは読んでいると思う。 のこぎりを見つけました。 簡単で価値がある! 本当に速くて楽しいこと:



  $html = new nokogiri($content); //  input' $RepairNumber = $html->get('#ctl00_cphMainContent_tbRepairNumber')->toArray(); $result['RepairNumber'] = $RepairNumber[0]['value']; //  select' $ConnectionTimeArr = $html->get('#ctl00_cphMainContent_ddlConnectionTime')->toArray(); foreach($ConnectionTimeArr as $e) { foreach($e['option'] as $el) { if(isset($el['selected'])) { $result['ConnectionTime'] = $el['#text'][0]; } } }
      
      







美しさとデザイン


突然、非常に奇妙な問題が発生しました。顧客は明らかな不満を持って、CSS、JS、およびその他の機能を備えていない開発者バージョンを使用しました。 より正確には、彼はそれ使用する方法まったく理解しいませんでした。



XHRリクエストに関する情報を探しています



 // ,   POST- var login = $('#login').val(); var password = $('#password').val(); var val = $('#datePicker').val(); //  var params = 'login=' + encodeURIComponent(login) + '&password=' + encodeURIComponent(password) + '&date=' + encodeURIComponent(date) + '&firstlogin=true'; //       ,  ,   ,    var req = getXmlHttp() req.open('POST', 'script.php', true) req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') req.send(params); //  -    ! $('.dark').fadeIn(); req.onreadystatechange = function() { if (req.readyState == 4) { if(req.status == 200) { // ,     $('.dark').fadeOut(); $('#worker').html(req.responseText); } } }
      
      







利益! ユーザーは喜んで、ユーザーの携帯電話はモバイルインターネット上の膨大なビューステートを追い越す必要性から解放され、手書きページのデザインの管理は多少簡単になります。



PSこのクライアントの助けを借りて、アプリケーションを使用する作業システムのデータを変更することは可能かどうか、彼らは私に尋ねました。 脅威のように思えた...



All Articles