Github has some holes in their basic security which allow some tampering and spoofing. This had and will again help APTs to run campaigns. We will walk through some of them.
Most of this has been found by several people before and at least once a year this gets some attention.

TL;DR: On Github it is possible to:

  • Spoof Commit authors
  • Spoof Contributors
  • Host hidden payloads under github.com (mostly solved)
  • Use Issues for phishing

Having fun with Github

Github is somehow the leading platform for code storage. But did you know that protections against impersonation are not that strong? I expect this functions are “by-design” and “working as intendend” it’s just that combining some of them might cause some risk.

Let’s jump into some “special” behavior. I tend to call it “with room for improvement”.

Spoof Commit Authors

We can spoof users on Github as long as we know the username and the email. Let’s demonstrate this. Put on your protection and follow me.

Finding a “victim”

At first, we need somebody we want to spoof. Let’s just take the CEO of Github, Thomas Dohmke. Nothing personal here, just fits the platform.

Always go big, target the CEO

So we need to find the Github profile, which was quite easy, as it is shown in the bottom left corner.

@ashtom is the profile. The next step is to find a commit from that person, which can be easily done via the “Contribution activity”.

Contribution activity

Open the commit details for a real commit, not a merge pull request like https://github.com/ashtom/hkimport/commit/e2a386c0f2fe4b8ec939eb132b5532c0396c9133.

Add a .patch to the URL to see the real git patch message:
https://github.com/ashtom/hkimport/commit/e2a386c0f2fe4b8ec939eb132b5532c0396c9133.patch

Getting the username and the e-mail

Here we have our needed user.name Thomas Dohmke and the user.email thomas@dohmke.de. Wondering why it’s written like that? We will see shortly.

Spoof some commits

Create a new repository and check it out via the git CLI.

You will need a Github Token for that, which you can generate under Developer Settings.

Now we make some nice commits and push them with another user.name.

user@localhost ~/must-be-legit (main)> git config user.name Thomas Dohmke
user@localhost ~/must-be-legit (main)> git config user.email thomas@dohmke.de
user@localhost ~/must-be-legit (main)> code -n .
user@localhost ~/must-be-legit (main)> git add *
user@localhost ~/must-be-legit (main)> git commit -m "Hello from Thomas"
[main (root-commit) 9d6c889] Hello from Thomas
 2 files changed, 1 insertion(+)
 create mode 100644 README.MD
 create mode 100644 image.png
user@localhost ~/must-be-legit (main)> git push
Username for 'https://github.com': <<myemail>>
Password for 'https://<<myemail>>@github.com': 
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 308.67 KiB | 17.15 MiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/PfiatDe/must-be-legit.git
 * [new branch]      main -> main

Note that the username for the commit was different from the one for the push.

And now, yeah, nothing. That’s all. You successfully spoofed a commit message. Spoofed commit

Spoofed commit

The Github user profile is linked with the commit user.email and therefore looks very valid and also links in the profile are working, as it’s the real user profile.

Connected User profile

Not that bad, right?

Looking at the repo insights, we also see our contributor.

Repository insights

However, there is still some discrepancy, which you might have noticed, the contributor did not show up on the repository main page.

Let’s tackle this.

Get Contributors shown

Actually, that’s quite easy. Looking at: Why are my contributions not showing up on my profile? we find several actions which might add the contributors.

We are going for a Pull Request, as we cannot create issues directly in the git CLI.

But WAIT

I was playing around with this when suddenly I realized it is way simpler. Just set the repository to public before you commit & push and you get your contributors badge.

Contributors

You can change the repository settings after your commit again.

Unverified commit status

If we look at the commit history, there is a status showing if the commit could be verified and bound to the user.

Unverified status

For some spoofed users, we see an unpleasant Unverified status.
This happens when the user has the vigilant mode enabled (Learn about vigilant mode) and commits must be signed. One might argue that this warning has poor visibility. However, it is there…

Let’s see if we can get rid of it. Luckily we can use another feature of Github, Co-authored-by in that case. This is even easier to use. So let’s do this:

  • Use the WebUI and create a commit.
  • Add an extended description.
  • Done.

Co-authored-by feature

The commit is now from two people, where one could be verified and therefore it is partially verified.

“Helpful” status popup

So we can get a partially verified which is green:

What’s also interesting is that Github does not state what’s wrong with the commit and even in the detailed view it is not possible to see.

And to stress this a little bit, the vigilant mode is not that far in use. So if we look at the current Github Chief of Staff, Demetris Cheatham, we see that even the C-Level of Github itself hasn’t enabled it for all board members.

Note: We can even get a verified status with the Co-Authored technique.

Committed with the Github Chief of Staff

Conclusion for the spoofing

