# EASYCTF - Nosource
> description: All you CTFers are sure getting on my nerves with your source-viewing and developer tools-ing! Alas, despite my best wishes, the experienced programmers on the wonderful website StackOverflow tell me that it's impossible to keep you from looking at the HTML. But a disable right click script certainly won't stop an experienced CTFer like you! So finding the flag in the source of this problem should be no trouble, right?
> category: Web
When we launch the chall, a web page informs us that we have to use `Chrome` and enable `Javascript`.So I used `Chrome` and nothing happended. After playing with `Javascript` options in `Chrome` browser, I finally ended up to the 'real' chall page.
Here you can't use 'right click -> inspect element' or 'ctrl+u' because it will redirect you to the first page and you won't be able to get the source code like that.
The way I did it was using Wireshark: I use it to sniff the network when we get the challenge page.
Then we can get the source code by following the stream. Here is the source code:
```
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>Stop looking at the source code</title><script class="delete">	var timeout = setTimeout(function () {		location.replace('/soupd?2');	}, 1000);</script><link href="/static/css/bootstrap.min.css" rel="stylesheet"><link href="/static/css/main.css" rel="stylesheet"></head>
<body><main role="main" class="container"><div class="starter-template">	<h1>Stop looking at the source code</h1> 		Welcome to the problem page! Please enter the flag below. 	<form id="flag-form">		<div class="form-group">			<input type="text" class="form-control" id="flag" placeholder="easyctf{">		</div>		<button type="submit" class="btn btn-success btn-lg">Check</button>	</form></div>
		Welcome to the problem page! Please enter the flag below. 
<script class="delete">	// Ah, old friend, we meet again...	function process(a, b) {		'use strict';		var len = Math.max(a.length, b.length);		var out = [];		for (var i = 0, ca, cb; i < len; i++) {			ca = a.charCodeAt(i % a.length);			cb = b.charCodeAt(i % b.length);			out.push(ca ^ cb); 		return String.fromCharCode.apply(null, out);	}
	(function () {		'use strict';
		function soupd() {			document.documentElement.innerHTML = '';			location.replace('/soupd?2');			setInterval(function () {				location.replace('/soupd?12');			}, 100); 
		try {			let badNodes = document.getElementsByClassName('delete');			for (let i = 0; i < badNodes.length; i++) {				badNodes[i].parentNode.removeChild(badNodes[i]);			}		} catch (e) {}
		try {			window.history.pushState({}, 'Stop looking at the source', '/');		} catch (e) {}
		try {			var element = new Image('/static/img/soup.png');			Object.defineProperty(element, 'id', { get: function () {			  soupd();			}});			eval("console.log('Stop looking at the source code%c', element);");		} catch (e) {}
		var formEl = document.getElementById('flag-form');		var inputEl = document.getElementById('flag');
		var func = "(function (e, v) { e.preventDefault() || " +					"alert(inputEl.value === process(this.prototype.flag, " +					"this.prototype.key) ? 'Your flag is correct!' : " +					"'Incorrect, try again.'); })";		var f = 'DQ4cJgsbCVofB18sNw4wRlhfCwAbXxpTC1wwKVlcGBIaUDAGJzowYDoqTiI=';		var p = { prototype: { flag: atob(f), key: 'heheheh!' }};
		document.addEventListener('DOMContentLoaded', function () {			formEl.addEventListener('submit', eval(func).bind(p));			$('.delete').remove();		});
	})();</script></main>
<script src="/static/js/jquery-3.2.1.slim.min.js"></script><script src="/static/js/popper.min.js"></script><script src="/static/js/bootstrap.min.js"></script><script class="delete">clearTimeout(timeout);</script>
</body></html>```
First let's get rid of this html and build our javascript:
```function process(a, b) {	var len = Math.max(a.length, b.length);	var out = [];	for (var i = 0, ca, cb; i < len; i++) {		ca = a.charCodeAt(i % a.length);		cb = b.charCodeAt(i % b.length);		out.push(ca ^ cb);	}	return String.fromCharCode.apply(null, out);}
entry = "WeWriteHere"
var f = 'DQ4cJgsbCVofB18sNw4wRlhfCwAbXxpTC1wwKVlcGBIaUDAGJzowYDoqTiI=';
flag = atob(f);key = 'heheheh!';
func()
function func() {	alert(entry === process(flag, key) ? 'Your flag is correct!' : 'Incorrect, try again.'); }```
It seems that all we have to do is to print process(flag, key) and write it as entry:
```console.log(process(flag, key));// -> ektCc~a{wb7I_kXg0:ces:rrc9XL19p3r5XcO_XARO&G```
We try this in entry, but it didn't work...We know the flag look like easyctf{...}And we can see: e??????{...Maybe the given key is not right. Let's generate another one (we can see that the process methos only compute xor between entry and key):
```# First character of the key is good (we want 'e' and we already have 'e')
# For the second character, we want 'a' in output, but we have 'k' and the actual second character key is 'e':chr(ord('a')^ord('k')^ord('e'))# -> o
# For the third character, we want 's' in output, but we have 't' and the actual third character key is 'h':chr(ord('s')^ord('t')^ord('h'))# -> o
# For the 4th character, we want 'y' in output, but we have 'C' and the actual 4th character key is 'e':chr(ord('y')^ord('C')^ord('e'))# -> _
# The 5th character of the key is good (we want 'c' and we already have 'c')
# For the 6th character, we want 't' in output, but we have '~' and the actual 6th character key is 'e':chr(ord('t')^ord('~')^ord('e'))# -> o
# For the 7th character, we want 'f' in output, but we have 'a' and the actual 6th character key is 'h':chr(ord('f')^ord('a')^ord('h'))# -> o```
Okay let's set our new key ('hoo_hoo') and print the flag:
```function process(a, b) {	var len = Math.max(a.length, b.length);	var out = [];	for (var i = 0, ca, cb; i < len; i++) {		ca = a.charCodeAt(i % a.length);		cb = b.charCodeAt(i % b.length);		out.push(ca ^ cb);	}	return String.fromCharCode.apply(null, out);}
var f = 'DQ4cJgsbCVofB18sNw4wRlhfCwAbXxpTC1wwKVlcGBIaUDAGJzowYDoqTiI=';flag = atob(f);key = 'hoo_hoo!';
console.log(process(flag, key));// -> `easyctf{wh0s_a_g00d_s0urc3_v13w3r?_YOU_ARE!}````
We can validate the chall with this flag =)