# 課題 作業メモ ## 課題3 今回は難しそうで放置してしまっていたのですが、できるところまではやってみようと思います - brew install jq - OpenTitechAppでwsTokenを取得 ### 課題3.1 [[macOS][iOS] パケットトレースツール「Charles」を使用してiOSデバイスの生の送受信データを確認する](https://dev.classmethod.jp/articles/getting-packet-trace-with-charles/) - Port: 8888 - Local IP Address: - en0: `192.168.1.10` - en1: `192.168.1.6` - en1で ![](https://i.imgur.com/mv3HwMt.png) 色々動かして出たログを export session → JSON session File (.chlsj)に保存してみたけど... ![](https://i.imgur.com/BgHEc5O.png) ![](https://i.imgur.com/8WEkisT.png) 見えない Decodeができない ![](https://i.imgur.com/jI6NIQB.png) これはHTTPS通信の暗号化によるものだった さっきの[記事](https://dev.classmethod.jp/articles/getting-packet-trace-with-charles/)の「SSL通信の中身を見たい場合は、Charlesの証明書をインストールします。」の部分を飛ばしたのが原因 証明書をインストールしてから諸々の作業をすると ![](https://i.imgur.com/zeJaSPr.png) 出てくるようになった iPhoneで動かしたのは - T2SCHOLAアプリを開く - 講義資料を見に行く 有機高分子化学→6/17 2回目→"有機高分子化学2 資料"(PDF) - 自分のプロファイルを見に行く | アプリ開いた|講義資料みた| |:---:|:---:| |![](https://i.imgur.com/kMp61OD.png)|![](https://i.imgur.com/xvNNb9p.png)| ということで、MoodleのUserIDを取得しているのは /webservice/rest/server.php の `core_webservice_get_site_info` 講義資料などを取得しているのは同じく/webservice/rest/server.php の `core_course_get_contents` ### 課題3.2 通信の通りにcURLしてみる ``` -d "moodlewssettingfilter=true&moodlewssettingfileurl=true&wsfunction=core_webservice_get_site_info&wstoken=..." "https://t2schola.titech.ac.jp/webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_webservice_get_site_info" ``` とJSONで色々帰ってきた パイプでjqに渡すと ![](https://i.imgur.com/X8VNc7I.png) 良い感じ まとめると ```shell= ID=$( curl -s -X POST -d "wsfunction=core_webservice_get_site_info" \ -d "wstoken=63a2d4cc280d4fc7542e5d906021dcbc" \ -d "moodlewsrestformat=json" \ "https://t2schola.titech.ac.jp/webservice/rest/server.php" \ | jq '.userid' ) echo "UserID: "$ID ``` ### 課題3.3 https://docs.moodle.org/dev/Web_service_API_functions から探す assignment で検索をかけると`mod_assign_get_assignments`が出てきた とりあえず`wsfunction`をこれに書き換えて実行させてみると... ![](https://i.imgur.com/wfUz8Mn.png) それっぽい `courses`内の各講義の`assignments`の`name`を持ってくれば良さそうなので ```| jq '.courses[].assignments[].name'``` で良い感じ まとめると ```shell= curl -s -X POST -d "wsfunction=mod_assign_get_assignments" \ -d "wstoken=63a2d4cc280d4fc7542e5d906021dcbc" \ -d "moodlewsrestformat=json" \ "https://t2schola.titech.ac.jp/webservice/rest/server.php" \ | jq '.courses[].assignments[].name' ``` で ![](https://i.imgur.com/lLNoR7R.png) --- ## 課題2 https://hackmd.io/@nanashiki/rJFjsqPKY 保存したファイルの中から ```htmlmixed= <tr> <th align="left" bgcolor="#6699CC"></th> <th bgcolor="#6699CC"></th> <td bgcolor="#6699CC"> <div class="col-sm-7 control-align">115777</div> </td> </tr> <tr> <th align="left" bgcolor="#6699CC">[A,7]</th> <th bgcolor="#6699CC"></th> <td bgcolor="#6699CC"> <div class="col-sm-7"><div class="inner-addon left-addon"> <i class="glyphicon glyphicon-lock"></i> <INPUT TYPE="password" NAME="message3" VALUE="" SIZE="32" MAXLENGTH="200" class="form-control" ng-model="password" placeholder="Password" ></div></div> </td> </tr> <tr> <th align="left" bgcolor="#6699CC">[B,3]</th> <th bgcolor="#6699CC"></th> <td bgcolor="#6699CC"> <div class="col-sm-7"><div class="inner-addon left-addon"> <i class="glyphicon glyphicon-lock"></i> <INPUT TYPE="password" NAME="message4" VALUE="" SIZE="32" MAXLENGTH="200" class="form-control" ng-model="password" placeholder="Password" ></div></div> </td> </tr> <tr> <th align="left" bgcolor="#6699CC">[I,1]</th> <th bgcolor="#6699CC"></th> <td bgcolor="#6699CC"> <div class="col-sm-7"><div class="inner-addon left-addon"> <i class="glyphicon glyphicon-lock"></i> <INPUT TYPE="password" NAME="message5" VALUE="" SIZE="32" MAXLENGTH="200" class="form-control" ng-model="password" placeholder="Password" ></div></div> </td> </tr> ``` で正規表現を使って[A,7]、[B,3]、[I,1]を抽出するのが目標。正規表現自体はGASのエゴサで書いたことがあった。[正規表現チートシート](https://murashun.jp/article/programming/regular-expression.html)や[チェッカー](https://weblabo.oscasierra.net/tools/regex/)を見ながら書くと `\[[A-J],[1-7]\]` あっさり書けた。あとはファイルを指定して検索する方法。 - `grep`で正規表現が書けそう:`grep -e '\[[A-J],[1-7]\]' $FILEPATH` - これだけだと行そのまま抽出: ```html <th align="left" bgcolor="#6699CC">[A,7]</th> <th align="left" bgcolor="#6699CC">[B,3]</th> <th align="left" bgcolor="#6699CC">[I,1]</th> ``` なので`awk`を使えば良さそう。`|`で渡した後は`,`で区切り$1の末尾と$2の先頭があれば良いので[調べて](https://atmarkit.itmedia.co.jp/ait/articles/1805/25/news035.html)(出力の区切り文字も変えて)\ `grep -e '\[[A-J],[1-7]\]' $FILEPATH | awk -F'[,]' -v 'OFS=' '{print substr($1, length($1)),substr($2, 1, 1)}'` とすると望みのものが得られた。 ## 課題2の回答 以上の話から、次の2行で現在のマトリクスが出力できる。 ```shell= read FILEPATH grep -e '\[[A-J],[1-7]\]' $FILEPATH | awk -F'[,]' -v 'OFS=' '{print substr($1, length($1)),substr($2, 1, 1)}' ``` --- ## 課題1 https://hackmd.io/@nanashiki/rJ3S10qPY curlの前提知識:TwitterのAPIの[仕様が書かれたページ](https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent)で見たことある 試しに`curl "https://api.twitter.com/2/tweets/search/recent?query=from%3Aco_planar" -H "Authorization: Bearer [ここにToken]"`と打つといつも見てるレスポンスが帰ってきた [Qiitaの記事](https://qiita.com/takayukioda/items/edf371b3566bea64d046)を読んだ。-H は HTTP の Request Header への情報の追加だった --- ここまでで課題1が分かった。 `curl "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=userpass_key&AUTHMETHOD=UserPassword"` でポータルの最初のログインページが帰ってきた。 `curl -o portal.html "https://...` とオプションを残してページを保存した --- `portal.html`の中でformタグを探すと... `<FORM NAME="login" METHOD="POST" AUTOCOMPLETE="off" ACTION="https://portal.nap.gsic.titech.ac.jp/GetAccess/Login" onSubmit="javascript:{ return idgisSetRedirectionCookie( this ); }">` 学籍番号やパスワードを打つ部分は `<INPUT TYPE="text" NAME="usr_name" VALUE="" SIZE="32" MAXLENGTH="255" class="form-control" ng-model="username" placeholder="Account" >` `<INPUT TYPE="password" NAME="usr_password" VALUE="" SIZE="32" MAXLENGTH="32" class="form-control" ng-model="password" placeholder="Password" >` HTMLのformの挙動は以前TweetDeckもどきを作った時に見た ヒントを1つずつ見ていくことにする HTMLのフォームの挙動は前にも見たことがある、今回のも開発者画面で見ると色々飛んでた - Request URL: https://portal.nap.gsic.titech.ac.jp/GetAccess/Login - Request Method: POST - Status Code: 302 Found - ... - usr_name: *** - usr_password: *** - CSRFFormToken: *** 最後のCSRF(対策)Tokenについて調べると - フォーム送信前にワンタイムトークンを生成 - フォーム送信ページにhiddenで生成したトークンを埋め込む - リクエスト送信先でセッションに格納されたトークンとリクエストとして送られてきたトークンが一致するか確認 だそう `portal.html`をよく見るとformタグ内の最後の方に`<input type='hidden' name=...>`がたくさんある、最後に`CSRFFormToken`もあるのでこれを使えば良さそう Cookieの中身が知りたいので`curl -c cookie.txt -o portal.html "https://...` とオプション付けてみると ``` # Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. #HttpOnly_portal.nap.gsic.titech.ac.jp FALSE /GetAccess TRUE 0 JSESSIONID ****** ``` この`JSESSIONID`は使う必要がありそう 最後にredirectについて。Status Codeが`302 Found`で転送先がlocationにあるらしい。さっきの開発者画面のもので見ると`Location: https://portal.nap.gsic.titech.ac.jp/webap/rt?refurl=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList`に飛んでいるらしい。curlに`-L`を足せば良さそう --- ここまでを踏まえて課題2。開発者画面で見たものをとりあえず全て入れる。bodyの方は`portal.html`のFORMタグの各inputを網羅する `curl -X POST -H [Header] -d [data] [URL]`で出来そう - Header - Content-Type: application/x-www-form-urlencoded - Cookie: JSESSIONID=$SESSIONID - Body - `"usr_name=$USERNAME&usr_password=$PASSWORD&OK=++++OK++++&AUTHTYPE=&HiddenURI=https%3A%2F%2Fportal.nap.gsic.titech.ac.jp%2FGetAccess%2FResourceList&GARESOURCEID=resourcelistID2&Template=userpass_key&AUTHMETHOD=UserPassword&LOCALE=ja_JP&CSRFFormToken=$TOKEN"`\ 開発者画面で見たものそのまま - pageGenTime だけ消した (入れたらtime limit exceededが出るので) で ```shell= read USERNAME read PASSWORD read TOKEN curl -v -L -o response1.html -X POST -b cookie1.txt -d "usr_name=$USERNAME&usr_password=$PASSWORD&OK=++++OK++++&AUTHTYPE=&HiddenURI=https%3A%2F%2Fportal.nap.gsic.titech.ac.jp%2FGetAccess%2FResourceList&GARESOURCEID=resourcelistID2&Template=userpass_key&AUTHMETHOD=UserPassword&LOCALE=ja_JP&CSRFFormToken=$TOKEN" "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login" ``` ... さっきとほぼ同じ(パスワード入力)ページが出た、コードは302でなく200、ページ最上部で ```htmlembedded= <br> <center> <font color=red>ERROR: You can only login from this page.</font> </center> <br> ``` と言われてしまった。formタグの場所にちゃんと送ったんだけど onSubmitの中身の関数も見てみるが分からない(開発者画面の方でもAUTHTYPEは空白のまま)、関数の結果(AUTHTYPEをCertにするなど)を入れても変わらず --- 試したこと - POST先が違う...? `https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=idg_key&AUTHMETHOD=IG&GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP&LOCALE=ja_JP&GAREASONCODE=13&GAIDENTIFICATIONID=UserPassword&GARESOURCEID=resourcelistID2&GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&Reason=13&APPID=resourcelistID2&URI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList`に直接 - 確かに302は出る - < HTTP/1.1 302 Found - < Date: Sun, 14 Nov 2021 01:02:41 GMT - < Server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k - < Location: https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&LOCALE=ja_JP&AUTHMETHOD=CERTIFICATE&GARESOURCEID=resourcelistID2&Template=idg_key&pageGenTime=1636851761013&GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP - ...LibreSSL SSL_read: error:1401E410:SSL routines:CONNECT_CR_FINISHED:sslv3 alert handshake failure, errno 0 - 多分違う - Chromeの開発者画面を見るに - https://portal.nap.gsic.titech.ac.jp/GetAccess/Login → 302 Found - → https://portal.nap.gsic.titech.ac.jp/webap/rt?refurl=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList → 302 Found - → https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList → 302 Found - → https://portal.nap.gsic.titech.ac.jp/portal.pl?GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP&LOCALE=ja_JP&GAREASONCODE=13&GAIDENTIFICATIONID=UserPassword&GARESOURCEID=resourcelistID2&GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&Reason=13&APPID=resourcelistID2&URI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList → 302 Found - → https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=idg_key&AUTHMETHOD=IG&GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP&LOCALE=ja_JP&GAREASONCODE=13&GAIDENTIFICATIONID=UserPassword&GARESOURCEID=resourcelistID2&GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&Reason=13&APPID=resourcelistID2&URI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList → 200 OK - **一向に https://portal.nap.gsic.titech.ac.jp/GetAccess/Login で302 Foundが出ない。** - ブラウザで打つ時との違い - Cookieに`AUTH_SESSION_ID`と`STYLEINDEX`が無い でも元々ない - `pageGenTime`が無い 仕方ないので入力を足す - 結果は変わらず < HTTP/1.1 200 OK - -Lは付けてるがそういう問題でなく出ない - `You can only login from this page.`しか情報がない。わからず - POSTしてるのはcurl -vから \> POST /GetAccess/Login HTTP/1.1 \> Host: portal.nap.gsic.titech.ac.jp \> User-Agent: curl/7.77.0 \> Accept: \*/\* \> Cookie: JSESSIONID=[ここにID] \> Content-Length: [ここに長さ] \> Content-Type: application/x-www-form-urlencoded \> \} [\*\* bytes data] で、ここは想定通り。 - (11/16) 学内でアクセス:変化なし それはそう --- 11/28 試験も終わったので再開 とりあえずSafariが送っているデータを全部入れてみる、User-Agentも変えちゃう(減らすのは後でできる) ```shell= curl -v -L -o response.html -b cookie1.txt -c cookie1.txt \ -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" \ -e "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=userpass_key&AUTHMETHOD=UserPassword" \ -H "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \ -H "Accept-Encoding:gzip,deflate,br" \ -H "Accept-Language:ja" \ -H "Connection:keep-alive" \ -H "Origin:https%3A%2F%2Fportal.nap.gsic.titech.ac.jp" \ -d ... ``` すると実行に時間がかかりログも多くなって ``` > POST /GetAccess/Login HTTP/1.1 < HTTP/1.1 302 Found < Location: https://portal.nap.gsic.titech.ac.jp/webap/rt?refurl=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList > GET /webap/rt?refurl=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList HTTP/1.1 < HTTP/1.1 302 Found < Location: https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList > GET /GetAccess/ResourceList HTTP/1.1 < HTTP/1.1 302 Found < Location: https://portal.nap.gsic.titech.ac.jp/portal.pl?GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP&LOCALE=ja_JP&GAREASONCODE=13&GAIDENTIFICATIONID=UserPassword&GARESOURCEID=resourcelistID2&GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&Reason=13&APPID=resourcelistID2&URI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList > GET /portal.pl?GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP&LOCALE=ja_JP&GAREASONCODE=13&GAIDENTIFICATIONID=UserPassword&GARESOURCEID=resourcelistID2&GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&Reason=13&APPID=resourcelistID2&URI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList HTTP/1.1 < HTTP/1.1 302 Found < Location: https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=idg_key&AUTHMETHOD=IG&GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP&LOCALE=ja_JP&GAREASONCODE=13&GAIDENTIFICATIONID=UserPassword&GARESOURCEID=resourcelistID2&GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&Reason=13&APPID=resourcelistID2&URI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList > GET /GetAccess/Login?Template=idg_key&AUTHMETHOD=IG&GASF=CERTIFICATE,IG.GRID,IG.TOKENRO,IG.OTP&LOCALE=ja_JP&GAREASONCODE=13&GAIDENTIFICATIONID=UserPassword&GARESOURCEID=resourcelistID2&GAURI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList&Reason=13&APPID=resourcelistID2&URI=https://portal.nap.gsic.titech.ac.jp/GetAccess/ResourceList HTTP/1.1 < HTTP/1.1 200 OK ``` となり、response.htmlにマトリクス認証コードが現れた。随分悩んでたけどなんかできた。ログたくさん出たとき感動した オプションを減らしていく。 - -A:消せた - -e "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=userpass_key&AUTHMETHOD=UserPassword":消したら200 OKすぐ帰ってきた。Refererが大事だったらしい - 他にも消せるものはあったが不要なものでもないので残しておく --- ## 課題1の回答 以上の話を踏まえて、 課題1 ```shell= curl "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=userpass_key&AUTHMETHOD=UserPassword" ``` でログインページが標準出力される(長いので-o portal.htmlなどする) 課題2 まず課題1の回答を改変した次のコード ```shell= curl -c cookie.txt -o portal.html \ "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=userpass_key&AUTHMETHOD=UserPassword" ``` を実行しCookieを `cookie.txt` に保存、加えてresponseを `portal.html`に保存。`portal.html` の179行目の`pageGenTime`と188行目の`CSRFFormToken`を控えておく。 次に ```shell= read USERNAME read PASSWORD read TIME read TOKEN curl -L -b cookie.txt -c cookie.txt \ -e "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login?Template=userpass_key&AUTHMETHOD=UserPassword" \ -H "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \ -H "Accept-Encoding:gzip,deflate,br" \ -H "Accept-Language:ja" \ -H "Connection:keep-alive" \ -d "usr_name=$USERNAME&usr_password=$PASSWORD&OK=++++OK++++&AUTHTYPE=&HiddenURI=https%3A%2F%2Fportal.nap.gsic.titech.ac.jp%2FGetAccess%2FResourceList&GARESOURCEID=resourcelistID2&Template=userpass_key&AUTHMETHOD=UserPassword&pageGenTime=$TIME&LOCALE=ja_JP&CSRFFormToken=$TOKEN" \ "https://portal.nap.gsic.titech.ac.jp/GetAccess/Login" ``` を実行。入力は ``` 学籍番号 パスワード pageGenTime CSRFFormToken ``` これでマトリクスコードの入力ページが標準出力される(長いので-o response.htmlなどする)