Skip to content

Commit d715a09

Browse files
committed
Merge branch 'master' of https://github.com/rev112/stepctf-2015
2 parents 7d4e51b + 3e98817 commit d715a09

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+450
-30
lines changed

ASR/summary.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ answer_regex: STCTF#Dang3r0u51R5AMay83Vu1n3ra813#
33
author: patrick
44
category: crypto
55
description: |
6-
Папа, будучи в коммандировке, оставил Кириллу послание с ключом от сейфа.
7-
В сейфе лежат золотые монеты, которые Кирилл может потратить, если сумеет отгадать, как расшифровать приложенное сообщение.
6+
Папа, будучи в командировке, оставил Кириллу послание с ключом от сейфа.
7+
В сейфе лежат золотые монеты, которые Кирилл может потратить, если сумеет отгадать, как расшифровать приложенное сообщение. Ключик в помощь.
88
name: ASR
99
price: 300

Catless/create/bootstrap.sh

+26-12
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

3-
rm -f \
4-
/bin/less /usr/bin/tail* /usr/bin/head /bin/*grep* \
5-
/usr/bin/*grep* /etc/alternatives/v* /usr/bin/xxd \
6-
/usr/bin/python* /bin/cat /usr/bin/perl* /usr/bin/vi* /bin/more \
7-
/bin/sed /usr/bin/*diff* /usr/bin/curl /usr/bin/wget /usr/bin/base64 \
8-
/bin/nc* /bin/netcat /usr/bin/nano /bin/nano /usr/bin/sort \
9-
/usr/bin/awk /bin/echo
3+
# sudo apt-get update && sudo apt-get install -y sl cowsay
104

11-
# /usr/bin/cut?
12-
# /usr/bin/nl?
135

146
# Greeting
15-
echo '### Welcome home! ###' > /.box/.greeting
7+
echo '< Welcome home >
8+
--------------
9+
\ ^__^
10+
\ (oo)\_______
11+
(__)\ )\/\
12+
||----w |
13+
|| ||
14+
' > /home/box/.greeting; chown box /home/box/.greeting
15+
16+
1617

1718
# Update bashrc
19+
echo 'tac /home/box/.greeting 2> /dev/null | tac; rm -f /home/box/.greeting' >> /home/box/.bashrc
1820
echo 'alias echo=/bin/echo' >> /home/box/.bashrc
21+
# echo 'alias ls=sl' >> /home/box/.bashrc
1922

20-
23+
# Write the flag
2124
echo "Noooo, you've managed to read me!
2225
2326
Ok, here's the flag: STCTF#l1nvxH4sN1ceStvff#
@@ -26,3 +29,14 @@ Ok, here's the flag: STCTF#l1nvxH4sN1ceStvff#
2629
# Remove sudo
2730
rm -f /etc/sudoers.d/box
2831

32+
# Remove programs
33+
rm -f \
34+
/bin/less /usr/bin/tail* /bin/tail* /usr/bin/head /bin/*grep* /usr/bin/tmux \
35+
/usr/bin/*grep* /etc/alternatives/v* /usr/bin/xxd /usr/bin/strings \
36+
/usr/bin/python* /bin/cat /usr/bin/perl* /usr/bin/vi* /bin/more \
37+
/bin/sed /usr/bin/*diff* /usr/bin/curl /usr/bin/wget /usr/bin/base64 \
38+
/bin/nc* /bin/netcat /usr/bin/nano /bin/nano /bin/echo /usr/bin/sort /usr/bin/awk
39+
40+
# /usr/bin/cut?
41+
# /usr/bin/nl?
42+

FMS/create/Dockerfile

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM ubuntu:14.04
2+
3+
RUN apt-get install -y nmap
4+
5+
COPY FMS run.sh flag.txt /
6+
CMD /run.sh

FMS/create/FMS

7.78 KB
Binary file not shown.

FMS/create/run.sh

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/bin/bash
2-
2+
/bin/echo 0 > /proc/sys/kernel/randomize_va_space
33
port=1234
44

5-
make main
6-
ncat -lp $port -ke ./main
5+
ncat -lp $port -ke ./FMS

FMS/summary.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ description: |
88
Will it make it easier on you now
99
If you've got someone to blame
1010
name: FMS
11-
price: 150
11+
price: 200

FeedDaPanda/create/feeddapanda.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#! /bin/bash
22

3-
sudo docker kill web100
4-
sudo docker rm web100
5-
sudo docker build -t patrick/web100 .
6-
sudo docker run -d --name web100 -p 127.0.0.1:13371:8080 patrick/web100
3+
sudo docker kill feeddapanda
4+
sudo docker rm feeddapanda
5+
sudo docker build -t patrick/feeddapanda .
6+
sudo docker run -d --name feeddapanda patrick/feeddapanda

FeedDaPanda/summary.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ author: patrick
44
category: web
55
description: |
66
Артуру нравились панды, поэтому он подкармливал их, и за это, они рассказывали ему все свои секреты.
7-
Мы обнаружили следы панд здесь: http://server:13371.
7+
Мы обнаружили следы панд здесь: feeddapanda.2015.ppctf.net
88
name: FeedDaPanda
9-
price: 100
9+
price: 200

IDontEven/summary.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ answer_regex: STCTF#aaaaad#
33
author: ZetsubouClown
44
category: reverse
55
description: |
6-
6+
Я слишком ленив, чтобы придумать описание для этой задачи. Не слишком ли вы ленивы, чтобы решить её?
77
name: I Don't Even
88
price: 100

NoisyNeighbor/create/README.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# NoisyNeighbor
2+
3+
## RF Transmitter
4+
![RF Transmitter](transmitter.jpg)
5+
Радиопередатчик 433 МГц, подключенный к Raspberry Pi:
6+
7+
## RF Receiver
8+
![RF Receiver](receiver.jpg)
9+
Радиоприемник 433 МГц, подключенный через резистор в микрофонный вход аудиокарты:
10+
11+
## Signal Generation
12+
На Raspberry Pi компилируем `trisend.cpp`, для сборки нужна библиотека [433Utils](https://github.com/ninjablocks/433Utils). `trisend` посылает tri-state последовательности, которыми кодируются команды rf пультов.
13+
14+
Запускаем скрипт `rf_broadcast.py`, который сначала посылает случайные команды со случайным интервалом между ними. Потом посылает команды вида `FFFFFxxxxxxx`, где `xxxxxxx` -- 7 бит `0` или `1`, представляющих ascii коды флага. После флага опять посылает случайные команды.
15+
16+
## Signal Sniffing
17+
На машине, к которой подключен rf приемник, запускаем [Audacity](http://sourceforge.net/projects/audacity/) и включаем запись с микрофонного входа.

NoisyNeighbor/create/receiver.jpg

683 KB
Loading

NoisyNeighbor/create/rf_broadcast.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env python3
2+
import random
3+
import subprocess
4+
5+
from time import sleep
6+
7+
8+
FLAG = 'STCTF#uN1oCKd00r#'
9+
10+
MAX_COMMAND_INTERVAL = 10
11+
12+
13+
def char2tristate(char):
14+
return 'FFFFF{0:07b}'.format(ord(char))
15+
16+
17+
def random_tristate():
18+
return ''.join((random.choice(['0', '1', 'F']) for i in range(12)))
19+
20+
21+
RANDOM_COMMANDS = [random_tristate() for i in range(10)]
22+
23+
24+
def send_tristate(tristate):
25+
subprocess.call(['./trisend', tristate])
26+
27+
28+
def send_random_commands(number):
29+
for i in range(number):
30+
send_tristate(random.choice(RANDOM_COMMANDS))
31+
sleep(random.randrange(MAX_COMMAND_INTERVAL))
32+
33+
34+
print("# Sending random commands")
35+
send_random_commands(23)
36+
37+
print("# Sending FLAG commands")
38+
for c in FLAG:
39+
tristate = char2tristate(c)
40+
subprocess.call(['./trisend', tristate])
41+
sleep(random.randrange(MAX_COMMAND_INTERVAL))
42+
43+
print("# Sending random commands")
44+
send_random_commands(12)

NoisyNeighbor/create/transmitter.jpg

600 KB
Loading

NoisyNeighbor/create/trisend.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "RCSwitch.h"
2+
#include <stdlib.h>
3+
#include <stdio.h>
4+
5+
int main(int argc, char *argv[]) {
6+
7+
// This pin is not the first pin on the RPi GPIO header!
8+
// Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/
9+
// for more information.
10+
int PIN = 0;
11+
12+
char* tri_state = argv[1];
13+
14+
if (wiringPiSetup () == -1) return 1;
15+
printf("sending tri_state[%s]\n", tri_state);
16+
RCSwitch mySwitch = RCSwitch();
17+
mySwitch.enableTransmit(PIN);
18+
19+
mySwitch.sendTriState(tri_state);
20+
21+
return 0;
22+
}

NoisyNeighbor/solution/rf_parser.py

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/env python3
2+
import struct
3+
import sys
4+
import wave
5+
6+
7+
FILENAME = sys.argv[1]
8+
9+
TRI_STATE_SEQUENCE_LENGTH = 12
10+
IS_SYNC_BIT_LOW = lambda inter: inter[0] == 0 and 450 < inter[1] < 500
11+
IS_LOW = lambda inter: inter[0] == 0 and 15 < inter[1] < 30
12+
IS_HIGH = lambda inter: inter[0] == 1 and 15 < inter[1] < 30
13+
IS_3LOW = lambda inter: inter[0] == 0 and 45 < inter[1] < 55
14+
IS_3HIGH = lambda inter: inter[0] == 1 and 45 < inter[1] < 55
15+
16+
17+
def read_pulses_sequence(intervals, index, pulses, bit):
18+
if all(is_pulse(inter) for is_pulse, inter in
19+
zip(pulses, intervals[index:index + len(pulses)])):
20+
return bit, index + len(pulses)
21+
return None, None
22+
23+
24+
def read_tri_state_0(intervals, index):
25+
pulses = [IS_HIGH, IS_3LOW, IS_HIGH, IS_3LOW]
26+
return read_pulses_sequence(intervals, index, pulses, '0')
27+
28+
29+
def read_tri_state_1(intervals, index):
30+
pulses = [IS_3HIGH, IS_LOW, IS_3HIGH, IS_LOW]
31+
return read_pulses_sequence(intervals, index, pulses, '1')
32+
33+
34+
def read_tri_state_F(intervals, index):
35+
pulses = [IS_HIGH, IS_3LOW, IS_3HIGH, IS_LOW]
36+
return read_pulses_sequence(intervals, index, pulses, 'F')
37+
38+
39+
def read_tri_state(intervals, index):
40+
read_funcs = [read_tri_state_0, read_tri_state_1, read_tri_state_F]
41+
for read_func in read_funcs:
42+
bit, new_index = read_func(intervals, index)
43+
if bit:
44+
return bit, new_index
45+
return None, None
46+
47+
48+
def read_tri_state_sequence(intervals, index):
49+
sequence = []
50+
for i in range(TRI_STATE_SEQUENCE_LENGTH):
51+
tri_state, index = read_tri_state(intervals, index)
52+
if not tri_state:
53+
return None, None
54+
sequence.append(tri_state)
55+
return ''.join(sequence), index
56+
57+
58+
def read_sync_bit(intervals, index):
59+
if IS_HIGH(intervals[index]) and IS_SYNC_BIT_LOW(intervals[index + 1]):
60+
return True, index + 2
61+
return None, None
62+
63+
64+
wf = wave.open(FILENAME)
65+
66+
signal_intervals = []
67+
signal = 0
68+
signal_length = 0
69+
for i in range(wf.getnframes()):
70+
frame_data = wf.readframes(1)
71+
frame = struct.unpack("<h", frame_data)[0]
72+
new_signal = 1 if frame > 0 else 0
73+
if new_signal == signal:
74+
signal_length += 1
75+
else:
76+
signal_intervals.append((signal, signal_length))
77+
signal = new_signal
78+
signal_length = 1
79+
80+
81+
tri_state_sequences = []
82+
index = 0
83+
while index < len(signal_intervals) - 1:
84+
is_sync_bit, new_index = read_sync_bit(signal_intervals, index)
85+
if not is_sync_bit:
86+
index += 1
87+
continue
88+
index = new_index
89+
#print("# Sync bit:", index)
90+
91+
tri_state_seq, new_index = read_tri_state_sequence(signal_intervals, index)
92+
if tri_state_seq:
93+
tri_state_sequences.append(tri_state_seq)
94+
index = new_index
95+
#print("# Read tri-state:", tri_state_seq)
96+
if tri_state_seq.startswith('FFFFF'):
97+
sys.stdout.write(chr(int(tri_state_seq[5:], 2)))

NoisyNeighbor/solution/solution.html

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Файл noise.wav является записью эфира с радиоприемника с частотой 433 МГц. Это частота имеет большое распространение в радиоуправляемой технике, в том числе в различных управляемых выключателях, розетках и замках для умных домов. Однако в таких системах обычно не используется никакой обратной связи от стороны приема, и сигнал, как правило, никак не шифруется. Таким образом, система подвержена прослушиванию и replay-атакам.
2+
3+
При передаче сигнала RF пультом используется амплитудная модуляция сигнала (ASK)[http://en.wikipedia.org/wiki/Amplitude-shift_keying]. Одно нажатие на кнопку RF пульта -- это обычно посылка серии одинаковых tri-state последовательностей, состоящая из 12 бит `0`, `1` или `F` (https://code.google.com/p/rc-switch/wiki/KnowHow_LineCoding). Каждый из трех битов модулируется амплитудой сигнала (восемь импульсов). Последовательности в серии разделяются битом синхронизации.
4+
5+
Предложенный файл можно открыть в Audacity (http://sourceforge.net/projects/audacity/) и нормализовать (Effect -> Normalize), чтобы нагляднее видеть изменения амплитуды цифрового сигнала. Кстати, просто проиграв wav файл, даже на слух среди шума можно услышать места, где передаются команды пульта. Пробуем записать вручную импульсы сигнала и видим, что он всегда состоит из шаблонов:
6+
10001000 - 0
7+
11101110 - 1
8+
10001110 - F
9+
это и есть tri-state биты последовательностей.
10+
11+
В начале файла записаны случайные команды, в середине можно отыскать 17 подряд идущих последовательностей виды FFFFFxxxxxxx, где xxxxxxx -- 7 бит `0` или `1`, представляющих ascii коды флага. После флага снова идут случайные RF команды.
12+
13+
Для автоматизации решения пишем скрипт, который извлечет нужные последовательности из аудио файла:
14+
15+
./rf_parser.py noise.wav
16+
SSSSTTTTTCCCCCTTTTTTFFF####uuuuuNNN1111ooooooCCCCKKKKKdddddd0000000000rrr#####
17+
18+
Удаляем повторяющиеся символы и получаем: STCTF#uN1oCKd00r#

NoisyNeighbor/summary.yml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
answer_regex: STCTF#uN1oCKd00r#
3+
author: spy
4+
category: forensics
5+
description: |
6+
Ваш сосед очень любит свой умный дом, его дом умнее уже даже своего хозяина. Сосед искренне уверен, что со всеми новомодными электронными штучками в доме он в полной безопасности. Докажите ему, что это не так, откройте входную дверь до его возвращения домой. https://stepic.org/media/attachments/course/117/noise.wav.xz
7+
name: NoisyNeighbor
8+
price: 500

Obscurity/create/Dockerfile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FROM ubuntu:14.04
2+
3+
COPY reader tag run.sh /
4+
RUN apt-get install nmap
5+
CMD /run.sh

Obscurity/create/obscurity.7z

1.32 KB
Binary file not shown.

Obscurity/create/reader

7.96 KB
Binary file not shown.

Obscurity/create/tag

8.38 KB
Binary file not shown.

Obscurity/summary.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ answer_regex: STCTF#chocolate_chip_c00kies_arrive_on_monday#
33
author: gnull
44
category: crypto
55
description: |
6-
На вооружение вражеской разведки поступили бесконтактные смарт-карты нового поколения. Новейшая разработка Западной Академии Естественной Близорукости использует шифр Crackto, основанный на секретности алгоритма. Нашей разведкой было выяснено, что смарт-карты используются для передачи информации о доставках вражеского печенья в наш тыл. Если вражеские голуби и дальше продолжат беспрепятственно доставлять секретные донесения, это нанесет непоправимый ущерб нашей пряниковой индустрии. К счастью, наш агент, Василий, сумел украсть <a href="source on dropbox">исходный код</a>, а так же адреса смарт-карты(IP:PORT) и считывателя(IP:PORT). В скором времени враг планирует переброску крупной партии овсяного печенья, ее необходимо предотвратить. Узнайте время доставки.
6+
На вооружение вражеской разведки поступили бесконтактные смарт-карты нового поколения. Новейшая разработка Западной Академии Естественной Близорукости использует шифр Crackto, основанный на секретности алгоритма. Нашей разведкой было выяснено, что смарт-карты используются для передачи информации о доставках вражеского печенья в наш тыл. Если вражеские голуби и дальше продолжат беспрепятственно доставлять секретные донесения, это нанесет непоправимый ущерб нашей пряниковой индустрии. К счастью, наш агент, Василий, сумел украсть <a href="https://www.dropbox.com/s/uunuvhaz84hd0p4/obscurity.7z?dl=0">исходный код</a>, а так же адреса смарт-карты(IP:PORT) и считывателя(IP:PORT). В скором времени враг планирует переброску крупной партии овсяного печенья, ее необходимо предотвратить. Узнайте время доставки.
77
88
name: Obscurity
9-
price: 300-400?
9+
price: 400

Sarcasm/summary.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ answer_regex: STCTF#5aRcAmMa5573R15Wa7Ch1NGY0u#
33
author: patrick
44
category: stegano
55
description: |
6-
Петя был мастер сарказмов. Попробуй найти небольшой ключ от его ящика-пандоры.
6+
Петя был мастер сарказмов. Попробуй найти небольшой ключ от его ящика Пандоры.
77
name: Sarcasm
8-
price: 100
8+
price: 300

Scrap/create/encrypted.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
�l�3������v#���#�:^�����u�Հ����qG*#ՈBd�e�Lq=ӻ��� �4F��r��

Scrap/create/key.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hoDWU3xn3Gk9y

Scrap/create/prog_05.c

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
int main()
6+
{
7+
FILE *fi, *fo, *fk;
8+
int i, r;
9+
char key[20], text[100];
10+
11+
fi = fopen("flag.txt", "r");
12+
fo = fopen("encrypted.txt", "w");
13+
fk = fopen("key.txt", "r");
14+
15+
fscanf(fi, "%s", text);
16+
fscanf(fk, "%s", key);
17+
18+
srand(key[0] * key[1] * key[2] * key[3]);
19+
for(i = 0; i < strlen(text); ++i)
20+
{
21+
r = rand();
22+
putc(r ^ key[(r % strlen(key))] ^ text[i], fo);
23+
}
24+
25+
fclose(fi);
26+
fclose(fo);
27+
fclose(fk);
28+
return 0;
29+
}

Scrap/solution/flag.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1fYouAreR4ad1ngTh1sThenYouHaveG0tTh1sF1agSTCTF#WhenWi11TrueRandom#co

Scrap/solution/key.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
T4DchoDWU3xn3Gk9y

Scrap/solution/solution.html

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Вспоминая, как работает стандартный ГПСЧ в Си, можно увидеть, что вся дешифрация зависит от первых 4х символов ключа.
2+
Т.к. 100 ^ 4 = 10^8 - это количество попыток подбора ключа неоптимизированным алгоритмом полного перебора, то таким образом
3+
можно получить за адекватное время ключ и оригинальный текст

0 commit comments

Comments
 (0)