Tags: google-forms misc 

Rating: 4.0

We have yet another google form task. The goal of this one seems to input the flag one character at a time. Selecting random characters until the end greets us this screen:

![](https://i.imgur.com/ZfZJhuh.png)

Using the same logic as the **infinite loop** task, we try to edit the hidden input with the page history. I will put my previous page as 62, assuming that is the final page that shows up when the flag is correct:

![](https://i.imgur.com/czZQcl4.png)

Well, seems like we were right, but they don't print the flag, they just say that the input was correct... so we need to find a way to figure out what the flag is.
We know that the flag starts with **lactf{**, so we start putting those characters in the form, and after a random letter. Looking at the history again we see something interesting:

```
<input type="hidden" name="pageHistory" value="0,2,4,6,8,10,12,14,15,17">
```

It seems like the page number is even when the answer is correct until that point. After an incorrect character, all pages become odd. There is the pattern we are looking for. Knowing this information, we can bruteforce the flag. The idea is to check each character and move to the next page in the form. If the last number of the pageHistory is odd, then it's a wrong character. If it's even, it's correct.

For this I used Puppeteer to simulate user clicks. Here is the code below:

```
const puppeteer = require('puppeteer');

const buttonClass = '.uArJ5e.UQuaGc.YhQJj.zo8FOc.ctEux';
const nextButtonClass = 'OCpkoe';
const prevButtonClass = 'GeGHKb';
const prefix = `lactf{`

const isFinished = false;

var flag = '';

(async () => {
const browser = await puppeteer.launch({headless:false});
console.log("Starting");
const page = await browser.newPage();

// First page
await page.goto('https://docs.google.com/forms/d/e/1FAIpQLSc-A-Vmx_Te-bAqnu3TrRj-DAsYTgn52uSk92v3fECQb3T83A/viewform');

await page.waitForSelector('.whsOnd.zHQkBf');

await page.focus('.whsOnd.zHQkBf')
await new Promise(r => setTimeout(r, 500));
await page.keyboard.type('test')

await page.click(`${buttonClass}`);

// Letters

await page.waitForSelector('div[role="listbox"]');

var nodes = await page.$$(".MocG8c.HZ3kWc.mhLiyf.OIC90c.LMgvRb")
var symbols = [];

for( let node of nodes ){
var attr = await page.evaluate(el => el.getAttribute("data-value"), node);
symbols.push(attr);
}

console.log(symbols);

while(!isFinished){

for( let i in symbols){
await page.waitForSelector('div[role="listbox"]');
await page.click('div[role="listbox"]');
console.log(symbols[i]);
var numberOfTimesToClickDown = 1;

if(flag.length < prefix.length)
{
numberOfTimesToClickDown = symbols.findIndex(el => el === prefix[flag.length]) + 1;
}

var selectorForDropdown = `.MocG8c.HZ3kWc.mhLiyf.OIC90c.LMgvRb[data-value='${symbols[i]}']`;
await page.waitForSelector(selectorForDropdown);

for(var c = 0; c < numberOfTimesToClickDown; c++)
{
await new Promise(r => setTimeout(r, 200));
await page.keyboard.press('ArrowDown');
}

await new Promise(r => setTimeout(r, 500));
await page.keyboard.press('Enter');
await new Promise(r => setTimeout(r, 500));

await page.click(`${buttonClass}[jsname="${nextButtonClass}"]`);

await page.waitForSelector('input[name="pageHistory"]');

var pageHistory = await page.$('input[name="pageHistory"]')
var pageHistoryValue = await page.evaluate(el => el.getAttribute("value"), pageHistory);
var lastPage = pageHistoryValue.split(',').pop();

if(lastPage % 2 == 0)
{
flag += symbols[i];
console.log("flag so far -> " + flag)

if(lastPage >= 62)
isFinished = true;

break;
}

await page.click(`${buttonClass}[jsname="${prevButtonClass}"]`);
}
}
console.log(flag);
})();

```

Running this takes a while and took quite some tries, as sometimes, probably due to my machine, the clicks failed. But either way, we got to the end with the flag being printed on the screen.

Flag: lactf{1_by_0n3_by3_un0_*,"g1'}

GingerArmy174Feb. 19, 2024, 10:40 p.m.

The flag was: lactf{1_by_0n3_by3_un0_*,"g1'}. Small typo probably