Skip to content

Commit c91171d

Browse files
committed
chapters/data: Add checkers for memory-security tasks
Done solving the issue 134 : chapters/data/memory-security/drills/tasks: Add solutions and checkers #134 Added the generate_skels.py infrastructure to generate the skeletons from the solutions Added checkers for the tasks which needed one Updated the README.md for every task with useful information on how to generate the skels and run the checker Added solution Updated generate_skels.py to add support for a task that requires uncommenting lines in the Makefile. Fixes #134 Signed-off-by: Vica Teodor Andrei <[email protected]>
1 parent dc21b9b commit c91171d

Some content is hidden

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

63 files changed

+1170
-771
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
support
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
PYTHON = python3
2+
SCRIPT = generate_skels.py
3+
4+
skels:
5+
mkdir -p support/src
6+
$(PYTHON) $(SCRIPT) --input ./solution/src --output ./support/src
7+
$(PYTHON) $(SCRIPT) --input ./solution/tests --output ./support/tests
8+
9+
clean:
10+
rm -rf support/

chapters/data/memory-security/drills/tasks/aslr/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# ASLR
22

3+
Navigate to `chapters/data/memory-security/drills/tasks/aslr` and run `make skels` to generate the `support/` folder.
4+
Then navigate to `support/src`.
5+
6+
37
Use the `Makefile.aslr` file to compile the `chapters/data/memory-security/drills/tasks/aslr/support/aslr.c` file:
48

