土日の勉強ノート

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

書籍「解題pwnable」の第1章「準備」を読んだ

前回 までは、「詳解セキュリティコンテスト: CTFで学ぶ脆弱性攻略の技術 Compass Booksシリーズ」を読み進めてきました。ようやく読み終わったので、今回からは、「解題pwnable セキュリティコンテストに挑戦しよう! 技術の泉シリーズ (技術の泉シリーズ(NextPublishing))」を読んでいきます。

全体で、140ページぐらいで、第1章から第12章まであります。

今回は、第1章の「準備」を読んでいきたいと思います。

それでは、やっていきます。

参考文献

今回、題材にさせて頂いた「解題pwnable」です。

はじめに

「セキュリティ」の記事一覧です。良かったら参考にしてください。

セキュリティの記事一覧
・第1回:Ghidraで始めるリバースエンジニアリング(環境構築編)
・第2回:Ghidraで始めるリバースエンジニアリング(使い方編)
・第3回:VirtualBoxにParrotOS(OVA)をインストールする
・第4回:tcpdumpを理解して出力を正しく見れるようにする
・第5回:nginx(エンジンエックス)を理解する
・第6回:Python+Flask(WSGI+Werkzeug+Jinja2)を動かしてみる
・第7回:Python+FlaskのファイルをCython化してみる
・第8回:shadowファイルを理解してパスワードを解読してみる
・第9回:安全なWebアプリケーションの作り方(徳丸本)の環境構築
・第10回:Vue.jsの2.xと3.xをVue CLIを使って動かしてみる(ビルドも行う)
・第11回:Vue.jsのソースコードを確認する(ビルド後のソースも見てみる)
・第12回:徳丸本:OWASP ZAPの自動脆弱性スキャンをやってみる
・第13回:徳丸本:セッション管理を理解してセッションID漏洩で成りすましを試す
・第14回:OWASP ZAPの自動スキャン結果の分析と対策:パストラバーサル
・第15回:OWASP ZAPの自動スキャン結果の分析と対策:クロスサイトスクリプティング(XSS)
・第16回:OWASP ZAPの自動スキャン結果の分析と対策:SQLインジェクション
・第17回:OWASP ZAPの自動スキャン結果の分析と対策:オープンリダイレクト
・第18回:OWASP ZAPの自動スキャン結果の分析と対策:リスク中すべて
・第19回:CTF初心者向けのCpawCTFをやってみた
・第20回:hashcatの使い方(GPU実行時間の見積りとパスワード付きZIPファイル)
・第21回:Scapyの環境構築とネットワークプログラミング
・第22回:CpawCTF2にチャレンジします(クリア状況は随時更新します)
・第23回:K&Rのmalloc関数とfree関数を理解する
・第24回:C言語、アセンブラでシェルを起動するプログラムを作る(ARM64)
・第25回:機械語でシェルを起動するプログラムを作る(ARM64)
・第26回:入門セキュリhttps://github.com/SECCON/SECCON2017_online_CTF.gitティコンテスト(CTFを解きながら学ぶ実践技術)を読んだ
・第27回:x86-64 ELF(Linux)のアセンブラをGDBでデバッグしながら理解する(GDBコマンド、関連ツールもまとめておく)
・第28回:入門セキュリティコンテスト(CTFを解きながら学ぶ実践技術)のPwnable問題をやってみる
・第29回:実行ファイルのセキュリティ機構を調べるツール「checksec」のまとめ
・第30回:setodaNote CTF Exhibitionにチャレンジします(クリア状況は随時更新します)
・第31回:常設CTFのksnctfにチャレンジします(クリア状況は随時更新します)
・第32回:セキュリティコンテストチャレンジブックの「Part2 pwn」を読んだ
・第33回:セキュリティコンテストチャレンジブックの「付録」を読んでx86とx64のシェルコードを作った
・第34回:TryHackMeを始めてみたけどハードルが高かった話
・第35回:picoCTFを始めてみた(Beginner picoMini 2022:全13問完了)
・第36回:picoCTF 2024:Binary Exploitationの全10問をやってみた(Hardの1問は後日やります)
・第37回:picoCTF 2024:Reverse Engineeringの全7問をやってみた(Windowsプログラムの3問は後日やります)
・第38回:picoCTF 2024:General Skillsの全10問をやってみた
・第39回:picoCTF 2024:Web Exploitationの全6問をやってみた(最後の2問は解けず)
・第40回:picoCTF 2024:Forensicsの全8問をやってみた(最後の2問は解けず)
・第41回:picoCTF 2024:Cryptographyの全5問をやってみた(最後の2問は手つかず)
・第42回:picoCTF 2023:General Skillsの全6問をやってみた
・第43回:picoCTF 2023:Reverse Engineeringの全9問をやってみた
・第44回:picoCTF 2023:Binary Exploitationの全7問をやってみた(最後の1問は後日やります)
・第45回:書籍「セキュリティコンテストのためのCTF問題集」を読んだ
・第46回:書籍「詳解セキュリティコンテスト」のReversingを読んだ
・第47回:書籍「詳解セキュリティコンテスト」のPwnableのシェルコードを読んだ
・第48回:書籍「バイナリファイル解析 実践ガイド」を読んだ
・第49回:書籍「詳解セキュリティコンテスト」Pwnableのスタックベースエクスプロイトを読んだ
・第50回:書籍「詳解セキュリティコンテスト」Pwnableの共有ライブラリと関数呼び出しを読んだ
・第51回:picoCTF 2025:General Skillsの全5問をやってみた
・第52回:picoCTF 2025:Reverse Engineeringの全7問をやってみた
・第53回:picoCTF 2025:Binary Exploitationの全6問をやってみた
・第54回:書籍「詳解セキュリティコンテスト」Pwnableの仕様に起因する脆弱性を読んだ
・第55回:システムにインストールされたものと異なるバージョンのglibcを使う方法
・第56回:書籍「詳解セキュリティコンテスト」Pwnableのヒープベースエクスプロイトを読んだ
・第57回:書籍「解題pwnable」の第1章「準備」を読んだ ← 今回

