1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonでのIPアドレスの取扱いについて

Last updated at Posted at 2021-05-12

#はじめに
IPアドレスの8進数の不適切な検証の脆弱性(CVE-2021-28918)がPythonのipaddressモジュール影響あるということで、ipaddressにおけるIPアドレスの取扱いを調べた。
また、ドット区切りIPアドレスからドット区切りなしIPアドレスへの変換を行う関数を作成した。

#ipaddressモジュールにおけるIPアドレスの扱い
以下のように、ipaddressモジュールがインポートされていることを前提とします。

>>> import ipaddress

例として、ローカルループバックアドレス(127.0.0.1)を用います。

##ドット区切りIPアドレスにおける8進数の扱い
先頭の0は単に除外される

>>> ipaddress.IPv4Address('127.0.0.01')
IPv4Address('127.0.0.1')

3桁を超えるとエラーになる(この例はChromeなどでは「88.0.0.1」に変換される。)

>>> ipaddress.IPv4Address('0127.0.0.1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.9/ipaddress.py", line 1302, in __init__
    self._ip = self._ip_int_from_string(addr_str)
  File "/usr/lib/python3.9/ipaddress.py", line 1199, in _ip_int_from_string
ipaddress.AddressValueError: At most 3 characters permitted in '0127' in '0127.0.0.1'

##ドット区切りなしIPアドレスの扱い
###10進数

>>> ipaddress.IPv4Address(2130706433)
IPv4Address('127.0.0.1')

###8進数

>>> ipaddress.IPv4Address(0o17700000001)
IPv4Address('127.0.0.1')

(Pythonでは、0oXXXが与えられるとXXXを8進数と認識し、内部では10進数として扱います。すなわち、本質的には10進数の場合と同じことをしています。)
###16進数

>>> ipaddress.IPv4Address(0x7f000001)
IPv4Address('127.0.0.1')

(Pythonでは、0xXXXが与えられるとXXXを16進数と認識し、内部では10進数として扱います。すなわち、本質的には10進数の場合と同じことをしています。)
###バイト型

>>> ipaddress.IPv4Address(b'\x7f\x00\x00\x01')
IPv4Address('127.0.0.1')

#ドット区切りIPアドレスからドット区切りなしIPアドレスに変換
例として、ローカルループバックアドレス(127.0.0.1)を用います。

##10進数
ドットごとに数値を取得し、最初の数値(例では、127)から順にに$ 2^{24}, 2^{16}, 2^8, 2^0 $を掛けて、合計を出力することで変換しています。
$ n\cdot2^x $の部分は、左シフトで計算しています。

>>> def ipv4d2nd(ipv4):
...     return sum((int(n)<<8*d for d,n in enumerate(reversed(ipv4.split('.')))))

>>> ipv4d2nd('127.0.0.1')
2130706433

(以降は単に変換方法になります。)
##8進数

>>> oct(ipv4d2nd('127.0.0.1'))
'0o17700000001'

##16進数

>>> hex(ipv4d2nd('127.0.0.1'))
'0x7f000001'

#バイト型

>>> ipv4d2nd('127.0.0.1').to_bytes(4, 'big')
b'\x7f\x00\x00\x01'

#参考文献
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-28918

1
3
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
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?