とあるマルウェアのお話

リレーブログの続きです。前回はこちら

お題はemotetについてです。なのに、タイトルがとあるマルウェアになっているのは検索避けです。詳しい記事が他にあることから、ちょっと表題に取り上げるのはやめました。

seccamp2022が始まってきてますが、時の流れは早いですね。今年のキャンプにはチューターとして参加します。受講生がどんなグループワークするか楽しみです。

emotetとは

まずは、マルウェアの種類

感染経路

  • メールの添付ファイル
    • パスワード付きzipファイルの中にある文書ファイルに添付されてる
  • メールに記載されたURL

感染被害

  • メールソフト・ブラウザに記録されたパスワードの窃取
  • 感染した端末のメールアドレスから再配布で感染拡大
  • ブラウザに保存されたクレジットカード情報が摂取される

 

ファイルレスマルウェアなので、ウイルス対策ソフトで検出できる実行可能ファイル(バイナリ形式)がない。emotet用検出ツールで僕が知っているのはこれです。

github.com

emotetは変化を結構しているぽくて(twiiterで追っかけているだけでも最新情報見る)、それに合わせてcheckerも更新されてます。特に、上記の感染被害で書いたクレジットカードの話は6/9なのでとても直近です。

簡単な時系列 (歴史)

  • 2014年 : 銀行の認証場法を搾取するマルウェアとして観測
  • 2017 ~ 2019 : 他のマルウェアをダウンロードするローダとなる
  • 2021年 1月 : EUROPOLにより、C&C、C2サーバーのテイクダウン
    • 無害化された。一旦終わった感じ
  • 2021年 11月 : 活動再開

無害化したときのニュースで

こんなの

とか。

自分たちができること

不審なメールアドレスから送られてきたファイルを開かない。

簡単なようで、できていないから広がっているので気をつけましょう。

 

時間があれば、解析とかしてみたいですね。できるか分からないけど。

SecHack365に取り組みます

SecHack365 2022やります

SecHack365(セックハックサンロクゴ)の学習駆動 今岡ゼミに所属することになりました。

1年間頑張りたいと思います。キャンプと違って、課題内容とかが書けるわけではないですが適当に抱負的なの書いときます。

申し込むきっかけ

就活終わってたら申し込む予定でした。加えて、高専の研究でやりたかったことがどんどん違うことになったからです。

それなら、高いレベルのものが作れるだろうし、いろんなことが経験できるsechackに行こうと思ったわけです。

コースは結構悩んでいて、次のコースで悩んでました

  • 学習 坂井ゼミ
    低レイヤ興味ある。デコンパイラとか、動的解析のサポートとか面白そう
  • 学習 今岡ゼミ
    研究でできなかったことをしたい
  • 研究
    なんかsechackでやる研究って面白そう?
  • 表現
    グループ開発よさげ。サービス制作とかに強くなれそう

って感じで、結局今のコースになりました。結構悩んだんです。課題やってるときも悩んでた。

やること

楽しみにしてて下さい。概念で終わらないように頑張っていきたいと思います。

その他

申し込むのはただなので、ちょっともってでも書くといいと思います。

あと、トレーナーの得意分野やコースごとの特徴を踏まえて申し込むことが大事だと思います(多分)。

 

最後に

ちゃんとセックハックサンロクゴと言います。

ブルートフォースアタックについて

リレーブログの続きです。前回はこちらで、次回はこちらで更新予定です。

今回のお題はブルートフォースアタック(総当たり攻撃)についてです。

ブルートフォースアタックとは

名前の通り、パスワード等の分からない文字列(数字)に対して総当りを行うことです。

ダイヤル式の鍵とか、パスを忘れても根気強く全ての組み合わせを試せば空きます。
3桁の場合10 ^ 3なので1000回ですね。まあ、5秒で1組できるとしたら5000秒だったら1時間半くらいで空きます。

オンライン上に存在するユーザーパスワードとかで先程と同様の条件だったら、機械的にやればいいのでもっともっと早く解かれますね。