以下は、の公式サイトです。特に追加の情報はありませんでした。

nextpublishing.jp

また、以下は、「解題pwnable セキュリティコンテストに挑戦しよう! 技術の泉シリーズ (技術の泉シリーズ(NextPublishing))」の公式の Docker Hub です。書籍では、tag として、3 を使っていますが、4 がアップされています。とりあえず、3 を使ってやっていきます。

https://hub.docker.com/r/kusanok/ctfpwn

では、書籍の章を参考に書き進めていきます。

第1章:準備

1.1:問題サーバの準備

環境は、Parrot OS 6.1 です。Docker は、自分ではインストールした記憶がないのですが、試しに、Docker を実行してみると、既にインストールされているようです。

本家の Docker ではなく、Podman という Docker互換のエミュレータ?がインストールされているようです。Podman は知らなかったのですが、root じゃなくても実行できる、デーモンではない、などの特徴のようです。

$ docker -v
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
podman version 4.3.1

まずは、書籍の最初に、以下のコマンドが書かれてるので、実行してみます。

エラーが出ました。

$ docker run --rm -it -p 10080:80 -p 10001-10013:10001-10013 kusanok/ctfpwn:3
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
Error: short-name "kusanok/ctfpwn:3" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

Podman は、短い名前(kusanok/ctfpwn:3)の場合は、設定が必要なようです。正式な名前を設定すればいいようです。正式名(docker.io/kusanok/ctfpwn:3)を指定すると、正常に実行できたようです。

$ docker run --rm -it -p 10080:80 -p 10001-10013:10001-10013 docker.io/kusanok/ctfpwn:3
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
Trying to pull docker.io/kusanok/ctfpwn:3...
Getting image source signatures
Copying blob e7cb79d19722 done  
Copying blob 4e280afd9780 done  
Copying blob 323d0d660b6a done  
Copying blob 3ff22d22a855 done  
Copying blob b7f616834fd0 done  
Copying blob 651a3c01bb06 done  
Copying blob 4bde72ab9496 done  
Copying blob 72f19bdb2e8d done  
Copying blob 4e224cbd8473 done  
Copying blob 4b0f5d2e446f done  
Copying blob b562778600c4 done  
Copying blob 0229a0981ca2 done  
Copying blob 8609aee5f00e done  
Copying blob 6cd7991e5983 done  
Copying config 2abac598f3 done  
Writing manifest to image destination
Storing signatures
 * Starting internet superserver xinetd                                                                                                                                                                                                                                  [ OK ] 
 * Starting nginx nginx                                                                                                                                                                                                                                                  [ OK ] 
open http://localhost/

Parrot OS のブラウザ(Firefox)で、http://localhost/ を開いてみます。あ、書籍を見ると、http://localhost:10080 でした。

うーん、「This address is restricted」と言われて、アクセスできません。chromium でやってみましたが、アクセスできません。curl で確認してみます。反応があるような気がします。

