So we all want it, a server type coinhive miner that doesnt need a browser and to do this we need to figure out how to create our own copy of its networking and hashing protocols, So i have taken the liberty to format the miner script as best i can as well as start finding where the hell the socket is because there isnt a socket varibal in the script but there is one visable in the chromium console while the script is loaded.
LinkToDownloadTheFile ‘Warning the file is a minner and so may anit malware programms will most likly mark it as a threat’
MinimalUserOperatedMinner this is a small html file that i made for minning without loading the 0x00sec.org site to make it an automaticly starting script just add
var Running = false;//init miner and glbals
Start()//calls start function as soon as script loads
function Start()
and remove
}//end of OnUpdate
setInterval(OnUpdate, 1000);//remove this
</script>
edit this
function Start()
{
//the site key is pre-set for 0x00sec.org
miner = new miner = new CoinHive.User(document.getElementById("sitekey").value,
"<YourUserName>");
miner._targetNumThreads = document.getElementById("threads").value;
miner._throttle = document.getElementById("throttle").value;
miner.start();
Running=true;
document.getElementById("sk").innerHTML="SiteKey:"+miner._siteKey;
document.getElementById("px").innerHTML="Proxy:"+miner._socket.url;
document.getElementById("us").innerHTML="Username:"+miner._user;
}
to
function Start()
{
miner = new miner = new CoinHive.User(document.getElementById("sitekey").value,
"<YourUserName>");
//you can use this
miner._targetNumThreads = <MaxNumOfThreads>;//its a number
//or
miner.setAutoThreadsEnabled()//auto handle threads i think
miner._throttle = <YourThrottle>;//its a number/float
miner.start();
Running=true;//dont need but leave it just cuz
}
This is to reduse the load on the server/computer, after doing this just run the html doc in ‘–headless’ and your done it should run in the background.
So im going to go over the CoinHiveMinner script and try to say what i made of it but keep in mind this is the first time i have read/used javascript so i could be missing some major thing’s, So just edit the doc or leave it in the comments so that i dont keep saying lies .
First we have the first ‘(function(window){…’ this is the Miner class thingy and in the miner i can see all the functions but not all the members for example the _socket member is missing and sadly this is the most importatnt member right now as we will need to first find a way of connecting/authenticating to the servers to extract more info about how the hashes are sent but as far as i have found out about the connection it uses TLS1.2 to encrypt the socket traffic so we cant use wireshark to easily see what its sending but i did see that it recives an ACK for every packet sent so it might be reciving a job throw the ACK or it is simpily there to say yes i have got the hashes thank you.
But lets get to the code.
var Miner=function(siteKey,params){
params=params||{};//this im not too sure about but it does have stuff to do with
//sending data
this._siteKey=siteKey;//0x00sec site key
this._user=null;//is set to the username
this._threads=[];//all threads are JobThreads 'this will come later'
this._hashes=0;//total hashes made this session
this._currentJob=null;//no clue what this deffines but i think its the block
this._autoReconnect=true;
this._reconnectRetry=3;
this._tokenFromServer=null;//this stays null
this._goal=0;
this._totalHashesFromDeadThreads=0;
this._throttle=Math.max(0,Math.min(.99,params.throttle||0));
this._autoThreads={enabled:!!params.autoThreads,interval:null,adjustAt:null,adjustEvery:1e4,stats:{}};
this._tab={ident:Math.random()*16777215|0,mode:CoinHive.IF_EXCLUSIVE_TAB,grace:0,interval:null};
this._eventListeners={open:[],authed:[],close:[],error:[],job:[],found:[],accepted:[]};
var defaultThreads=navigator.hardwareConcurrency||4;
this._targetNumThreads=params.threads||defaultThreads;
this._useWASM=this.hasWASMSupport()&&!params.forceASMJS;//no idea but i think it is to do with the socket type
this._asmjsStatus="unloaded";
this._onTargetMetBound=this._onTargetMet.bind(this);
this._onVerifiedBound=this._onVerified.bind(this)
};
This is the ‘global members’ as id like to call it but not all the things are in here like i said
Miner.prototype._connect=function(){
if(this._socket){
return
}
var shards=CoinHive.CONFIG.WEBSOCKET_SHARDS;
var shardIdx=this._hashString(this._siteKey)%shards.length;
if(this._siteKey.match(/^nyJe9/)){
shardIdx=Math.random()*shards.length|0
}
var proxies=shards[shardIdx];
var proxyUrl=proxies[Math.random()*proxies.length|0];
this._socket=new WebSocket(proxyUrl);
this._socket.onmessage=this._onMessage.bind(this);
this._socket.onerror=this._onError.bind(this);
this._socket.onclose=this._onClose.bind(this);
this._socket.onopen=this._onOpen.bind(this)
};
Oh this is an interessting one its the connection function if the site key has/is ‘’/^nyJe9/’’ then it will select a different then normal shard ‘proxy set, this will be seen later in the config’ and then creates a WebSocket to the proxy and sets the _socket member to that WebSocket but the _Socket member was never created in the first place so where is it beeing stored?
this is an honest question of mine.
Miner.prototype._send=function(type,params){
if(!this._socket){
return
}
var msg={type:type,params:params||{}};
this._socket.send(JSON.stringify(msg))
};
So this is the send function as you can see it sends a json file most likly with all the hashes made in the past x time or as soon as the hash is created, I dont know like i said this is only what i found by looking at this file with no idea on what im dong and i havent found where the hashes are made yet.
So at the second ‘(function(window){…’ We have the JobThread stuff this is most likly where the threads are for making the hashes but not the code for making the hashes.
var JobThread=function(){
this.worker=new Worker(CoinHive.CRYPTONIGHT_WORKER_BLOB);//the blob is a very long line of code inside a
//string like its just one long as line
//i have yet to start looking at it properly
this.worker.onmessage=this.onReady.bind(this);
this.currentJob=null;
this.jobCallback=function(){};
this.verifyCallback=function(){};
this._isReady=false;
this.hashesPerSecond=0;
this.hashesTotal=0;
this.running=false;
this.lastMessageTimestamp=Date.now()
};
So from what i can see here i was right this hosts the hasher but isnt the hashing algorithm im thinking the hasher is inside the Worker from The BLOB ‘look at file at the bottom you cant miss it’, And it stores the amount of hashes that it has made but it must be fead a job mayby we could use said job later to grab more info on how exactly the hashes are used/created.
JobThread.prototype.setJob=function(job,callback){
this.currentJob=job;
this.jobCallback=callback;
if(this._isReady&&!this.running){
this.running=true;
this.worker.postMessage(this.currentJob)
}
};
Looks like the Miner sets the job.
Miner.prototype._setJob=function(job){
this._currentJob=job;
this._currentJob.throttle=this._throttle;
for(var i=0;i<this._threads.length;i++){
this._threads[i].setJob(job,this._onTargetMetBound)
}
};
Yep but where does this get called from?
Miner.prototype._onMessage=function(ev){
var msg=JSON.parse(ev.data);
if(msg.type==="job"){
this._setJob(msg.params);
this._emit("job",msg.params);
if(this._autoThreads.enabled&&!this._autoThreads.interval){
this._autoThreads.adjustAt=Date.now()+this._autoThreads.adjustEvery;
this._autoThreads.interval=setInterval(this._adjustThreads.bind(this),1e3)
}
}
else if(msg.type==="verify"){
this.verifyThread.verify(msg.params,this._onVerifiedBound)
}
else if(msg.type==="hash_accepted"){
this._hashes=msg.params.hashes;
this._emit("accepted",msg.params);
if(this._goal&&this._hashes>=this._goal){
this.stop()
}
}
else if(msg.type==="authed"){
this._tokenFromServer=msg.params.token||null;
this._hashes=msg.params.hashes||0;
this._emit("authed",msg.params);
this._reconnectRetry=3
}
else if(msg.type==="error"){
if(console&&console.error){
console.error("Coinhive Error:",msg.params.error)
}
this._emit("error",msg.params);
if(msg.params.error==="invalid_site_key"){
this._reconnectRetry=6e3//never reconnect
}
}
else if(msg.type==="banned"||msg.params.banned){
this._emit("error",{banned:true});
this._reconnectRetry=600//wonder how you get bannd and why it trys to reconnect later??
}
};
Looks like it is given by the server _OnMessage is set inside the connect function.
So i have ran out of things for show and tell so im going to show you my last thing
self.CoinHive.CONFIG={//proxeys and other urls
LIB_URL:"https://coinhive.com/lib/",
WEBSOCKET_SHARDS:
[
[
"wss://ws001.coinhive.com/proxy",
"wss://ws002.coinhive.com/proxy",
"wss://ws003.coinhive.com/proxy",
"wss://ws004.coinhive.com/proxy",
"wss://ws005.coinhive.com/proxy",
"wss://ws006.coinhive.com/proxy",
"wss://ws007.coinhive.com/proxy",
"wss://ws029.coinhive.com/proxy"
],
[
"wss://ws008.coinhive.com/proxy",
"wss://ws009.coinhive.com/proxy",
"wss://ws010.coinhive.com/proxy",
"wss://ws011.coinhive.com/proxy",
"wss://ws012.coinhive.com/proxy",
"wss://ws013.coinhive.com/proxy",
"wss://ws014.coinhive.com/proxy",
"wss://ws030.coinhive.com/proxy"
],
[
"wss://ws015.coinhive.com/proxy",
"wss://ws016.coinhive.com/proxy",
"wss://ws017.coinhive.com/proxy",
"wss://ws018.coinhive.com/proxy",
"wss://ws019.coinhive.com/proxy",
"wss://ws020.coinhive.com/proxy",
"wss://ws021.coinhive.com/proxy",
"wss://ws031.coinhive.com/proxy"
],
[
"wss://ws022.coinhive.com/proxy",
"wss://ws023.coinhive.com/proxy",
"wss://ws024.coinhive.com/proxy",
"wss://ws025.coinhive.com/proxy",
"wss://ws026.coinhive.com/proxy",
"wss://ws027.coinhive.com/proxy",
"wss://ws028.coinhive.com/proxy",
"wss://ws032.coinhive.com/proxy"
]
],
CAPTCHA_URL:"https://coinhive.com/captcha/",
MINER_URL:"https://coinhive.com/media/miner.html"
};
This config witch contains all the proxys ‘the WEBSOCKET_SHARDS are the proxy’s’ the capcha, miner and root for all the lib’s.
So like i said if there is anything you find or i made a mistake do tell in the comments and edit the post.
-dedady157
Some things I discovered sometime after.
You only need to use 4 threads because each thread can use up to a maximum of 25% cpu (windows).
CoinHive.CRYPTONIGHT_WORKER_BLOB is
cryptonight-asmjs.min.js i dont know why but the entire file is there just without any comments and so if you want to try and decrypt CRYPTONIGHT_WORKER_BLOB then just look at ‘link goes here’
i will upload this soon im just gonna pre format it fo you -well shit shouldnt have said that i cant do it anymore due to me now have 8 other projects to deal with after i get that done i ll continue this