59
```console
@@ -26,3 +30,17 @@ Disable PIC by uncommenting the `-fno-PIC` and `LDFLAGS` lines.
2630
We observe that for randomization to work, we need to instruct the OS to randomize the program sections and the compiler to generate code that is position independent.
2731

2832
If you're having difficulties solving this exercise, go through [this](../../../reading/memory-security.md) reading material.
33+
34+
## Checker
35+
36+
To run the checker, go into the `tests` directory located in `src`, then type `make check`.
37+
A successful output of the checker should look like this :
38+
39+
```console
40+
student@os:~/.../drills/tasks/aslr/support/src/tests make check
41+
test_aslr ........................ passed ... 100
42+
43+
========================================================================
44+
45+
Total: 100/100
46+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#!/usr/bin/python3 -u
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
4+
import sys
5+
import argparse
6+
import os.path
7+
import re
8+
9+
10+
def process_file(src, dst, pattern, replace, remove, replace_pairs, end_string=None):
11+
if not pattern or not replace or not remove:
12+
print(
13+
f"ERROR: The script behaviour is not properly specified for {src}",
14+
file=sys.stderr,
15+
)
16+
sys.exit(1)
17+
18+
fin = open(src, "r")
19+
os.makedirs(os.path.dirname(dst), exist_ok=True)
20+
fout = open(dst, "w")
21+
22+
remove_lines = 0
23+
skip_lines = 0
24+
uncomment_lines = 0
25+
end_found = True
26+
makefile_special_handling = "Makefile" in src
27+
28+
for i, l in enumerate(fin.readlines()):
29+
# Skip generation of file.
30+
if "SKIP_GENERATE" in l:
31+
fout.close()
32+
os.remove(dst)
33+
return
34+
35+
if end_string and not end_found:
36+
fout.write(l)
37+
if end_string in l:
38+
end_found = True
39+
continue
40+
41+
if remove_lines > 0:
42+
remove_lines -= 1
43+
continue
44+
45+
if skip_lines > 0:
46+
skip_lines -= 1
47+
m = re.search(pattern, l)
48+
if m:
49+
l = "%s%s\n" % (m.group(1), m.group(3))
50+
fout.write(l)
51+
continue
52+
53+
if uncomment_lines > 0:
54+
uncomment_lines -= 1
55+
for fro, to in replace_pairs:
56+
l = re.sub(fro, to, l)
57+
fout.write(l)
58+
continue
59+
60+
if makefile_special_handling and "TODO" in l and "Uncomment" in l:
61+
fout.write(l)
62+
next_line = fin.readline()
63+
fout.write("# " + next_line)
64+
continue
65+
66+
m = re.search(pattern, l)
67+
if m:
68+
if m.group(2):
69+
skip_lines = int(m.group(2))
70+
else:
71+
skip_lines = 1
72+
73+
if end_string and end_string not in l:
74+
end_found = False
75+
76+
l = "%s%s\n" % (m.group(1), m.group(3))
77+
78+
m = re.search(replace, l)
79+
if m:
80+
if m.group(2):
81+
uncomment_lines = int(m.group(2))
82+
else:
83+
uncomment_lines = 1
84+
continue
85+
86+
m = re.search(remove, l)
87+
if m:
88+
if m.group(2):
89+
remove_lines = int(m.group(2))
90+
else:
91+
remove_lines = 1
92+
continue
93+
94+
fout.write(l)
95+
96+
fout.close()
97+
98+
def main():
99+
parser = argparse.ArgumentParser(
100+
description="Generate skeletons sources from reference solution sources"
101+
)
102+
parser.add_argument(
103+
"--input", help="input directory to process files", required=True
104+
)
105+
parser.add_argument(
106+
"--output", help="output directory to copy processed files", required=True
107+
)
108+
args = parser.parse_args()
109+
110+
for root, dirs, files in os.walk(args.input):
111+
new_root = os.path.join(args.output, os.path.relpath(root, args.input))
112+
for d in dirs:
113+
os.makedirs(os.path.join(new_root, d), exist_ok=True)
114+
115+
for src in files:
116+
if (
117+
re.match("Makefile.*$", src)
118+
or re.match(r".*\.sh$", src)
119+
or re.match(r".*\.[sS]$", src)
120+
or re.match(r".*\.py$", src)
121+
):
122+
pattern = r"(^\s*#\s*TODO)( [0-9]*)(:.*)"
123+
replace = r"(^\s*#\s*REPLACE)( [0-9]*)"
124+
remove = r"(^\s*#\s*REMOVE)( [0-9]*)"
125+
replace_pairs = [("# ", "")]
126+
end_string = None
127+
elif re.match(r".*\.asm$", src):
128+
pattern = r"(^\s*;\s*TODO)( [0-9]*)(:.*)"
129+
replace = r"(^\s*;\s*REPLACE)( [0-9]*)"
130+
remove = r"(^\s*;\s*REMOVE)( [0-9]*)"
131+
replace_pairs = [("; ", "")]
132+
end_string = None
133+
elif (
134+
re.match(r".*\.[ch]$", src)
135+
or re.match(r".*\.cpp$", src)
136+
or re.match(r".*\.hpp$", src)
137+
):
138+
pattern = r"(.*/\*\s*TODO)([ 0-9]*)(:.*)"
139+
replace = r"(.*/\*\s*REPLACE)( [0-9]*)"
140+
remove = r"(.*/\*\s*REMOVE)( [0-9]*)"
141+
replace_pairs = [(r"/\* ", ""), (r" \*/", "")]
142+
end_string = "*/"
143+
elif re.match(r".*\.d$", src):
144+
pattern = r"(.*//\s*TODO)([ 0-9]*)(:.*)"
145+
replace = r"(.*//\s*REPLACE)( [0-9]*)"
146+
remove = r"(.*//\s*REMOVE)( [0-9]*)"
147+
replace_pairs = [(r"// ", "")]
148+
end_string = None
149+
else:
150+
continue
151+
152+
dst = os.path.join(new_root, src)
153+
src = os.path.join(root, src)
154+
print(dst)
155+
process_file(src, dst, pattern, replace, remove, replace_pairs, end_string)
156+
157+
158+
if __name__ == "__main__":
159+
sys.exit(main())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/aslr

chapters/data/memory-security/drills/tasks/aslr/support/Makefile chapters/data/memory-security/drills/tasks/aslr/solution/src/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ SRCS = aslr.c
88
OBJS = $(SRCS:.c=.o)
99

1010
# Flags for compiling and linking
11+
# TODO: Uncomment the -fno-PIC line
1112
CFLAGS += -fno-stack-protector -fno-PIC
13+
14+
# TODO: Uncomment the LDFLAGS line
1215
LDFLAGS += -no-pie
1316

1417
# Output binary

chapters/data/memory-security/drills/tasks/exec-shellcode/support/tests/Makefile chapters/data/memory-security/drills/tasks/aslr/solution/tests/Makefile

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
SRC_PATH ?= ../src
2-
FULL_SRC_PATH = "$(realpath $(SRC_PATH))"
3-
CPPFLAGS = -I. -I$(FULL_SRC_PATH) -I../utils
2+
FULL_SRC_PATH = $(realpath $(SRC_PATH))
3+
CPPFLAGS = -I. -I$(realpath $(SRC_PATH)) -I../utils
44
CFLAGS = -Wall -Wextra
55
# Remove the line below to disable debugging support.
66
CFLAGS += -g -O0
@@ -22,7 +22,7 @@ check: $(SHELLCODES)
2222
make -C $(FULL_SRC_PATH) clean
2323
make clean
2424
make -i SRC_PATH=$(FULL_SRC_PATH)
25-
./run_all_tests.sh
25+
sudo bash ./run_all_tests.sh
2626

