Guestbook [97 Solves]
Description
I made this cool guestbook for the CTF. Please sign it.
Author: Ido
Attachments: index.html
Source Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Guestbook</title>
<script async=false defer=false>
fetch("https://script.google.com/macros/s/AKfycbyMdMLPsRtvXmcQN1V2yR3Zv_HYI1jvVqOCNAZpx7xgXqSflgwrtcveyUaGB8eTZwkM/exec?sheetId=1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ").then(x=>x.json()).then(x=>{
x.slice(x.length-11).forEach(entry =>{
const el = document.createElement("li");
el.innerText = entry.Name + " - " + entry.Message
document.getElementById("entries").appendChild(el)
})
document.getElementById("loading")?.remove();
})
</script>
</head>
<body>
<h1>
Hi! I made this guestbook for my site, please sign it.
</h1>
<iframe name="dummyframe" id="dummyframe" style="display: none;"></iframe>
<h3 style="margin: 0">Last 10 user entries in the guestbook:</h3>
<p id="loading" style="margin: 0">Loading...</p>
<ul id="entries" style="margin: 0">
</ul>
<h3>Sign the guestbook:</h3>
<form method="POST" action="https://script.google.com/macros/s/AKfycbyMdMLPsRtvXmcQN1V2yR3Zv_HYI1jvVqOCNAZpx7xgXqSflgwrtcveyUaGB8eTZwkM/exec?sheetId=1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ">
<input id="name" name="name" type="text" placeholder="Name" required>
<input id="message" name="message" type="text" placeholder="Message" required>
<button type="submit">Send</button>
</form>
</body>
</html>
Solution
The API URL is https://script.google.com/macros/s/AKfycbyMdMLPsRtvXmcQN1V2yR3Zv_HYI1jvVqOCNAZpx7xgXqSflgwrtcveyUaGB8eTZwkM/exec?sheetId=1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ. This is the URL hosted by GAS (Google Apps Script) Web Apps.
The query parameter of the URL includes sheetId, which is believed to be the ID of a Google Spreadsheet.
So we can access the spreadsheet by https://docs.google.com/spreadsheets/d/1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ/edit URL.
Also, we can open GAS project attached the Spreadsheet: File > Make a copy > Open Attached Apps Script file named as Untitled project.
And get the source code of this GAS API.
This API returns values in a sheet named sorted.
Instead, I will try to get values from a sheet named raw.
Create a GAS project in my account and execute the following code:
function doGet(e) {
let file;
try{
file = SpreadsheetApp.openById("1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ"); // change here: hard cording
}
finally{
if(!file){
return ContentService.createTextOutput(JSON.stringify({status:404, message:"invalid sheet ID"})).setMimeType(ContentService.MimeType.JSON);
}
}
const sheet = file.getSheetByName('raw'); // change here: sorted -> raw
const [headers, ...rows] = sheet.getDataRange().getValues();
const res = rows.map(row => headers.reduce((a,x, i)=> {a[x] = row[i]; return a;},{}))
return ContentService.createTextOutput(JSON.stringify(res)).setMimeType(ContentService.MimeType.JSON);
}
Flag
uoftctf{@PP 5cRIP7 !5 s0 coOL}