Rating: 0

![](https://expend20.github.io/assets/files/ctf/2018/inctf/kernel2/logo.png)
* https://s3.us-east-2.amazonaws.com/inctfi/chall_final.tar.gz
* [orig link](https://ctf.inctf.in/challenges)
* [ctftime](https://ctftime.org/event/662/)

The function `check_flag()` is really interesting. First of all, it checks two values. That values should be set by `mmap()` and `write()` call to the driver device. Later that values will be `xor`ed with one another and the result would be actually checked in `check_flag()`.

![](https://expend20.github.io/assets/files/ctf/2018/inctf/kernel2/check_flag.png)

There are two magic values that we can bruteforce:

```
if ( len_1 == 7
* ((unsigned __int64)(((unsigned __int64)(len_1 - (0x2492492492492493LL * (unsigned __int128)len_1 >> 64)) >> 1)
+ (0x2492492492492493LL * (unsigned __int128)len_1 >> 64)) >> 2) )

...
if ( (unsigned int)(need16 - 1) > 0x1F
|| (v28 + 2) * (v28 + 1) + ((v28 + 2) * (v28 + 1) - 1) * ((v28 + 2) * (v28 + 1) - 1) != 0x16C93 )

```

The python scripts.
```
#!/usr/bin/python

for v13 in xrange(1023):
if v13 == 7 * ((((v13 - (0x2492492492492493 * v13 >> 64)) >> 1) + (0x2492492492492493 * v13 >> 64)) >> 2):
print v13
```
and
```
#!/usr/bin/python

for v33 in xrange(1023):
if (v33 + 2) * (v33 + 1) + ((v33 + 2) * (v33 + 1) - 1) * ((v33 + 2) * (v33 + 1) - 1) == 93331:
print v33
```

Will give results `7*x` for the first, and `16` for the second. So the password length should be a power of 7.

Now we should reverse engineer whole function and write a solver. We can actually debug it with GDB, orgs are provided us with a very useful intro to debugging.

```
#!/usr/bin/env python

rev = "#v(2fx]PJZF[wY48E=,5hyAkL>s3?m|~;pS_WNgIjOuU0Q.$G7+eCl^d1rq9XKDa)':BcHn&zTob}<mi*!r{6t-v" out="" for="" chrtofind,="" carry="" in="" zip('bios{1}',="" [-1,="" 0,="" 0,="" -1,="" 0,="" -1,="" 0]):="" idx="rev.find(chr(ord(chrToFind)" -="" 16))="" +="" carry="" strbin="bin(idx)" toprint="strbin.replace("b"," "").replace("0",="" "`").replace("1",="" "c")="" toprint="toPrint.rjust(8," '`')[1:]="" print("[%s:%s:%d="" %x]="" %s"="" %="" (chrtofind,="" chr(ord(chrtofind)="" -="" 16),="" idx,="" idx,="" toprint))="" out="" +="toPrint" print("out:="" %s"="" %="" out)="" ```="" the="" final="" code="" will="" look="" like="" this.="" ```="" #include="" <sys="" cdefs.h="">
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys ioctl.h="">
#include <string.h>
#include <sys mman.h="">

#define _PATH_DEV_MAPPER "/dev/chall2"

int main(int argc, char **argv)
{
int devfd;
char *buf;
char *p;
int i;

buf = malloc(50);

if ((devfd = open(_PATH_DEV_MAPPER, O_RDWR)) == -1)
err(EXIT_FAILURE, "Cannot open %s", _PATH_DEV_MAPPER);

for (i = 0; i < 16; i++){
ioctl(devfd, 0x20004B01);
}

p = mmap(0, 50, PROT_READ + PROT_WRITE, 0, devfd, 0);
strcpy(p, "c`c```c```cc`c`c```ccc````cc``c`cccc`c``````ccc`c");
write(devfd, "\x01", 1);

ioctl(devfd, 0x20004B02, "1234567", 7);

read(devfd, buf, 100);
printf("%s", buf);
if (close(devfd) == -1)
err(EXIT_FAILURE, "Cannot close %s", _PATH_DEV_MAPPER);

return EXIT_SUCCESS;
}

```