- blogs:
- cles::blog

ExifTool の脆弱性に注意(CVE-2021-22204)


ExifTool*1*2 に脆弱性(CVE-2021-22204)が見つかっていたのでメモ。
特定の画像を処理すると任意のコマンドが実行できる*3ようになってしまうという問題のようです。
普段からGPS データの書き込みなどに便利に使っているので、忘れずにアップデートしておきたいと思います。
- *1: ExifTool by Phil Harvey
- *2: exiftool/exiftool: ExifTool meta information reader/writer
- *3: CVE-2021-22204 ExifTool の任意のコード実行の脆弱性 - PwnWiki

時計がズレているカメラで取った写真の Exif を ExifTool で修正

先日買った D850 ですが、メモリカードから吸い出した写真を見ていたら Exif の年月がデタラメなことに気づきました。
初期設定のときに日付を入れずにうっかり時刻だけを設定してしまったようです。
新しいカメラを買ったということもあり、我ながら舞い上がっていたみたいですね。
さすがにこのまま保存しておくと本当の撮影日が分からなくなってしまうので、いつも頼りにしている ExifTool でなんとかできないか調べてみました。
そうしたら Date/Time Shift Feature という、まさにそういうときのための機能があるではないですか。
使い方としては以下のような感じで年月日時分秒を指定すると、Exif の時間をずらすことができます。
例えば + 2 年と 2 ヶ月と 14 日ずらす場合には以下のような感じになります。
日付の指定方法の詳細は「ExifTool Date/Time Shift Module」で解説されています。

exiftool で GPS データを削除する


以前、exiftool.exe を使って GPS データを EXIF に書き込むというのをやりましたが、今回はその逆で exiftool を使って EXIF から GPS データを削除する方法を調べてみたのでメモ。
結論から述べると、以下のようなオプションがついたショートカットを作ればいいみたいです。
マニュアルにも以下に記載がありますが -geotag= だと緯度経度情報は消えますが、他の GPS タグが残ってしまうのでで、すべての GPS データを消すためには必ず -gps:all= を使う必要があることに注意が必要です。
Geotagging with ExifTool
Delete GPS tags which were added by the geotag feature. (Note that this does not remove all GPS tags -- to do this instead use -gps:all=):
exiftool -geotag= a.jpg

D500 の EXIF の MakerNote がちょっと違う



D500 にしてから EXIF の Makernote からレンズの種類が取得できないので、データを眺めて原因を探ってみました。
ヘッダの16進ダンプはこんな感じなので、フォーマットは D600 と同じ Nikon Type 3 ですが、Version は 2111 と D600 の 2110 から若干上がっただけで、それ以外は大差ないように見えます。
でも EXIF ライブラリがうまく parse できないので、よく見てみるとヘッダが若干違うんですね。 Type 3 のヘッダ部は "Nikon\x00\x02\x10\x00\x00" か "Nikon\x00\x02\x00\x00\x00" のはずなのですが、ここが "Nikon\x00\x02\x11\x00\x00" となってしまっているので、これが諸悪の根源に思えます。ちょっと安直ですが、The PHP JPEG Metadata Toolkit の該当の判定部分に条件を追加してみたところ、これまで通り Makernote にアクセスできるようになったので、ひとまずこれで良しとします。
バージョンが上がっているので、おそらく何らかの拡張は行われているのだろうと思いますが。。。。。

Chrome で EXIF が手軽に確認できる拡張


FxIF という EXIF を Firefox で確認するアドオンがありましたが、Chrome にも同じようなアドオンを見つけたのでメモ。FxIF と違ってこちらは特に何もせずともマウスオーバーするだけで EXIF の内容を表示することができるので扱いやすいです。さらに GPS データは Google Maps のポップアップを示してくれるのでとっても便利です。
【レビュー】写真へマウスオーバーするだけでExif情報をチェックできるChrome拡張「EXIF Viewer」 - 窓の杜
本拡張機能を利用すると、Webページに掲載されている写真上へマウスカーソルを移動させるだけで、当該写真に含まれているExif情報を見ることが可能。
さらに、Exif情報にGPSで取得した位置情報が含まれている場合は、その位置を“Google マップ”で確認することも可能。赤く[GPS]と書かれたラベルにマウスカーソルを移動させると、写真の代わりに当該位置を中心とした“Google マップ”が現れる。

exiftool.exe を使って GPS データを EXIF に書き込む


これまで画像への GPS データの合成は Jpeg GPX Merger のような GUI フロントエンドを持ったものを使っていたのですが、exiftool.exe のマニュアル*1を読んでいたら、バッチで GPS のデータを合成できるようなので色々と実験してみました。
結論から述べると、以前ファイル名のリネームをやったときと同じで、下記のようなオプションをつけれやれば OK でした。合成を始める前に exiftool.exe の置いてあるディレクトリに GPX というフォルダを作り、そこに必要な .gpx ファイルを入れておく必要があります。exiftool 自体は GPX 以外にも NMEA RMC/GGA/GLL, KML, IGC, Garmin XML and TCX, Magellan PMGNTRK, Honeywell PTNTHPR, and Winplus Beacon text files をサポートしているので、GPX 以外を用いる場合には -geotag の部分の拡張子を変更してください。
いくつかオプションがついていますが、-api GeoMaxIntSecs=0 は合成すべき時間が GPS から取得できない場合に線形補完を使うかどうかを決めるためのパラメータで、デフォルトは間隔が 1800 (30分) 以内の場合有効にすることになっています。線形補完は車や飛行機など一定スピードで移動している事が明らかな場合は有効かもしれませんが、変なところにプロットされるよりはタグ付けするのを諦めてもらう方がよいので 0 (無効)にしてあります。次の -api GeoMaxExtSecs=15 についても合成すべき時間が GPS から取得できない場合のパラメーターですが、これは補完ではなく規定以内の秒数であればそのポイントを使うというものです。こちらもデフォルトが 1800 (30分) になっているので、誤差を考慮して 15 にしています。
また、-k は処理が終了した時にプロンプトを出して待ちに入るようにするオプションになります。-overwrite_original は処理の時にオリジナルを上書きして、バックアップファイルを残さないという指示です。これは場合によっては危険なので、テストの時は入れない方がいいでしょう。-geotag "GPX/*.gpx" は GPS のログファイルをどこから取ってくるかという指示になります。

