コピーアンドペーストに注意してください:印刷できない文字を含むテキストのフィンガープリント

読みたくないですか? デモをご覧ください。



ゼロ幅文字は、ほとんどのアプリケーションで表示されない印刷できない制御文字です。 たとえば、この提案では、幅がゼロの10個の白を尋ねましたが、目立っていますか? (ヒント:文字の場所を確認するには、 Diff Checkerに文を貼り付けてください!)。 これらの文字は、ユーザーを識別するためのテキストの一意の「指紋」として使用できます。





もちろん、彼はここにいることができます。 そして、あなたは推測することはありません



なんで?



まあ、元の理由はあまり面白くないです。 数年前、チームと私はさまざまなビデオゲームに参加しました。 チームには、特に重要な発表用のプライベートページがありました。 しかし、最終的に、これらの発表は他の場所に再投稿され始め、チームをいじめ、機密情報とチームの戦術を明らかにしました。



サイトの保護は非常に安定しているように思えたので、ユーザー名とパスワードでログインし、広告をコピーして別の場所に配置するインサイダーがいることを提案しました。 したがって、各広告にこの広告を表示するユーザーの名前を目に見えないように刻印するスクリプトを開発しました。



Zach Aisan による最近の投稿の後、人々は印刷不可能なキャラクターのテーマに興味があることが明らかになりました。 そこで、私はこのメソッドをここに公開し全員向けのインタラクティブデモを公​​開することにしました。 最新のJavaScript用にコードサンプルが更新されましたが、一般的なロジックは同じです。



どうやって?



正確な手順とロジックを以下に説明しますが、簡単に説明すると、ユーザー名文字列はバイナリ形式に変換され、その後バイナリファイルは各ビットを表す一連の印刷できない文字に変換されます。 次に、印刷不可能な行がテキストに無意識のうちに挿入されます。 テキストが別のサイトで公開されている場合、印刷できない文字の行を抽出し、逆のプロセスを実行して、コピーと貼り付けを行ったユーザーの名前を見つけることができます!



テキストフィンガープリンティング



1.ログインしているユーザーの名前を取得し、バイナリファイルに変換します。



ここでは、ユーザー名の各文字を同等のバイナリに変換します。



const zeroPad = num => '00000000'.slice(String(num).length) + num; const textToBinary = username => ( username.split('').map(char => zeroPad(char.charCodeAt(0).toString(2))).join(' ') );
      
      





2.バイナリ形式のユーザー名を取得し、印刷できない文字に変換します



次のスクリプトは、バイナリ文字列を反復処理し、各ビット1を非印刷スペースに変換し、各0を非印刷非結合文字に変換します。 各文字を変換した後、合字(結合者)に印刷不可の許可記号を挿入し、次へ進みます。



 const binaryToZeroWidth = binary => ( binary.split('').map((binaryNum) => { const num = parseInt(binaryNum, 10); if (num === 1) { return '​'; // zero-width space } else if (num === 0) { return '‌'; // zero-width non-joiner } return '‍'; // zero-width joiner }).join('') // zero-width no-break space );
      
      





3.非印刷機密テキストに「ユーザー名」を挿入



ここでは、非印刷文字のブロックを機密テキストに挿入するだけです。



タグ付きテキストからユーザー名を抽出



逆の順序で同じアクション。



1.機密テキストから印刷できない「ユーザー名」を抽出する



文字列から機密テキストを削除し、印刷できない文字のみを残します。



2.印刷できない「ユーザー名」をバイナリに変換します



ここでは、追加された文字間セパレータを考慮して、文字列をフラグメントに分割します。 これにより、ユーザー名の各文字の制御文字が同等になります! 文字を反復処理して1または0を返し、バイナリ文字列を再作成します。 対応する1または0が見つからない場合は、文字間隔(合字解決文字)を取得し、文字のバイナリ変換を完了しました。行にスペースを1つ追加して、次の文字に移動できます。



 const zeroWidthToBinary = string => ( string.split('').map((char) => { // zero-width no-break space if (char === '​') { // zero-width space return '1'; } else if (char === '‌') { // zero-width non-joiner return '0'; } return ' '; // add single space }).join('') );
      
      





3.ユーザー名をバイナリ形式からテキストに変換します



最後に、バイナリ文字列を分析し、各シリーズ1と0を対応する文字に変換します。



 const binaryToText = string => ( string.split(' ').map(num => String.fromCharCode(parseInt(num, 2))).join('') );
      
      





おわりに



企業はこれまで、情報漏えいやインサイダーの検索に多くの注意を払ったことがありません。 これは、使用できる多くのトリックの1つにすぎません。 作業の方向によっては、テキストのコピーに伴うリスクを理解することが重要になる場合があります。 印刷できない文字を表示するアプリケーションはほとんどありません。 たとえば、端末がそれらを表示しようとすると仮定できます(私のものは違います!)。



秘密の掲示板に戻ると、計画は正常に機能していました。 スクリプトの実装後まもなく、新しい発表がありました。 数時間以内に、印刷できない行が添付されたテキストが他の場所に配布されました。 犯人のユーザー名が正常に特定され、禁止されました:ハッピーエンド!



もちろん、この方法の使用については一定の予約があります。 たとえば、ユーザーがスクリプトについて知っている場合、理論的には、印刷不可能な文字を置き換えて別の人を置き換えることができます。 そのため、ユーザー名の代わりに一意のシークレットIDを挿入することをお勧めします。



スクリプトを試すには、 デモを実行するか、 ソースコードを参照してください。



All Articles