備忘録

備忘録

C#でPublic Key Pinningする

Ⅰ. はじめに

Public Key Pinningとは、SSL証明書のチェックを行うことです。
チェックを行うことで、不正な証明書を検知することができます。

例えばクラッカーはMITMを利用して傍受を試みます。
MITMを利用するとSSL証明書が書き換わる為、
不正な証明書であれば通信を行わないようにすることが出来ます。

Ⅱ. プログラム

Program.cs
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback);
CertificateValidation.cs
public static bool OnRemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
  var hashs = new Dictionary<string, string>()
  {
    { "aaa.jp", "6c276e0c4e2fa19d1656df1298d8ff6497d0cc49" },
    { "aab.jp", "7dfc0fd1abf2af11dd2f9503448009f090d529eb" },
    { "aac.jp", "bb1d931851cc679a476021494550573eb1e1148d" }
  };

  if (hashs.ContainsValue(certificate.GetCertHashString().ToLower()))
  {
    // 通信を許可する
    return true;
  }
  else
  {
    // 通信を許可しない
    return false;
  }
}

SSL証明書ハッシュ値は、SSL証明書の「拇印」の値を使います
f:id:kagasu:20170310145511p:plain

「拇印」のコピーについて

「拇印」をそのままコピーするとデータ先頭に謎のデータが付加されています。
テキストエディタやVisualStudioのエディタで見ても見た目は正しい文字列ですが、バイナリで見ると間違っていることが解ります。
面倒ですがコピーしない方が良いです。
f:id:kagasu:20170915111229p:plain

注意

証明書の有効期限を予め確認する必要があります。
上記のサンプルコードの場合、証明書を更新した後にクライアント側を修正しようとしても通信が一切できない状態になります。
アップデートチェックとしてWeb APIを利用しているケースでは致命的になる場合があります。

PythonでPOSTする

Ⅰ. はじめに

PythonでPOSTする方法です。

Ⅱ. プログラム

import requests

# InsecureRequestWarning を非表示にする場合
# from requests.packages.urllib3.exceptions import InsecureRequestWarning
# requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

s = requests.session()

proxies = {
  'http':'http://user:pass@127.0.0.1:8008',
  'https':'https://127.0.0.1:8008'
}

headers = {
  'User-Agent' : 'Mozilla/...',
  # 'Content-Type' : 'application/x-www-form-urlencoded'
}

params = {
  'param1' : 'xxx',
  'param2' : 'yyy'
}

s.proxies = proxies
# 証明書チェックを省く
s.verify = False
s.headers = headers

response = s.post('https://example.com/', params)

# 文字化けする場合はcmdで「chcp 65001」を実行すると治る(Windows)
# 65001 はutf-8
print response.content

Ⅲ. その他

開発環境でMITMを利用したproxy(FiddlerやBurpSuiteやCharlesやmitmproxyなど)
SSL Decryptを有効にしていると以下のエラーが出ます。

requests.exceptions.SSLError:
("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)
s.verify = False

にするとでなくなります。

VisualStudioで設定したAWSのプロファイルを修正する

Ⅰ. はじめに

AWS Toolkit for Visual Studioを利用しているのが前提です。
VisualStudioに追加したプロファイルの追加、編集、削除するについて説明します。

Ⅱ. やり方

1. AWS Explorer を表示させる

VisualStudioのメニューから
「表示」→「AWS Explorer」を選択します。

2. 追加、編集、削除する

人のアイコンが左から順番に
「追加」、「編集」、「削除」となっています。
f:id:kagasu:20170304201010p:plain

JMPの隠蔽

Ⅰ. はじめに

リバースエンジニアリングのテクニックの1つです。
パターン化しているので覚えておいて損はありません。
主に ASProtect というパッカーが利用する方法です。

Ⅱ. JMPの隠蔽方法

通常の場合

アセンブリでJMPする場合は以下のように書きます。

JMP x

隠蔽の例

push x
retn

push x とすると x がスタックに積まれます。
retn するときはスタックの一番上に積まれた x にジャンプします。
よって、上記2つのコードは全く同じ動作をします。

また、アセンブリ言語レベルで任意のコードを実行する場合、PUSHを利用したほうが楽になります。
JMP の場合 JMP 先のアドレスとの差を計算して第一オペランドに与える必要がありますが、PUSH を利用すると計算の必要が無くなる為です。

C# WPF 数値のみ入力できるTextBoxを作る

Ⅰ. はじめに

半角数値0~9のみを許可するTextBoxの作り方です。
数値のみ入力可能なTextBoxは標準機能として用意されていません。(2017/02/20時点)
入力値が数値かどうかを判定するコードを書く必要があります。

Ⅱ. 作り方

1. MainWindow.xaml

<TextBox
  x:Name="textBoxPrice"
  InputMethod.IsInputMethodEnabled="False"
  PreviewTextInput="textBoxPrice_PreviewTextInput"
  CommandManager.PreviewExecuted="textBoxPrice_PreviewExecuted"/>

2. MainWindow.xaml.cs

private void textBoxPrice_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
  // 0-9のみ
  e.Handled = !new Regex("[0-9]").IsMatch(e.Text);
}
private void textBoxPrice_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
{
  // 貼り付けを許可しない
  if (e.Command == ApplicationCommands.Paste)
  {
    e.Handled = true;
  }
}