EXIF に含まれるサムネイルを一括削除

EXIF にはサムネイルが含まれていることがあり、元データにはモザイクかけたのにサムネイルにはモザイクがかかっていなくて元画像が丸見えという事故が起こりやすいので、公開ファイルからはサムネイルは削除しておいたほうが賢明です。もちろんEXIF の情報が編集できる画像編集ソフトを使えば一つ一つの EXIF を修正していくこともできますが、これを一括で行う良い方法がないかと思って調べてみました。
以前にも EXIF によるファイル名置換でお世話になった ExifTool by Phil Harvey を使えばいいみたいです。
前回と同様に下記のパラメータを入れたショートカットを作り、ショートカットに画像ファイルをドラッグアンドドロップすると、サムネイルが削除されたファイルが出来上がります。
サムネイルがなくなるので、ファイルのサイズも若干ですが小さくなるようですね。

EXIF に潜むマルウェア


EXIF ヘッダにマルウェアが埋め込まれているという話が興味深かったのでメモ。
- JPEG画像のEXIFヘッダにマルウェアを隠して実行させる新しい手口が登場 - GIGAZINE
- Malware Hidden Inside JPG EXIF Headers | Sucuri Blog
PHP のバックドアというと、リモートのファイルをインクルードする*1という攻撃方法がポピュラーでしたが、下記の攻撃は直接スクリプトファイルを読み込むのではなく、スクリプトを EXIF に埋め込んでおき、exif_read_data()*2 で読み出すという方式になっています。そして最終的に利用されるのは preg_replace()*3 の e 修飾子*4 。これまでも e 修飾子については、攻撃の踏み台として使われることが多かったので、5.5 では非推奨となっており、将来的には削除されるものと思われますが、それまではこのような攻撃が発生し続けると思われます。
このような方式だと単純なフィルタリングでは検知できないかもしれないので、注意が必要ですね。
- *1: 今週のSecurity Check - リモート・ファイル・インクルード攻撃:ITpro
- *2: PHP: exif_read_data - Manual
- *3: PHP: preg_replace - Manual
- *4: PHP: 正規表現パターンに使用可能な修飾子 - Manual

続・EXIF からレンズ名を取得する(Nikon編)



先日作った EXIF からレンズ ID を取り出すプログラムですが、どうしてもレンズ ID の8バイト目を一致させることができませんでした。初めは単なる僕の作り込んだバグだと踏んでいたのですが、改めてこの件を調べてみると JpegAnalyzer Plus に同梱されている LensData.ini にレンズ ID の8バイト目は 0x0098 というタグからではなく、0x0083 というタグから取得する必要があるという記載を見つけました。
どうやら僕の仕様の勘違いだったようです。
というわけでこれを反映したコードにアップデートしてみました。

EXIF からレンズ名を取得する(Nikon編)



以前、Panasonic 機の EXIF からレンズデータを抽出するというのをやりましたが、最近メインのカメラが D600 になったので、今回は Nikon 機の EXIF からのレンズデータの抽出にチャレンジすることにします。
プログラミングの大きな問題点は2つ。Pana機の場合はレンズ名が直接 EXIF に埋まっていましたが、Nikon 機はレンズの ID 情報だけが埋め込まれているだけのようなので、 ID とレンズ名の関連づけは自分でやらなくてはなりません。また、Nikon 機の EXIF は項目によっては暗号化がされていて、そのままではデータが読めないようになっているので、これを復元してやる必要があります。
レンズの ID については下記のサイトに纏められていたので、これを利用させてもらいました。
もう一つの暗号化されたデータの復元については FITS*1 というプロジェクトに Perl で書かれた Decypt()*2 という復号化ルーチンがあったので、これを丸々 PHP にポーティングしました。
EXIF のパースは前回と同様に、The PHP Metadata Toolkitを用います。
- Rufus Windows11 インストーラカスタム
- Rufus に Windows のインストールをカスタマイズできる機能がついてた
- Rufus Windows11 インストーラカスタム
- Rufus に Windows のインストールをカスタマイズできる機能がついてた
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110866)
3 . 年次の人間ドックへ(110437)
4 . 2023 年分の確定申告完了!(1つめ)(109983)
5 . 三菱鉛筆がラミーを買収(109886)
Academic[574]
Book[155]
Diary[522]
Disaster[101]
Foodlogue[1425]
Game[284]
Goods[805]
Healthcare[341]
Hobby[32]
IT[1195]
Military[343]
misc.[1570]
Mobile[510]
Music[38]
Neta[106]
News[95]
Photo[391]
RealEstate[120]
Security[1178]
SEO Contest[36]
Software[634]
Tips[1886]
Travelogue[1238]
Web[675]
Work[193]