question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

File read/write and prompt switch issues while using 'effective' user/group IDs

See original GitHub issue

Bug Description

While trying to upload or download a file to which we have access through euid or egid, pwncat shows an access error.

pwncat version

$ pwncat --version
0.4.3

Target System (aka “victim”)

Regular Kali Linux as a VM

Steps to Reproduce

Steps to reproduce the behavior:

  1. Prepare a SUID binary for bash owned by root
  2. Get a session in pwncat using a normal user (non-root)
  3. Use that SUID binary to elevate your privileges
  4. Upload a test file to /root
  5. See the error

Expected Behavior

pwncat should upload the test file without any access errors

Screenshots

Found during KoTH Screenshot from 2021-08-08 21-41-57

Read issue Screenshot from 2021-08-10 01-21-21

Write issue Screenshot from 2021-08-10 01-19-47

NOTE: I had updated the PROMPTS list for zsh and default, thus the prompt doesn’t show root as the user ($(whoami))

Possible solution

Before performing upload or download, we need to refresh_uid() In pwncat/platform/linux.py

491 class LinuxPath(pathlib.PurePosixPath):
...
494     def readable(self):
495         """Test if a file is readable"""
496
497         # refresh the uid, to pick up any changes
498         self._target.refresh_uid()
499
...
504         # get the stats for the current path
505         _stat = self.stat()
506
507         file_uid = _stat.st_uid
508         file_gid = _stat.st_gid
509         file_mode = _stat.st_mode
510
511         # check for uid, euid, gid, egid  <<<<<
...
520     def writable(self):
521         """Test if the path is writable"""
522
523         # refresh the uid, to pick up any changes
524         self._target.refresh_uid()
...
530         # get the stats for the current path
531         _stat = self.stat()
...

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
calebstewartcommented, Sep 21, 2021

If you have some time to do some independent testing of the above pull request, I’d appreciate it. The tests pass, and some anecdotal testing seems positive, but I haven’t thoroughly tested these changes yet.

1reaction
calebstewartcommented, Sep 21, 2021

I’m not sure what the best solution is here. There’s fundamentally two problems detailed here:

  1. euid permissions are lost during Popen calls due to /bin/sh -c
  2. Processes with euid set cannot read /proc/$$/exe regardless of using /bin/sh -c

Lost Permissions during Popen

I think this can be solved by simply not using /bin/sh -c. Looking at the code, I don’t think this is strictly speaking needed. The shell argument to Popen is documented as using /bin/sh -c to execute the command, but that is already effectively how commands are executed by pwncat anyway. I think this is fine to remove and effectively ignore the shell argument to Popen. I tried this locally, and at the very least all tests pass. I’m going to do a little more testing and then push a branch.

Failure to read /proc/$$/exe

This is a trickier problem. I’m not sure why we are unable to read that file. Interestingly, my local machine (Arch Linux), this doesn’t happen, but in a Ubuntu container it does.

In the short-term, I think that catching the OSError is the best course forward. If readlink() raises an exception, we can simply catch the OSError and fallback to the SHELL environment variable as was intended if that method fails. This doesn’t fix the problem, but it at least ensures pwncat doesn’t crash and lose your session. A sad side-effect of this is that in this situation, we lose the nice syntax highlighting as pwncat ends up falling back to assuming SHELL=/bin/sh in most cases. This isn’t the end of the world, and is mostly cosmetic, though.

In the long term, I need to implement a module to correct euid != uid situations. Since this doesn’t always work, the above needs to be implement to ensure pwncat functions in that situation, but the real fix is just replacing uid with euid so we have the full permissions of the target user.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Client, service, and program issues can occur if you ...
This article describes incompatibilities that can occur on client computers that are running Windows XP, or an earlier version of Windows, when you...
Read more >
Prepare for LPIC-1 exam 1 - topic 104.5: Manage file ...
The first group indicates the read, write, and execute permissions for the file's owner. A - indicates that the corresponding permission is not...
Read more >
Managing Group Accounts in Ubuntu
After a file has been created, a user can change the group ownership of the file to another group by using the chgrp...
Read more >
[Chapter 4] 4.3 su: Changing Who You Claim to Be
Sometimes, you may want to take on the identity of another user to access some files or execute some commands. You might do...
Read more >
Working with users, groups, and permissions at the ...
Files and directories in an Amazon EFS file system support standard Unix-style read, write, and execute permissions based on the user ID and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found