$ curl http://localhost:10080
<!doctype html>
<html>
  <head>
    <title>Malleus CTF Pwn Challenge</title><meta data-n-head="1" charset="utf-8"><meta data-n-head="1" name="viewport" content="width=device-width,initial-scale=1"><meta data-n-head="1" data-hid="description" name="description" content="Malleus CTF Pwn Practice"><link data-n-head="1" rel="icon" type="image/png" href="/favicon.png"><link data-n-head="1" rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&display=swap"><link data-n-head="1" rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css"><link rel="preload" href="/_nuxt/runtime.2d43a49.js" as="script"><link rel="preload" href="/_nuxt/node_modules/commons.1a40dd4.js" as="script"><link rel="preload" href="/_nuxt/app.c569442.js" as="script">
  </head>
  <body>
    <div id="__nuxt"><style>#nuxt-loading{background:#fff;visibility:hidden;opacity:0;position:absolute;left:0;right:0;top:0;bottom:0;display:flex;justify-content:center;align-items:center;flex-direction:column;animation:nuxtLoadingIn 10s ease;-webkit-animation:nuxtLoadingIn 10s ease;animation-fill-mode:forwards;overflow:hidden}@keyframes nuxtLoadingIn{0%{visibility:hidden;opacity:0}20%{visibility:visible;opacity:0}100%{visibility:visible;opacity:1}}@-webkit-keyframes nuxtLoadingIn{0%{visibility:hidden;opacity:0}20%{visibility:visible;opacity:0}100%{visibility:visible;opacity:1}}#nuxt-loading>div,#nuxt-loading>div:after{border-radius:50%;width:5rem;height:5rem}#nuxt-loading>div{font-size:10px;position:relative;text-indent:-9999em;border:.5rem solid #f5f5f5;border-left:.5rem solid #fff;-webkit-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-animation:nuxtLoading 1.1s infinite linear;animation:nuxtLoading 1.1s infinite linear}#nuxt-loading.error>div{border-left:.5rem solid #ff4500;animation-duration:5s}@-webkit-keyframes nuxtLoading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes nuxtLoading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}</style><script>window.addEventListener("error",function(){var e=document.getElementById("nuxt-loading");e&&(e.className+=" error")})</script><div id="nuxt-loading" aria-live="polite" role="status"><div>Loading...</div></div></div><script>window.__NUXT__={config:{},staticAssetsBase:void 0}</script>
  <script src="/_nuxt/runtime.2d43a49.js"></script><script src="/_nuxt/node_modules/commons.1a40dd4.js"></script><script src="/_nuxt/app.c569442.js"></script></body>
</html>

いろいろ調べたところ、「This address is restricted」と言われた場合、特殊なポートなどはアクセス制限がされているとのことです。URL に about:config を入力して、許可するポートの範囲を設定するため、検索ボックスに network.security.ports.banned.override を入力します。String にチェックを入れて、+ボタンを押します。そして、1-12000 として、チェックボタンを押して、有効にします。すると、ようやくアクセスできました。

問題の一覧
問題の一覧

1.2:攻撃用の環境の準備

先ほど、アクセスを確認したものを「問題サーバー」と呼ぶようです。ここでは、問題サーバーへのアクセスを確認します。

問題なく、アクセスできました。

$ nc localhost 10001
ID: aaa
Password: bbb
Invalid ID or password

また、書籍で使用する「pwntools」のインストール方法が説明されています。私は既にインストール済みですが、以下のように、インストール方法が説明されていました。

$ sudo pip3 install pwntools

1.3:解析用サーバーの準備とツールの使用法

ここでは、解析用サーバーの準備が説明されています。私の場合は、問題サーバーは、先ほど起動した Dockerコンテナで、解析用サーバーは、Parrot OS とします。

問題サーバーは、Ubuntu 20.04 で、glibc 2.31 とのことなので、以下の記事で、Parrot OS 6.1 で、glibc 2.31 を動作させる方法を構築したので、それを使います。

daisuke20240310.hatenablog.com

あとは、objdump、GDB、PEDA、pwngdb が紹介されています。PEDA と pwngdb は、GDB のプラグインです。私は、pwndbg を使います。

また、checksec、socat、One-Gadget RCE、GCC が紹介されています。One-Gadget RCE は、「詳解セキュリティコンテスト: CTFで学ぶ脆弱性攻略の技術 Compass Booksシリーズ」でも紹介されていましたが、Ruby を使うということで、環境構築が面倒ということでスルーしました。必要になったら、インストールすることにします。

以上で、第1章「準備」は終了です。

おわりに

今回から「解題pwnable セキュリティコンテストに挑戦しよう! 技術の泉シリーズ (技術の泉シリーズ(NextPublishing))」を読み始めました。今回は、第1章「準備」ということで、少し短かったですが、この書籍でも、これまでと同じ環境で問題ないということだと思います。

次回は、第2章「login1(スタックバッファオーバーフロー1)」を進める予定です。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。