This challenge is the follow up of Blockshark
The server the exfiltrator was communicating with has been seized and a copy of the software has been installed on: 52.214.111.33
To obtain the flag, only the same type of traffic as the exfiltrator is needed/allowed.
To prove your knowledge send the following message to the server: "gimme the second flag …" (minus the " quotes)
Here we can start by replicating the requests found in the .pcap
file on the live host (example).
We already know the return_value
contains special information. Another giveaway for this is the incorrect formatting of the json: there is no comma delimiter after the return_code
entry.
This return_value
is also available in other /address/
requests. Let's translate with some more in-browser javascript.
Note: I loaded a small jQuery snippet in the devtools to allow for $.ajax()
requests. These requests can also be perfomed using XMLHttpRequest()
.
urls = [
"1f620e09863c3d9321492c06096b3e492012489b3b5dc03d3d6d305d082d5d9e2148301109a211",
"58d93309a22a1f5817580f13484d0a58e535097f0e091d1304e70609ba0e16031809ab1b589b0e",
"4817395d782f040e124961231f8a3e49100958a11e58cc0904e6004933003d7a2a4881251fc30b",
"191f325d7f3609e00f097400487e0b04350e1f96215dfe1d49342904b42909753358f93858c431",
"58d401048520048e352e140e09dc0e5dd03158a0331f5437584208485c1458a02d3d742a5d9136",
"3d8d1b3d660704a62f2e2f283d66025885351f603e4918092e083709d13209630d58c80158f730",
"095c2749523e1f822a04db024915020938052e182f49310409630d09e4265dfa03489408044217",
"099a174859163d530d58690758471e041027488b143dae151f841a1f1e3804350d5dd0015d6238",
"58872c5d9e211f15235d5233042e3d588b125de7294813394858373d1125042c145d973b3d8918",
"48252f1f88023dac0209e10a04f60958011f58f5312e18323d38391f791c5854035d2928582414",
"09490a580f0104f13658e12904e73548733d5d56295d201404fd1f09882304321d2e1f3449762b",
"09ae1848041e04d72604b3231f4f1e09452049741b58d00709be2c04b80f5db22e58b30e04c610",
"040e125dc73b5dd91c58e1001f2e0858210b0455011f831904471d09a3243d2a0a04592b094811",
"4965383d2b3358b32e48812558210b09ed1f097c04492c06496c20482c021fd7101fa119494f1a",
"49220b48043158a432487333495c053d751c1fac205ded1004ca1509a32d584e225dc81b04653a",
"5802353d8d1b5d03381f1f2c4820135d1d225d81123da3285d56195d3c04048b2e5dc3015d5d38",
"4861385876071fc43004241704d3381f5a2b3d080904c31f099d2d04663758183e58f70a580b06",
"58d92e58e6082e211c04e934193e1016040304012119061048552c09903158b31904142a48213d",
"09701d3d0b075824143d3d3c1f3c2b5d0d2e3d581309cc131f5e1858692e1f29220454105daa16",
"04cd2f493e1e040c3b04702a3d391e58ee1348281c04d30e58b82d48581f58592e193e0c046408",
"160620584c305d8c1404f42f04c90509e23004d30e493a012e391704ce071f1e1f58c1375d6c1e",
"09eb1e58293209ac3958f234096b0004d03358b52f094e222e182f1fac20493d3d5d5f3a5dfe1d",
"047b1a1f0312585a0258992c3daa1849673e09d6003da30e58482e588e113d192b4952343da405",
"09612958083719311e09a41a2e201c5831132e202909b8104873224846175d8c285d721f5dac26",
"5de00909340a58223c58653e5891093d5733484422497811497b0904ac225db93809173b3da829",
"5d9e051fa8132e2f32484f28048b2b042f120970355d4d0f3d9a040908161f1e30048102092e08",
"5dc41704622404e42e1f2f015dee1c485506094d3d09b6074919151f742d0992342e1214580c06",
"584a2004901209e52e2e202748570858b40c04ff061f2d0409be2c4857083da4152e082b192920",
"09943b19092f3d1f151f6227098e1a496b00192f0809df145d991f3d1939096619095204192129",
"1f061b1fcb2f48251004940309233a1f213858212948360a1fc23e160b083d9b2f584f19046c0b",
"5d56193d391e1f312c482510097e173d8e02190615097309485e2d584e221fae3b49602c04453c",
"09ca1258c62a48170404482758f6213d203858f622496e120943125d14243d7639094e035d4b24",
"58c62c58690716012b1feb1b1fac305839351f5e185dc3015859171fb13958082909ea02094f21",
"1f933409943b58cc091f753c04ec1a4964091f0b1549170a048c214869303d3f23093106097e17",
"1f10335d53302e1e254825101f0a203da41c496809496f1c5d830f1fd42f58022f58680d5d0e24",
"047b3209272258ab23097e1a04532b5d9b144939095d162609bf1e1fbf1204f30a04db0204ee2f",
"4808354973345d9b3e485f2a58210409c514042030042a3e48201f48902c58b0285d570f5d9f04",
"5d58091f4f093d660758982e1fb82209e72f585c3e1fe51d09371c5d593c2e200c040334192116"
];
out = [];
function getMessage(url) {
return $.ajax({
type: 'GET',
url: '/address/'+url+'?format=json'
});
}
function translate(data) {
return atob(/"return_value":"(.*)"/.exec(data)[1]);
}
function writeMessage() {
console.log(out.reduce((a,b)=>a+b));
}
urls.forEach((url, uindex) => {
getMessage(url).then(res => {
msg = translate(res)
out[uindex] = msg;
});
});
$(document).ajaxStop(() => {
writeMessage();
});
This will reveal the following message:
Top Secret !!! A novel substance was sucessfully extracted from the leaves of the tea bush and also from kola nuts. After complex and dangerous experimetnts a white solid was obtained with a melting point of 500K. Chemical analysis revealed the followibg composition: 1,3,7-Trimethylpurine-2,6-dione. This new subtance will change the way in which people will be able to work, hackers will write even more l33t c0d3 and provide hipsters with an essential ingredient for their gatherings. --
Each return_value
contained 13 characters. Each requested 'address' also contained 78 characters. By manipulating the request we notice any address with n*6
characters will contain a base64 string of n
characters in the return_value
. Otherwise this key would return empty. Another finding is that the same 6 'address' characters (three bytes) always return the same character.
We can keep track of which three bytes form each character if we extend our script. This extension will look at each character in the return_value
string and map it to the bytes from the request. This way we build up a dictionary.
// jQuery and the url array from previous snippet is required to run this code
out = [];
dict = {};
function getMessage(url) {
return $.ajax({
type: 'GET',
url: '/address/'+url+'?format=json'
});
}
function translate(data) {
return atob(/"return_value":"(.*)"/.exec(data)[1]);
}
urls.forEach((url, uindex) => {
getMessage(url).then(res => {
msg = translate(res)
out[uindex] = msg;
// build up dictionary
msg.split("").forEach((char, cid) => {
dict[char] = url.substr(6*cid, 6);
});
});
});
After each request is parsed we have a partial dictoinary built up:
dict = {
" ":"2e200c","0":"58c62c","1":"58c137","2":"3da30e",
"3":"16012b","5":"1fc430","6":"588e11","7":"09ac39",
"!":"58d933",",":"1fcb2f","-":"192116",".":"5d593c",
":":"04ce07","A":"1f8802","C":"046637","K":"1f5a2b",
"S":"096b3e","T":"583113","a":"5d5809","b":"1f6227",
"c":"5d4b24","d":"1fbf12","e":"58982e","f":"5d9b3e",
"g":"1fe51d","h":"3d6607","i":"09e72f","k":"48360a",
"l":"58ab23","m":"481704","n":"585c3e","o":"485f2a",
"p":"496409","r":"1fb822","s":"09371c","t":"1f4f09",
"u":"58223c","v":"09ea02","w":"097e17","x":"1f4f1e",
"y":"04e42e","|":"312346"
}
To prove your knowledge send the following message to the server: "gimme the second flag …" (minus the " quotes)
function translateMessage(message) {
urlBuilder = "";
message.split("").forEach((char) => {
urlBuilder += dict[char]
});
return urlBuilder;
}
function sendMessage(message) {
getMessage(translateMessage(message)).then(res => {
console.log(translate(res));
});
}
sendMessage("gimme the second flag ...")
Upon which the second flag is returned: Flag 2: CSCBE{sdfIUerw893475#$&Y&#}