なので、複雑なパスワードにする必要があるわけです。

下にパソコンでブルートフォースを行った場合にかかる時間をまとめた図を引用します。(引用元 : https://cybersecurity-jp.com/column/17426)

これ、2015年なので今はもっと早いでしょう。GPUとか使ったらもっと早くできる。
2019年3月19日に出ているIPAの情報セキュリティ5か条では10文字以上の英数字記号が奨励されています。

短くなければいいというわけではなく、よくあるパスワードは使ってはいけません。
まあ、上記のような制約があればありきたりのパスワードは生まれないでしょう。

これくらいで終わると味気ない気がするので、CTFでの総当り攻撃を行う場面を考えてみたをやっていきます。

PDFのパスワードに対して総当りをやってみた

やってみたといっても今やるわけではありません。やったことがあった。です。

setodaNote CTFのstrong_passwordになります。これ、常設になったらしい?

確か、これは問題文の中にパスワードのルールが書いてあったはずです。
ルールが分かれば10文字超えても総当りは楽になります。

ちなみに最近、パスワードをこういう理由でつけましたという言葉とともにファイルが送られてきましたが一生開けてないです。総当りをしてほしいのでしょうか。

pdfのパス総当りでは、pdfcrackやJack The Ripper + hashcatを用いた方法があります。

使い方は各自で調べてもらえたらなと思います。

 

基本、CTFで総当りをする機会は少ないでしょう。
今回は以上になります。

Winja CTF | Nullcon Berlin 2022

個人で参加して36 / 93でした。

3問解きました。

Forensic Manila:

14 solvedで198pt。

pdfが配布されます。pdfビューワーで開きますが、何もありません。ファイル形式はちゃんとpdfです。

stringsコマンド等で見ますが、flagが直接入っているわけではありませんでした。

全体を見ていると、途中で文字が反転していることに気づきます。そしてこの文字列はpngを表していることが分かります。以下のようなコードを書き、生成したファイルからbinwalkでpngを取り出しました。

with open("Manila.pdf", "rb") as f:
    dat = list(f.read())

dat = bytes(dat[::-1])

with open("hoge", "wb") as f2:
    f2.write(dat)

flagが書かれた写真でした。

flag : flag{f497dfa4fe524bdaa6d973453859df9a_You_f0UNd_7H3_undERCover_r0bber}

このCTF、全体的にflagが長いんですがここまで長いと打つのめんどくさい

Rev Mercedes Colmenar:

44 solvedで250pt。

入力を求められます。

ltrace ./Mercedes_Colmenar

とすると、分解された比較対象が見えます。 -> The_3nd_0f_tHE_rO4D

改めて実行し、先程のpassを入力します。

flag : flag{3a81fcc46d1f7b990cafab0b0e1c01ce_REvEnge_iS_4_SELf15h_@ct}

Misc Suárez:

38 solvedで179pt

pythonのコードがアセンブリっぽくなったファイルが渡されます。

内容は

  • flagがasciiコードになってる
  • indexがばらばら

これだけなので、ツールを調べてもよかったですが手元で簡単にできそうです。

c_dat = []
iti = []

flag = [""] * 54

with open("dat.txt", "r") as f:
    dat = f.read().splitlines()


for i in range(0, len(dat), 2):
    c_dat.append(int(dat[i]))
    iti.append(int(dat[i+1]))

# print(c_dat)
# print(iti)

for i in range(len(iti)):
    flag[iti[i]] = chr(c_dat[i])

print(''.join(flag))

flag : flag{5424b01a0e1a94198c5aa17de5a599b9_wA$_I7_e@5y_x0R}

Pwn Francisco Torres:

24 solvedで192pt

間に合いませんでした。

これはpwnじゃなくてmiscでしょと思うし、flag長すぎ。

ncで接続するとqrコードが渡される。これを読むとflagの一部が見れます。時間内で90文字見たんですが、まだ完成しませんでした。終わってからちょっとやりましたが100超えても完成しないので、やめました。

うーん。意図が読めない。自分のコードが悪いのかもしれませんが。

from ptrlib import *
from time import sleep

s = Socket("3.145.216.156", 41879)

# flag = []


i = 0

while True:
    if i == "見たいqrの数字":
        s.recvuntil("set.")
        sleep(2)
        with open("qr.txt", "a") as f:
            f.write(s.recv(4000).decode('utf-8'))
        break
    
    s.recvuntil("Enter the Flag you got till now >")
    
    
    s.sendline(flag[i].encode())
    print("{}, {}".format(i, flag[i]))
    sleep(1)

    i += 1

sleepを挟まないと、データが見れなかった。

公開鍵基盤 / pkiについて

リレーブログの続きです。前回はこちらで、次回はこちらで更新予定です。

今回のお題は公開鍵基盤についてです。取り掛かるのが遅く、薄い内容になってしまいました。

公開鍵基盤とは

PKIはPublic Key Infrastructureの略で、名前の通り公開鍵暗号方式の技術を利用して認証を行うセキュリティのインフラ(基盤)を指します。

具体的には以下のことができます。

  • 秘密鍵による暗号化
  • 公開鍵による復号化
  • 本人性の確認
  • 文書の改ざん検知 等

本人性の確認はデジタル署名で行います。このデジタル署名は認証局(CA)によって発行された電子証明書によって行われます(という解釈をしているがあっていますかね)。

公開鍵暗号

これはだいぶ前のリレーブログで触れた気がするのですが...

公開鍵暗号の代表的なものとしてRSA暗号があります。
RSA素因数分解に時間がかかることを利用したものです。

次のように暗号化と復号化を行います。これをしてくれるのが先程説明したPKIになるわけです。

  1. 受信者が公開鍵・秘密鍵を生成
  2. 送信者がメッセージを公開鍵で暗号化する
  3. 受信者は秘密鍵で暗号化を解く

 

今回は以上です。薄くてごめんなさい。

高専での就活

注意

  • ポエムです
  • 結局は受かったから言えてます
  • 参考になればと思い書くことにしました
  • エンジニアの就活です
  • 会社名は出しません
  • 何書くか決めないまま書いているので読みづらいかも
  • 一般応募について書きます -> なので高専は特に関係ないかも

いつ就職に決めたのか

はっきりとは覚えていないですが、2から3年生になるときだったと思います。
このときになりたい職業もあらかた決まっていた気がします。

高専入るときに考えていた進路・将来の夢が生活をするにつれ違う方向になったからな気がします。

しっかりと決めたのは3から4年生でしょう。結局は編入の勉強から逃げたわけです。

一般応募か推薦応募かについて

はっきり言うと、高専に来ている求人は自分にあっていませんでした。なので、一般で受けるつもりしかなかったです。1社、推薦で受けようかなと思っているところがありましたが自分が受ける年は推薦がなくなっていました

なりたい職の推薦があるなら推薦もいいでしょうし、ないなら諦めずに一般を受けるべきです。ここでおすすめなのは、とりあえず気になった企業のマイページを作っておくことです。

ただ、一般で落ちて病むようならやめた方がいいんじゃないかと思います。個人の自由です。

準備等について

就活を始めたのは、4年の夏休み終了後です。一般応募には早期選考というものがあります。なので情報のチェック等を始めるの3年の冬休み終了後がいいんじゃないでしょうか。結局は1年前からになるのかな

やったこと

とりあえず、自分がやったことをつらつら書きます

  • マイページ作る
  • マイページない会社に連絡してみる
  • コーディングテストの勉強
  • 面接受ける会社の情報収集とまとめ
  • 学校での面接練習

友達から、適性検査とかESの練習(添削)はしないのかと聞かれますが自分はいらないと思いました。ES提出時(いわゆる書類選考)で落ちていたら考えたかもしれませんが、この時点で落ちたことはなかったので

やったやらなかったに関わらずの反省点
  • 学校の面接練習は意味ない
  • コーディングの勉強はもうちょい早めにやるべき
  • 企業を見る視野が狭すぎた <- 徐々に広まりますが
  • 面接後の振り返りをしなかった <- 途中からされた質問を書き起こしたりしました
  • あと、インターン行ってなかった

適性検査

一般的に適性検査は国語 + 算数だと思います。その中でもそれぞれ2種類に分かれるんじゃないかなと思います。

国語

  1. ただの語句とか、ちょっとした穴埋め : 難易度低い
  2. 穴埋めばっかり : 難易度高い

算数

  1. ただの計算(割合とか) : 難易度低い
  2. グラフの読み解き : 難易度高い

自分は1が多かったです。1の場合は生きてる中で得ている知識でどうにかなると思います。2はグラフがかなり難しい気がしますが、特に対策はしませんでした。

書き忘れていましたが、適性検査には人柄チェックみたいなのもありますね。これは対策とかないでしょう。思ったままに答えていました。

ES

企業によると思いますが、基本的に志望動機・技術 + 会社による課題への回答って感じじゃないでしょうか。

添削はしてもらうといいんじゃないでしょうか。自分は書くのに困ったことはなかったです。添削してもらう場合などは、添削者の予定・締切の予定があるのでゆとりを持って取り掛かるといいんじゃないでしょうか。

自分の書き方としては、2個大きな一文を用意してそれを補足する文章を書くという形にしていました。

  1. 貴社の育成がいいと思います + こうこうこうで
  2. 貴社のこの事業が... + こうこうこうで

みたいな。このブログ見て、こいつにとやかく言われたくねえって思うかもですが

コーディングテスト

アルゴリズム嫌だったので、ずっと逃げてました。ただ、どうしても逃げれなくなって(それをしったのが受付始まる1週間前くらいだったかな。もうちょいあったかも)急いでやり始めました。

前提として、全く書けないわけではなくアルゴリズムを知らないという所からスタートしました。なので、まじで書けないって方は参考にならないかもですがまじで書けない方はコーディング求める所受けないでしょう。

言語はpythonオンリーです。

Atcoderやっている友人に助けてもらいました。用いた教材はアルゴ式です。やったアルゴリズムは次になります。

テスト受けるときはある程度理解していました。今は、無理です。

ここのコーディングテストはどうだったとかは書きません。

1週間前じゃなくて、1ヶ月前からしたほうがいいでしょう。Atcoderの色で言うと何色ぐらいまで実力をつけたらいいのかは分かりません。

面接(練習)

初めて受ける面接の前に2回やりましたが、意味がなかったです。理由はいくつかあります。

  • 最初は技術面接、それは学校の練習で補えない(推薦は知らん
  • 練習で面接慣れ・場慣れができなかった

本番を繰り返すことで面接に慣れてきました。

どうしゃべるかは人それぞれにあったものがあると思いますが、自分が気をつけたのは思っているよりゆっくりしゃべることです。

使用したサイト・ツール

  • 求人一覧
    • マイナビ (使っていない。登録もしなかったと思う)
    • 各社のマイページ
  • 逆求人系
    • paizaスカウト(あんま使ってない)
    • offerbox (あんま使ってない)
    • athletics (あんま使ってない)
    • Labbase (あんま使ってない)
  • イベント系
    • conpass (ちょっと使った)
    • サポーターズ (見てすらない)
    • エンジニアEXPO (見てすらない)
    • 高専のやつ (一回参加した)
  • 過去の選考・質問まとめ
    • unistyle (いらんの一緒に登録されるけど良いサイト)

流れ(日程)

まずはエントリーから内定?までの流れ
エンジニアなので、技術面接があります。こんな感じ

  • 書類選考 (+ コーディングテストとかの技術テスト)
  • 一次(技術)面接
  • 二次面接
  • 最終面接

いくつステップを踏むかは企業によると思いますが、自分はだいたいこうでした。

次にそもそもの就活の流れ(体感です)

  • 夏のインターンが内定に直結するところもある
  • 秋ぐらいから早期選考が増える。もっと早いところはこのときで終わってる
  • 早期じゃない選考(就活解禁?) 春

ここから先は受けてないから知らない

その他

相談をどうしたか

  • 国語の先生と、研究室の先生にした
    • 国語 : おおまかな書き方を聞く
    • 選考状況を話して、自分の考えがあっているか聞く

早めにやってて悪いことはないので、早めに動くといいんじゃないでしょうか

あと、明石はインターンを4年で行けば単位貰えるけど

  • 正味、就職予定の人は3年の夏・冬も行ったほうがいいんじゃとは思う
  • 自分はそれで失敗した(4年の夏にseccampに行った)

 

追加してほしい内容とかあったらtwitterでどうぞ。

picoCTF 2022 Writeup

はじめに

メンバーはshiratakiさんと、ny_aさんです。僕の勝手なイメージでshiratakiさんはpwn系、ny_aさんはweb、crypto系だと思っていたのでいいチームバランスだと思っていました。
僕がやるつもりだったのはrevです。

チームはsokusekiです。即席結成なので、このチーム名にしました。(決して煽りではありません。)

合計で13100点を獲得し、80位です。個人では(横取りしてしまったのもありますが)、4600点を獲得しました。3人同じくらいの点数を取っているのでいい具合に助け合えたかなと思っています。(もうこいつとは組まんと思われていなければ幸いです。)

客観的に見て、revは去年に比べて簡単になったと思います。forensicsは去年ほどguessが多くなかった?ように思います。うーん。

良い結果を残せたと思います。では、自身が通した+手伝った問題のwriteupを書きます。

メンバーのWriteup(追記する予定)

Reversing

file-run1(100pt)

$ strings run | grep pico

flag : picoCTF{U51N6_Y0Ur_F1r57_F113_e5559d46}

file-run2(100pt)

$ strings run | grep pico

flag : picoCTF{F1r57_4rgum3n7_96f2195f}

何がしたいんだ

GDB Test Drive

$ chmod +x gdbme

$ gdb -q gdbme

$ start
$ disas
main + 99はsleep関数を呼んでいるよう。なので、ここにbreak pointを貼るみたいですね

$ b *(main+99)
$ r
$ jump *(main+104)

flag : picoCTF{d3bugg3r_dr1v3_72bd8355}

patchme.py(100pt)

pythonのファイルとエンコードされたflagが配布される。
プログラムを実行するとパスワードを求めてきた。

プログラムを見ると改行されて見づらくなった比較文字列がある。(下は改行をなくしたもの

if( user_pw == "ak98-=90adfjhgj321sleuth9000"):

これを入力するとflagを得る。

flag : picoCTF{p47ch1ng_l1f3_h4ck_f01eabfa}

Safe Opener(100pt)

今度はjavaのファイル。プログラム内部にはbase64という言葉とbase64 encodeされてそうな文字列がある。

String encodedkey = "cGwzYXMzX2wzdF9tM18xbnQwX3RoM19zYWYz";

cyber chefで復元。問題分はpicoCTF{password}となっているので、この復元した文字列を中に入れたら良い。

flag : picoCTF{pl3as3_l3t_m3_1nt0_th3_saf3}

unpackme.py(100pt)

pythonのプログラム。payloadがdecryptされて、最後のexecで実行されるよう。

つまり、そのdecrypt結果を見れば内容が分かる。

# 上にはコードがある

plain = f.decrypt(payload) print(plain) # exec(plain.decode())

結果が

b"\npw = input('What\\'s the password? ')\n\nif pw == 'batteryhorse':\n  print('picoCTF{175_chr157m45_cd82f94c}')\nelse:\n  print('That password is incorrect.')\n\n"

flag : picoCTF{175_chr157m45_cd82f94c}

bloat.py(200pt)

pythonファイルとencodeされたflag.txt

今回は難読化と言っていいか分からないけどprintableな文字列をaという配列に代入し、添字を用いて文字列を表現していた。

見やすくなるよう、適宜コード間に改行を挟む。

  • arg132はflag.txt.encを読み出す
  • arg232は入力を受け取る -> arg432に代入する
  • arg432をarg133で比較する

arg133の比較対象を見ればいい。適当に手元のshellでpythonを起動。

a = "string.pritableな文字列たち"
a[71]+a[64]+a[79]+a[79]+a[88]+a[66]+a[71]+a[64]+a[77]+a[66]+a[68]

結果はhappychanceだったので、これを入力する。

flag : picoCTF{d30bfu5c4710n_f7w_161a4f09}

Fresh Java(200pt)

javajavaだけど、classになっている。こういう系はbytecode-viewerで見ます。

見る。ここには入力をけつから見ていくコードがありその比較対象はflagだということが分かる。一文字づつ打ってみたけどなんか弾かれたので、このコードをコピペしてパースを行った。

べちゃってコード貼っちゃいます。

  • KeygenMe.classの中身
import java.util.Scanner;

public class KeygenMe {
   public static void main(String[] var0) {
      Scanner var1 = new Scanner(System.in);
      System.out.println("Enter key:");
      String var2 = var1.nextLine();
      if (var2.length() != 34) {
         System.out.println("Invalid key");
      } else if (var2.charAt(33) != '}') {
         System.out.println("Invalid key");
      } else if (var2.charAt(32) != 'e') {
         System.out.println("Invalid key");
      } else if (var2.charAt(31) != 'b') {
         System.out.println("Invalid key");
      } else if (var2.charAt(30) != '6') {
         System.out.println("Invalid key");
      } else if (var2.charAt(29) != 'a') {
         System.out.println("Invalid key");
      } else if (var2.charAt(28) != '2') {
         System.out.println("Invalid key");
      } else if (var2.charAt(27) != '3') {
         System.out.println("Invalid key");
      } else if (var2.charAt(26) != '3') {
         System.out.println("Invalid key");
      } else if (var2.charAt(25) != '9') {
         System.out.println("Invalid key");
      } else if (var2.charAt(24) != '_') {
         System.out.println("Invalid key");
      } else if (var2.charAt(23) != 'd') {
         System.out.println("Invalid key");
      } else if (var2.charAt(22) != '3') {
         System.out.println("Invalid key");
      } else if (var2.charAt(21) != 'r') {
         System.out.println("Invalid key");
      } else if (var2.charAt(20) != '1') {
         System.out.println("Invalid key");
      } else if (var2.charAt(19) != 'u') {
         System.out.println("Invalid key");
      } else if (var2.charAt(18) != 'q') {
         System.out.println("Invalid key");
      } else if (var2.charAt(17) != '3') {
         System.out.println("Invalid key");
      } else if (var2.charAt(16) != 'r') {
         System.out.println("Invalid key");
      } else if (var2.charAt(15) != '_') {
         System.out.println("Invalid key");
      } else if (var2.charAt(14) != 'g') {
         System.out.println("Invalid key");
      } else if (var2.charAt(13) != 'n') {
         System.out.println("Invalid key");
      } else if (var2.charAt(12) != '1') {
         System.out.println("Invalid key");
      } else if (var2.charAt(11) != 'l') {
         System.out.println("Invalid key");
      } else if (var2.charAt(10) != '0') {
         System.out.println("Invalid key");
      } else if (var2.charAt(9) != '0') {
         System.out.println("Invalid key");
      } else if (var2.charAt(8) != '7') {
         System.out.println("Invalid key");
      } else if (var2.charAt(7) != '{') {
         System.out.println("Invalid key");
      } else if (var2.charAt(6) != 'F') {
         System.out.println("Invalid key");
      } else if (var2.charAt(5) != 'T') {
         System.out.println("Invalid key");
      } else if (var2.charAt(4) != 'C') {
         System.out.println("Invalid key");
      } else if (var2.charAt(3) != 'o') {
         System.out.println("Invalid key");
      } else if (var2.charAt(2) != 'c') {
         System.out.println("Invalid key");
      } else if (var2.charAt(1) != 'i') {
         System.out.println("Invalid key");
      } else if (var2.charAt(0) != 'p') {
         System.out.println("Invalid key");
      } else {
         System.out.println("Valid key");
      }
   }
  • parseのコード
import re

with open('コピペしたファイル', 'r') as f:
    code = f.read()

flag_dat = re.findall(r"\'.\'", code)
for i in range(len(flag_dat)-1, -1, -1):
    print(flag_dat[i][1], end = "")

flag : picoCTF{700l1ng_r3qu1r3d_9332a6be}

Bbbbloat(300pt)

elfファイル
実行すると数を求めてくる。Ghidraで解析

entry部の最初の関数 FUN_00101307がmain。
関数を見ると、直で比較している値がある -> 0x86187

hexで書かれているけど、入力はちゃんと10進数で

flag : picoCTF{cu7_7h3_bl047_695036e3}

unpackme(300pt)

elfファイルだけど、名前の通りupxでパックされているみたい。

$ upx -d unpackme-upx

実行すると、また数を求めてくる。Bbbbloatと同じ。
値は0xb83cb

flag : picoCTF{up><_m3_f7w_e510a27f}

Keygenme(400pt)

main関数の挙動

  • 入力を受け取る(0x25)
  • checker渡す
  • その結果でinvalidかvalidが出力される

checkerの挙動

  • 比較対象の生成
  • まずは、長さの比較(0x24)
  • 次に、一文字づつ比較対象と比較

以上から、まず入力は0x24でないとお話にならないことが分かります。

一文字づつ比較するということから、最近解いていたこの問題を思い出しました。

https://tsalvia.hatenablog.com/entry/2021/04/08/110000#Easy-as-GDB---160-points

なので、gdbを用いた総当りを試そうと思いました(コードは適宜調整)。
しかし、入力の受け取り方が上記の問題と異なるためデータの入力がうまく行きませんでした。なので、コードを用いた総当りは断念しました。

時間を置いて考え直しました。
まず、上記のコードではifが通った回数(そこにbreak pointを貼る)を数えることで適切な入力データを導きます。しかし、その手前でbreak pointを貼れば比較する瞬間・比較対象を見れるのではないかと思いました。

細かいアドレスの調整・gdbとghidraの差の計算はすっとばして、僕は次のようにしました。

$ gdb -q ./keygenme
$ b *0x555555555411
$ run
ここで、入力を手動で入れる : flagの一部+"A" * ( 0x24 - len( flagの一部 ) )
そして、break pointで止まります。
$ n <- これを複数回

すると、次のような部分まで進みます

f:id:Bigdrea6:20220317204410p:plain

RAXが比較対象、RDXが入力データです。

ここで、flagをメモリつつ(flagの一部を更新して、入力データを新しくする)
$ c
$ run

を繰り返します。

RAXにはときおりノイズが入ります。早とちりしてそれをflagに含めないようにします。

flag : picoCTF{br1ng_y0ur_0wn_k3y_abb48a6c}

Wizardlike(500pt)

サポート強。迷路風なゲームです。

静的解析すると10階層であることが分かります。また、マップは文字列として直に埋め込まれています。

~チームメイトパート~
discordで、gdbで現在地(マップ上でのx、y座標と階層)をいじる方法を教えてくれました。
詳しいことはチームメイトのwriteupで書いてくれるのではと思っています。

マップ外に自身を配置することで、flagの一部をゲットしていました。

~自分のパートに戻ります~
教えを受けたので、他のマップを見てみますがかなり時間がかかりました。そこで、次のような解法をすることにしました。

  1. 階層の移動をgdbで行う
  2. 一部のマップとghidraから取ってきたマップを比較
  3. 全体のマップを作り上げる

はい。10回地道にやるだけです。

flag : picoCTF{ur_4_w1z4rd_1496299E}

Forensics

Enhance!(100pt)

ちゃんとsvgsvgファイルが配られる。

$ strings drawing.flag.svg

分割されたflagがある。

flag : picoCTF{3nh4nc3d_24374675}

File types(100pt)

サポート強。自分でやったのだけ書きます。

discordにて

7069636f4354467b66316c656e406d335f6d406e3170756c407431306e5f
6630725f3062326375723137795f37396230316332367d0a

なにこれは

ふむ。この問題ではmd5の話もあったので、md5かなと思ってbit数を調べるが違う。
脳死でlong_to_bytesです。

flag : picoCTF{f1len@m3_m@n1pul@t10n_f0r_0b2cur17y_79b01c26}

Lookey here(100pt)

$ strings anthem.flag.txt | grep pico

flag : picoCTF{gr3p_15_@w3s0m3_58f5c024}

Packets Primer(100pt)

wiresharkで見ます。

4番目のパケットにflagがあります。

flag : picoCTF{p4ck37_5h4rk_b9d5375}

Redaction gone wrong(100pt)

pdfのpdfファイルが配られます。黒で隠された部分をコピペしてみると、見えます。

flag : picoCTF{C4n_Y0u_S33_m3_fully}

Sleuthkit Intro(100pt)

disk imageにmmlsをします。
$ mmls disk.img

ncすると、求めてくるのはLength in sectors
mmlsで出てきた202752を打ちます。

flag : picoCTF{mm15_f7w!}

Sleuthkit Apprentice(200pt)

今回はflag.txtを修復する系。自分はFTK imagerが使い慣れているので、それを使いました。

3つ目のLinuxの中を覗く

root -> root -> my_folder -> flag.uni.txt

flag : picoCTF{by73_5urf3r_adac6cb4}

St3go(300pt)

pngpngファイルが配られます。

$ zsteg -a pico.flag.png

flag : picoCTF{7h3r3_15_n0_5p00n_a1062667}

Torrent Analyze(400pt)

pcapのファイルが渡されます。
ヒントでbt-dhtとか見れるようにしとけよと言われます。

wiresharkで見ててもよく分からんので、jsonに吐き出してエディタで見てました。
bt-dhtの中にもいくつか情報があるみたいで、info_hashが一番目を引きました。

(引きましたといっても結構時間溶かした後にです。)

info_hashは7つほどあり、その中でも重複して呼ばれるhashがありました。

"e2467cbf021192c241367b892230dc1e05c0580e"

これを調べると、以下のURLにたどりつきます。
ubuntu-19.10-desktop-amd64.iso at Linuxtracker

このファイルが答えです。

flag : picoCTF{ubuntu-19.10-desktop-amd64.iso}

Web

Roboto Sans(200pt)

robotとあるので、脳死robots.txtをurlに貼り付けます。

robots.txtは次のような内容でした。

User-agent *
Disallow: /cgi-bin/
Think you have seen your flag or want to keep looking.

ZmxhZzEudHh0;anMvbXlmaW
anMvbXlmaWxlLnR4dA==
svssshjweuiwl;oiho.bsvdaslejg
Disallow: /wp-admin/

真ん中のbase64 encodeされた文字列を復号すると、
js/myfile.txtとなり、ここに移動するとflagを得ます。

flag : picoCTF{Who_D03sN7_L1k5_90B0T5_22ce1f22}

Crypto

credstuff

手伝った。

分からんと、エンコードされたflagが送られてきたのでシーザーっぽいですと

合ってたようです。

Substitution1(100pt)

単一換字暗号って言うんだっけ、メンバーが解けてそうだったんだけどflagが通らないと言っていたので改めてやってみるとちょっとミスがあったみたいだった。

flag : picoCTF{FR3QU3NCY_4774CK5_4R3_C001_7AA384BC}

Very Smooth(300pt)

これは解いたと言っていいのか分からない。メンバーがsmoothなrsaです。と言っていたので調べてみると次がヒット。

blog.csdn.net

コードを拝借。答えでた。

flag : picoCTF{7c8625a1}

Sum-O-Primes

手伝った。p*qとp+qが与えられているということで、何かできないかなぁと調べていると次がヒット。

math.stackexchange.com

手元で計算してみても正しい計算方法だったので、pythonでやってみるけどコードが動かない。ほっちっちにして、このURLだけ共有していたらメンバーが解いてくれた。

bcってやつを使うといいらしい。ほえー