It is really easy to spoof other Github users in the commits. We must decide if we want either the commit author directly spoofed, which might bring up an Unverified status if the user is using the vigilant mode. Or we use the Co-authored-by flag to get the Partially verified and a better visibility for our spoofed author. There are even some ready to use memes around:

https://www.reddit.com/r/ProgrammerHumor/comments/1jaldin/gitpush/

You also might find a clever way to combine them :)

Host payloads under other repos

Until somewhere in 2024 it was possible to host payloads in issues for other repositories. You can check e.g. the following report for details:

https://research.openanalysis.net/github/lua/2024/03/03/lua-malware.html

https://x.com/JustasMasiulis/status/1764171634469122165

After some malicious campaigns using this, Github finally fixed it after several months and now temporary uploads are hosted under some user folder now:
[copilot-language-server.zip](https://github.com/user-attachments/files/19891659/copilot-language-server-darwin-arm64-1.306.0.zip).
So, this still works, but isn’t that great anymore.

Note: The file is getting deleted if there is no reference to it, e.g. in an issue. So it is not available anymore.

What is particularly interesting is that the file seems to get incremented, which might allow brute-forcing some of them.

Incremented ID for the upload

Letting a Burp eat some RAM this quite quickly revealed a 302 response.

Intruder Attack

Note: This is done unauthenticated! The session ID is not connected to an account. Also note: There are some brute-force protections in place, but yeah, they are not bulletproof.

Following the redirect brings us some files which are not ours.

Get some uploaded files

But this is only for public files, so it’s kinda boring!

Host under Tickets

Another approach is to host the file at a ticket.

Go to: Account –> Github Support –> My Tickets –> New Ticket –> open a support ticket to create a new service ticket.

Upload your file and it will be available under a Zendesk URL https://github.zendesk.com/attachments.

For example:

https://github.zendesk.com/attachments/token/jwxXlXEbwo0IJFzrhy1OVPkEZ/?name=copilot-language-server-darwin-arm64-1.306.0.zip

No need to finally send the ticket, but the file is getting deleted after some hours if not. Okay, to be fair, this is not hosting the file under the github.com domain anymore, but at least it is kind of worthless :)

Conclusion

So this seems to be quite good solved by Github finally. You can ofc still host your files in a public repo or in a gist but that is kind of lame.

Use issues for phishing

If we drop somebody an issue in their repository, typically an e-mail will be sent to the owner.

The most interesting part for sure is the possibility to insert links.

Somebody might choose a nice Github name and set the display name and a fitting profile picture.

The display name of the profile will be the from field, which is … interesting.

Phishing Mail with a link

The HTML which will be sent via e-mail notification is quite limited, however, it might be possible to craft something. We can use Headlines and basic stuff like bold, italic. The use of colors is restricted and not trivial to escape.

There are several samples around how an issue might look like, e.g. here: https://www.bleepingcomputer.com/news/security/fake-security-alert-issues-on-github-use-oauth-app-to-hijack-accounts/

# Security Alert: Login Blocked
Your GitHub account was successfully signed in to but we did not recognize the location of the sign-in. You can review this sign-in attempt by visiting [https://github.com/settings/sessions/authentications/4102671234](https://github.com/settings/sessions/authentications/4102671234)

## Login Information
* 🏠 Location: Wolgograd, Russia 🇷🇺
* 🖧 IP Address: 102.222.77.66
* 💻 Device: Chrome on Red Hat Linux

If you recently signed in to your account, you do not need to take any further action.

If you did not sign in to your account, your password may be compromised. 

## Steps to secure your Account
Visit [https://github.com/settings/security](https://github.com/settings/security) to create a new, strong password for your GitHub account.

For more information, see [https://docs.github.com/articles/keeping-your-account-and-data-secure/](https://docs.github.com/articles/keeping-your-account-and-data-secure/) in the GitHub Docs.

To see this and other security events for your account, visit [https://github.com/settings/security-log](https://github.com/settings/security-log)


Thanks,
The GitHub Team

This is how some example might look like: Phishing Mail with a link

We can edit the issue after a few seconds.

Cleanup

And then delete the history: Cleanup

Bonus: Colors in online issues

We can get some colors for the rendered online version of the github issues. This is rather funny than useful, as Github will not generate the HTML for the Code Block and therefore it will land as text in the email. So this only works for the online rendered version.

## By using LaTeX Macros we can get colored Text

$${\color{red}Welcome \space \color{lightblue}To \space \color{orange}My \space \color{green} \Huge{\textsf{Site}}}$$

${{\color{Goldenrod}\Huge{\textsf{Some\ more\ Text\ }}}}$

${{\color{blue}\Huge{\textsf{Lorem\ ...}}}}$

Phishing Mail with a link

But ofc you can also just make an image or embedd an svg, which is also fine and offers some more room for design.