[HTS] Harmonisation Technologique Système


You must push your code to:


You must change LOGIN with yours. You have to upload your ssh-key to accounts.cri.epita.net.

Every exercises should be done before Sunday February 11.


hello world

In the folder “hello” you will have to create a special hello world example.

  • commits messages should be prefixed with hello:
  • you need to call printf() from the libc, but you have to find it manually
  • binary will be named hello
  • you must use autotools or make to generate your code
  • you can’t use assembly code
  • you can’t call printf directly
  • you code should be able to work on multiple architectures and versions of the libc
  • you can’t use any function provided by the libc except the ones you will gather manually.
  • description of the elf format (with the description of the hash table): GNU_HASH
  • You can use _r_debug or _DYNAMIC
  • don’t try to search for *libc* in the l_name, you have no guaranties that the libc is called like this (look at musl libc for example)
  • gdb will help a lot to search and browse the structures
  • start the readelf code early to have the code to dump the structs/macros/etc.
  • In order to start simply, try to start with shortcuts, in order to have something working before starting using GNU_HASH, bloom filter and whatnot.

There is an explanation of the GNU_HASH on oracle_blog.


  • find the link map of your process (auxv, phdr, dynamic, r_debug, link_map)
  • get the dynamic segment
  • get the symtab, strtab and hash
  • find the address of printf inside them
  • call it

The notation is simple:

You can use every shortcut you want (_DYNAMIC, _r_debug, not using GNU_HASH, not using the bloom filter) but this will not give you any points over 10. Every shortcut you skip will give you points over 10.


For this exercise, you have to write a small readelf clone that output json.

You must use autotools, gcov and check to test your code.

Expected results should be outputted on:

./autogen.sh && ./configure --enable-code-coverage && make distcheck

in your directory.

  • you should handle elf binaries in the same ‘size’ as your machine (look into link.h for the macro ElfW)
  • the directory for your sources is “readelf”
  • commits should be prefixed with readelf:
  • binary should be named simple-readelf
  • Same as before, you should have complete coverage of your code
  • AX_CODE_COVERAGE macro is your friend (either copy the macro inside your repository, or install autoconf-archive)
  • Use check and/or make check to test your code (don’t forget to check that it is installed)
  • sample output of the tool
  • use the xlat subsystem of strace to avoid too much dumb code for the constants pretty printing.

Binary Exploitation Workshop

  • Explanation slides
  • All the exercises are on the ctf website, under the event “Workshop HTS 2017”.
  • Don’t forget that the remote environment is running busybox, so you should call execve() correctly (argv[0] must be filled with the binary name).
  • Your scripts must be in the ctf directory
  • for each exercise, you need to create a script that outputs the flag.
  • There is no constraints on what should be in your script, you can do whatever you want. If there is some exotic dependencies, explain and write them in a README file.

Sample exploit usage:

$ ./shellcode0 $host $port
FLAG: sample_flag

Obviously, the script needs to get the flag from the server, not just print it.


  • shellcode0
  • shellcode1
  • stackoverflow0
  • stackoverflow1
  • stackoverflow2
  • format0
  • heap0
  • rop0
  • rop1
  • rop2

Building & Launching your first kernel

All the explanations are in Linux development section

First Module

Let’s write a first module. This will be an out of tree module. In order to avoid repetition, Here is a simple module that only prints that it is loaded.

In order to load/unload your module, you have multiple tools:

  • modprobe
  • insmod
  • rmmod
  • modinfo
  • lsmod
  • depmod

For this part, you will use the kprobes subsystem to monitor some syscalls.

The goal is to have a module that:

  • take a string parameter filename (look into <linux/moduleparam.h>, especially module_param() and module_param_string()).
  • You need to use a kprobe to print in dmesg output when a file named filename is open for writing. (~linux/Documentation/kprobes.txt, and ~linux/samples/kprobes. You need to hook do_sys_open())
  • You need to output something like pr_info(“open file %sn”, filename);
  • Attention, you can’t look into user memory without copying it safely into kernel memory. (copy_from_user, kmalloc, strlen_user, strncpy_from_user can help a lot. <asm/uaccess.h> will be a good starting point).
  • Your module will be named “kprobe-open”
  • The Makefile is already in working, don’t modify KDIR variable. You can call make KDIR=??? in order to set up your correct path.
  • The module should live in the “kprobe-open” directory
  • commits should be prefixed with kprobe-open:

First Syscall


Here is the repositories you must use to submit your work:


In order to submit you work you ned to send patches to kernel-submission@lse.epita.fr.


Your tests will be pulled from your test repository, we will execute epita/first-syscall.yaml.

Explanation are in How to write lava tests


You will create a first syscall that is called dummy:

  • it must work for all architectures

  • syscall number should be: 1080 for generic, 385 on x86 32bit, and 333 on x86_64 & x32.

  • it should be activated with CONFIG_SYSCALL_DUMMY, should be disabled by default and must be protected under EXPERT.

  • prototype is:

    int dummy(const void *buffer, size_t size);
  • It will print on dmesg (info level) something like:

    dummy: called with \"$buffer\"
  • pay attention to details, and test it correctly, with all possible corner cases.

See also:

  • ~linux/Documentation/process/adding-syscalls.rst