LoginSignup
10
11

More than 3 years have passed since last update.

0.やりたいこと

自サーバにはphpファイル1個のみを置く。
file_get_contents(Googleドライブにアップしたhtmlファイル)をやることで、
あたかもコンテンツを持ったサーバであるかのように扱いたい。
これができると、パソコンやスマホなどから容易にページが更新できて便利だ(ftp接続が要らない)。

1.課題

普通にhtmlファイルをアップしてGoogleドライブの画面から素直にリンクを取得しても、うまくいかない。2つ工夫する必要がある。

1-1. 課題1つ目

1つは、「Googleドライブ専用の画面」が開き、その内部でコンテンツを開いてしまうという問題。
例えば、こんな感じ。
https://drive.google.com/open?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk
この問題を解決するには、urlをちょっといじる。
openucに書き換えるだけでよい。
こんな感じ。
https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk
確かに変な画面内でコンテンツを開くという問題はなくなった。

1-2. 課題2つ目

しかし、1-1節の方法でhtmlファイルを共有しようとすると、Googleドライブはhtmlファイルをダウンロードさせようとする。ダウンロードせずに直接表示したいのに。。。
https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk&export=viewとしても、https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk&export=view#dummy.htmlとしても結果は変わらず。
しかし、bmpなどの画像ファイルではなぜかうまくいく。(ダウンロードではなく普通にブラウザで表示してくれる)
こんな感じ。
https://drive.google.com/uc?id=1LtcHFzaYa1bahScgEZRFjxuStIgZ0Udx
いろいろやってみると、ucを使ったとき、Googleドライブではファイルの種類ごとに異なる仮想サーバへリダイレクトし、そこからコンテンツ提供しているようだとわかった。
例えばbmp形式やpng形式では「doc-04-3c-docs.googleusercontent.com」から、
html形式では「doc-04-b4-docs.googleusercontent.com」からだった。
さらに、htmlファイルの拡張子を変更し、test.pngというファイルとしてアップロードしたものを表示しようとすると、これもバレて、「test.png.html」というファイルとしてダウンロードが開始してしまった。

きっと仮想サーバごとに、コンテンツ提供の方法がダウンロードか、そのままブラウザで表示させるかが異なるのだろう。

2. 実験

1-2節の問題を解消し、ブラウザ上でGoogleドライブに保存したhtmlファイルを表示させるため、次のような方法を考えた。
「空のbmpファイルを作り、内部にhtmlソースを書き込み、これをGoogleドライブにアップロードする(2-1節)。
これをサーバサイドプログラムがちゃんと認識すれば、内部にあるhtmlソース通りに表示できるだろう(2-2節)。」

2-1. bmpファイルにhtmlを埋め込む

bmpは画像のフォーマットの一種だ。他の形式と比較して極めて単純な構造を持っていて、バイナリエディタなどで16進(あるいは256進)表示すると、画像の画素の並びに従ってbitが記録されていることが分かる。構造が簡単な故に改編なども容易だ。そのため、「画像に画像以外の情報を埋め込む」には最適なフォーマットであるといえる。
次の手順でhtmlソースを埋め込んだ。

  1. c.bmpを作成し、ペイントで開き、24色1000px×1000pxとした
  2. バイナリエディタStirlingでb.bmpを開き、FFの連続が開始しているところから、<html>hello world</html>という文字列を上書きした。バイト数が変わらないように気を付けた。(これが変わるとファイルが壊れてしまう)
  3. これをGoogleドライブにアップロードした。
    https://drive.google.com/uc?id=1-G5TkDMgZBAeH2t8TudaVRF9BMwgRAGy
  4. 手順3のリンクを開くと、大きな白地の画像の、左下にかすかに黒い小さな線があるのが分かるだろうか。これが<html>hello world</html>という情報を表現している。
  5. このファイルをダウンロードし、再びバイナリエディタで開いた。確かに<html>hello world</html>という情報は残っていた(圧縮などが自動で書けられ、壊されてしまう可能性があり、調べた)

以上で、Googleドライブはhtmlファイルを、専用画面でもダウンロードでもなく、ブラウザに直接表示することになった。但しbmp画像として。

2-2. サーバ上でbmpファイルからhtmlを取り出す

2-1節で作ったbmp画像からhtmlファイルを取り出すのは自サーバのphpファイルの仕事だ。
次のようなプログラムを書こう。やってることは、「file_get_contensでページを取得したら、そこから<html></html>を取り出して、それを表示してね」という単純な処理だ。

<?php

$asBmp =  file_get_contents("https://drive.google.com/uc?id=1-G5TkDMgZBAeH2t8TudaVRF9BMwgRAGy");
/* urlパラメータ「id」でファイルIDを動的に変えたいなら次の通り
$asBmp =  file_get_contents("https://drive.google.com/uc?id=".$_GET['id']);
*/

$start = strpos($asBmp, '<html');
$end = strpos($asBmp, '</html>')+7;

$html = substr($asBmp, $start, $end-$start);

print $html;


このphpプログラムにアクセスすると・・・
image.png
うまくいった!

3.感想

こんな手垢のつきまくったであろう手法で出来ることなのだから、きっとこれは想定外の脆弱性などではなく、裏技の類なのだろうと思った。(だからここで公開した。)
何はともあれ、これによって、「パソコン上でファイルを更新すれば後は自動でホームページが更新される」という仕組みが完成した。うれしい。

10
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11