2727
lint:
2828
-cd .. && checkpatch.pl -f src/*.c
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
4+
#
5+
# Print test result. Printed message should fit in 72 characters.
6+
#
7+
# Print format is:
8+
#
9+
# description ...................... passed ... NNN
10+
# description ...................... failed ... NNN
11+
# 32 chars 24 chars 6 3 3
12+
#
13+
14+
print_test()
15+
{
16+
func="$1"
17+
result="$2"
18+
points="$3"
19+
20+
if test "$points" -gt 999; then
21+
points=999
22+
fi
23+
24+
printf "%-32s " "${func:0:31}"
25+
printf "........................"
26+
if test "$result" -eq 0; then
27+
printf " passed ... %3d\n" "$points"
28+
else
29+
printf " failed ... 0\n"
30+
fi
31+
}
32+
33+
run_test()
34+
{
35+
func="$1"
36+
points="$2"
37+
# Run in subshell.
38+
(eval "$func")
39+
print_test "$func" "$?" "$points"
40+
}

chapters/data/memory-security/drills/tasks/exec-shellcode/support/tests/run_all_tests.sh chapters/data/memory-security/drills/tasks/aslr/solution/tests/run_all_tests.sh

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
#!/bin/bash
21
# SPDX-License-Identifier: BSD-3-Clause
2+
#!/bin/bash
33

44
if test -z "$SRC_PATH"; then
5-
SRC_PATH=../src
5+
SRC_PATH=../src/
66
fi
77

88
export SRC_PATH
9-
9+
echo ""
1010
(
11-
./test_helloworld.sh
12-
./test_getpid.sh
13-
./test_openfile.sh
14-
./test_brk.sh
11+
bash test.sh
1512
) | tee results.txt
16-
13+
echo ""
14+
echo "========================================================================"
1715
total=$(grep '\( passed \| failed \)' results.txt | rev | cut -d ' ' -f 1 | rev | paste -s -d'+' | bc)
1816
echo ""
1917
echo -n "Total: "
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
4+
source graded_test.inc.sh
5+
6+
binary=../src/aslr
7+
8+
if test -z "$SRC_PATH"; then
9+
SRC_PATH=./../src
10+
fi
11+
12+
test_aslr()
13+
{
14+
start_address=$(nm "$binary" | awk '/_start/ {print $1}' | head -n 1)
15+
start_address_decimal=$((0x$start_address))
16+
if ((start_address_decimal < 0x400000)); then
17+
exit 1
18+
fi
19+
exit 0
20+
}
21+
22+
run_test test_aslr 100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
support
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
PYTHON = python3
2+
SCRIPT = generate_skels.py
3+
4+
skels:
5+
mkdir -p support/src
6+
$(PYTHON) $(SCRIPT) --input ./solution/src --output ./support/src
7+
$(PYTHON) $(SCRIPT) --input ./solution/tests --output ./support/tests
8+
9+
clean:
10+
rm -rf support/
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
# Bypassing the Stack Protector
22

3+
Navigate to `chapters/data/memory-security/drills/tasks/bypassing-stack-protector` and run `make skels` to generate the `support/` folder.
4+
Then navigate to `support/src`.
5+
6+
37
Inspect the `chapters/data/memory-security/drills/tasks/bypassing-stack-protector/support/stack_protector.c` source file.
48
Compile the program and examine the object code.
59
Try to identify the canary value.
6-
Using the `addr` variable, write 2 `scanf` instructions: one that overwrites the canary with the correct value and one that overwrites the return address with the address of function `pawned`.
10+
Using the `addr` variable, write 2 instructions: one that indexes `addr` to overwrite the canary with the correct value and one that indexes `addr` to overwrite the return address with the address of function `pawned()`.
711
In case of a successful exploit a video will be offered as reward.
812

913
If you're having difficulties solving this exercise, go through [this](../../../reading/memory-security.md) reading material.
14+
15+
## Checker
16+
17+
To run the checker, go into the `tests` directory located in `src`, then type `make check`.
18+
A successful output of the checker should look like this :
19+
20+
```console
21+
student@os:~/.../drills/tasks/aslr/support/src/tests make check
22+
test_bypassing-stackprotector ........................ passed ... 100
23+
24+
========================================================================
25+
26+
Total: 100/100
27+
```

0 commit comments

Comments
 (0)