# upside-down writeup TSGCTF 2023 のWeb問題。 久々に解けたので、WriteUp書く。 Cryptoも解けそうだったけど、ぷろぐらみんぐちからが足りなかった。 ## index.html どうやら、POSTリクエストでJSONを送信しているようだ。  ## main.mjs 受け取る部分。JSONを受け取って解釈してる。  string.lengthを比べて、Arrayの中身を見ているようだ。  ## JavaScriptにおけるJSONの取り扱いについてみる。 [JSON の操作](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/JSON)のページにもある通り、  で表すことができる。 そのため`string.length`と、`string[i]`、`string[string.length -i -1]`はそれぞれJSONの要素を指定することができる形を取っているので、stringではなくJSONを送るものであると推測して作成する。 この時点で確定しているPayloadは ```jsonld {"length":"1000"} ``` ## Arrayについてみる。 `const i of Array(string.length).keys()`のiに入る値は`string.length`の配列の長さによる。 [Array - mdn web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array) `string.length`はJSONの値なので、配列としての長さは存在せず、`const i`には`0`がはいる。 ~~はいるというか、入った。dockerで動かして、return で`i`を返させたらそうだった。~~ `i=0`なので、 ```javascript string[i] = string[0] string[string.length -i -1] = string[999] ``` となる。ここまででできるPayloadは ```jsonld {"length":"1000","0":hogehoge,"999":hugahuga} ``` ## ifの条件に合わないように調整する。 回避しなきゃいけない条件は合計で3つ。 最終的に`return null`でないといけないため、すべて避ける必要がある。 ```javascript if (string.length < 1000) { return 'too short'; } ``` 1つ目はstring.lengthが1000以上であること。これは`"length":"1000"`で回避できている。 2つ目と3つ目はこれ。 ```javascript if (original !== reverse || typeof original !== 'string') { return 'not palindrome'; } ``` 2つ目は回文チェック(だったもの)で、`original`と`reverse`が同じである必要がある。 `original`は`string[i]`を、`reverse`は`string[string.length-i-1]`を指しているため、JSON内の`0`と`999`の値を同一にすることで回避できる。 3つ目は、`original`が`string`であること。 これは、JSONの値が色々な型を取ることができることを活かして、`string`になるようにおいてあげる。具体的には`"`でくくってあげたらそれで良い。 これら3つの条件を満たしたものが以下のJSONになる。 ```jsonld {"length": "1000","0": "1000","999":"1000"} ``` ## 送信しておわり!!! 今まで忘れられていた`index.html`はここでいきる。 ```htmlembedded= const res = await fetch('/', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({palindrome}), }); ``` `{palindrome}`は見慣れない書き方だけど、[ここに色々書いてあった](https://sbfl.net/blog/2019/08/26/javascript-bracketed-variables/)。分割代入という方法のようだ。 [JSON.stringify()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)は`{palindrome}`に代入された値をJSONに変換しているとみることができる。 (JSON内の変数名"palindrome"がどこから来ているのかが全く分からなかったので、わかる方教えてください。) つまり、先のJSONと組み合わせるとこうなる。 ```jsonld {"palindrome": {"length": "1000","0": "1000","999":"1000"}} ```  ただ、Web上から送信するとその値がダブルクォーテーションで囲まれているため、送信後も文字列として扱われてしまう。 JSONで扱ってほしいので、Web上から送信するのではなくPostmanなどで直接リクエストを送る。 お疲れさまでした。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up