Skip to content
This repository has been archived by the owner on May 17, 2023. It is now read-only.

Commit

Permalink
Remove hack, back up to speed 😎
Browse files Browse the repository at this point in the history
You'll need Node installed though
  • Loading branch information
JustTalDevelops committed Apr 4, 2021
1 parent f50c7be commit 907b931
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions hsl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,32 @@ package hcaptcha

import (
"errors"
"github.com/tidwall/gjson"
"io/ioutil"
"net/http"
"os"
"os/exec"
"strings"
)

// HSL contains the code needed to be sent to Wandbox to generate an n token for hCaptcha.
// TODO: Stop relying on Wandbox and fix v8go integration
const HSL = `{"compiler":"nodejs-14.0.0","code":"function atob(a) {\n return Buffer.from(a, 'base64').toString('binary');\n}\n \nvar hsl = function() {\n \"use strict\";\n Date.prototype.toISOString || function() {\n function r(r) {\n var t = String(r);\n return 1 === t.length && (t = \"0\" + t), t\n }\n Date.prototype.toISOString = function() {\n return this.getUTCFullYear() + \"-\" + r(this.getUTCMonth() + 1) + \"-\" + r(this.getUTCDate()) + \"T\" + r(this.getUTCHours()) + \":\" + r(this.getUTCMinutes()) + \":\" + r(this.getUTCSeconds()) + \".\" + String((this.getUTCMilliseconds() / 1e3).toFixed(3)).slice(2, 5) + \"Z\"\n }\n }();\n var r = function(r) {\n try {\n var t = r.split(\".\");\n return {\n header: JSON.parse(atob(t[0])),\n payload: JSON.parse(atob(t[1])),\n signature: atob(t[2].replace(/_/g, \"/\").replace(/-/g, \"+\")),\n raw: {\n header: t[0],\n payload: t[1],\n signature: t[2]\n }\n }\n } catch (e) {\n throw new Error(\"Token is invalid.\")\n }\n },\n t = {\n hash: function(r) {\n if (\"string\" != typeof r) throw new Error(\"Message Must Be String\");\n for (var e = [1518500249, 1859775393, 2400959708, 3395469782], n = [1732584193, 4023233417, 2562383102, 271733878, 3285377520], o = unescape(encodeURIComponent(r)), a = (o += String.fromCharCode(128)).length / 4 + 2, i = Math.ceil(a / 16), s = new Array(i), u = 0; u < i; u++) {\n s[u] = new Array(16);\n for (var c = 0; c < 16; c++) s[u][c] = o.charCodeAt(64 * u + 4 * c + 0) << 24 | o.charCodeAt(64 * u + 4 * c + 1) << 16 | o.charCodeAt(64 * u + 4 * c + 2) << 8 | o.charCodeAt(64 * u + 4 * c + 3) << 0\n }\n s[i - 1][14] = 8 * (o.length - 1) / Math.pow(2, 32), s[i - 1][14] = Math.floor(s[i - 1][14]), s[i - 1][15] = 8 * (o.length - 1) & 4294967295;\n for (var f = 0; f < i; f++) {\n for (var h = new Array(80), l = 0; l < 16; l++) h[l] = s[f][l];\n for (var g = 16; g < 80; g++) h[g] = t.rotateLeft(h[g - 3] ^ h[g - 8] ^ h[g - 14] ^ h[g - 16], 1);\n for (var d = n[0], v = n[1], p = n[2], w = n[3], y = n[4], S = 0; S < 80; S++) {\n var C = Math.floor(S / 20),\n T = t.rotateLeft(d, 5) + t.f(C, v, p, w) + y + e[C] + h[S] >>> 0;\n y = w, w = p, p = t.rotateLeft(v, 30) >>> 0, v = d, d = T\n }\n n[0] = n[0] + d >>> 0, n[1] = n[1] + v >>> 0, n[2] = n[2] + p >>> 0, n[3] = n[3] + w >>> 0, n[4] = n[4] + y >>> 0\n }\n return n\n },\n digest: function(r) {\n return [r[0] >> 24 & 255, r[0] >> 16 & 255, r[0] >> 8 & 255, 255 & r[0], r[1] >> 24 & 255, r[1] >> 16 & 255, r[1] >> 8 & 255, 255 & r[1], r[2] >> 24 & 255, r[2] >> 16 & 255, r[2] >> 8 & 255, 255 & r[2], r[3] >> 24 & 255, r[3] >> 16 & 255, r[3] >> 8 & 255, 255 & r[3], r[4] >> 24 & 255, r[4] >> 16 & 255, r[4] >> 8 & 255, 255 & r[4]]\n },\n hex: function(r) {\n for (var t = [], e = 0; e < r.length; e++) t.push((\"00000000\" + r[e].toString(16)).slice(-8));\n return t.join(\"\")\n },\n rotateLeft: function(r, t) {\n return r << t | r >>> 32 - t\n },\n f: function(r, t, e, n) {\n switch (r) {\n case 0:\n return t & e ^ ~t & n;\n case 1:\n return t ^ e ^ n;\n case 2:\n return t & e ^ t & n ^ e & n;\n case 3:\n return t ^ e ^ n\n }\n }\n },\n e = \"0123456789/:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n function n(r, t) {\n var e = function(r, t) {\n for (var e = 0; e < 25; e++) {\n for (var n = Array(e), s = 0; s < e; s++) n[s] = 0;\n for (; a(n);) {\n var u = t + \"::\" + i(n);\n if (o(r, u)) return i(n)\n }\n }\n }(r, t);\n return \"1:\" + r + \":\" + (new Date).toISOString().slice(0, 19).replace(/[-:T]/g, \"\") + \":\" + t + \"::\" + e\n }\n\n function o(r, e) {\n return function(r, t) {\n var e, n = -1,\n o = [];\n for (; ++n < 8 * t.length;) e = t[Math.floor(n / 8)] >> n % 8 & 1, o.push(e);\n var a = o.slice(0, r);\n return 0 == a[0] && (a.indexOf(1) >= r - 1 || -1 == a.indexOf(1))\n }(r, (n = e, o = t.hash(n), t.digest(o)));\n var n, o\n }\n\n function a(r) {\n for (var t = r.length - 1; t >= 0; t--) {\n if (r[t] < e.length - 1) return r[t] += 1, !0;\n r[t] = 0\n }\n return !1\n }\n\n function i(r) {\n for (var t = \"\", n = 0; n < r.length; n++) t += e[r[n]];\n return t\n }\n var s = new Function(\"try{return(function(){try{return this===window&&this.document!=='undefined';}catch(e){return false;}}())&&!(function(){try{return this===global||(typeof process!=='undefined'&&process.versions!=null&&process.versions.node!=null);}catch(e){return false;}}())&&!(function(){try{return this===window&&(this.name==='nodejs'||navigator.userAgent.includes('Node.js')||navigator.userAgent.includes('jsdom'))}catch(e){return false;}}())}catch(e){return false;}\");\n return function(t) {\n return new Promise((function(e, o) {\n try {\n var a = r(t).payload,\n i = (s() ? \"\" : \"@\") + a.d,\n u = a.s;\n if (!i || !u) throw new TypeError(\"Invalid Spec\");\n e(n(u, i))\n } catch (c) {\n o(c)\n }\n }))\n }\n}();\n\nhsl('%hsl%').then(function(result) {\n console.log(result);\n});","codes":[],"stdin":"","options":"","runtime-option-raw":""}`
// HSL contains the code needed to generate an N token.
const HSL = `function atob(r){return Buffer.from(r,"base64").toString("binary")}var hsl=function(){"use strict";Date.prototype.toISOString||function(){function r(r){var t=String(r);return 1===t.length&&(t="0"+t),t}Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+r(this.getUTCMonth()+1)+"-"+r(this.getUTCDate())+"T"+r(this.getUTCHours())+":"+r(this.getUTCMinutes())+":"+r(this.getUTCSeconds())+"."+String((this.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"}}();var r={hash:function(t){if("string"!=typeof t)throw new Error("Message Must Be String");for(var e=[1518500249,1859775393,2400959708,3395469782],n=[1732584193,4023233417,2562383102,271733878,3285377520],o=unescape(encodeURIComponent(t)),a=(o+=String.fromCharCode(128)).length/4+2,i=Math.ceil(a/16),s=new Array(i),u=0;u<i;u++){s[u]=new Array(16);for(var c=0;c<16;c++)s[u][c]=o.charCodeAt(64*u+4*c+0)<<24|o.charCodeAt(64*u+4*c+1)<<16|o.charCodeAt(64*u+4*c+2)<<8|o.charCodeAt(64*u+4*c+3)<<0}s[i-1][14]=8*(o.length-1)/Math.pow(2,32),s[i-1][14]=Math.floor(s[i-1][14]),s[i-1][15]=8*(o.length-1)&4294967295;for(var f=0;f<i;f++){for(var h=new Array(80),l=0;l<16;l++)h[l]=s[f][l];for(var g=16;g<80;g++)h[g]=r.rotateLeft(h[g-3]^h[g-8]^h[g-14]^h[g-16],1);for(var d=n[0],v=n[1],p=n[2],w=n[3],y=n[4],S=0;S<80;S++){var C=Math.floor(S/20),T=r.rotateLeft(d,5)+r.f(C,v,p,w)+y+e[C]+h[S]>>>0;y=w,w=p,p=r.rotateLeft(v,30)>>>0,v=d,d=T}n[0]=n[0]+d>>>0,n[1]=n[1]+v>>>0,n[2]=n[2]+p>>>0,n[3]=n[3]+w>>>0,n[4]=n[4]+y>>>0}return n},digest:function(r){return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]},hex:function(r){for(var t=[],e=0;e<r.length;e++)t.push(("00000000"+r[e].toString(16)).slice(-8));return t.join("")},rotateLeft:function(r,t){return r<<t|r>>>32-t},f:function(r,t,e,n){switch(r){case 0:return t&e^~t&n;case 1:return t^e^n;case 2:return t&e^t&n^e&n;case 3:return t^e^n}}},t="0123456789/:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";function e(r,t){var e=function(r,t){for(var e=0;e<25;e++){for(var i=Array(e),s=0;s<e;s++)i[s]=0;for(;o(i);){if(n(r,t+"::"+a(i)))return a(i)}}}(r,t);return"1:"+r+":"+(new Date).toISOString().slice(0,19).replace(/[-:T]/g,"")+":"+t+"::"+e}function n(t,e){return function(r,t){for(var e,n=-1,o=[];++n<8*t.length;)e=t[Math.floor(n/8)]>>n%8&1,o.push(e);var a=o.slice(0,r);return 0==a[0]&&(a.indexOf(1)>=r-1||-1==a.indexOf(1))}(t,(n=e,o=r.hash(n),r.digest(o)));var n,o}function o(r){for(var e=r.length-1;e>=0;e--){if(r[e]<t.length-1)return r[e]+=1,!0;r[e]=0}return!1}function a(r){for(var e="",n=0;n<r.length;n++)e+=t[r[n]];return e}var i=new Function("try{return(function(){try{return this===window&&this.document!=='undefined';}catch(e){return false;}}())&&!(function(){try{return this===global||(typeof process!=='undefined'&&process.versions!=null&&process.versions.node!=null);}catch(e){return false;}}())&&!(function(){try{return this===window&&(this.name==='nodejs'||navigator.userAgent.includes('Node.js')||navigator.userAgent.includes('jsdom'))}catch(e){return false;}}())}catch(e){return false;}");return function(r){return new Promise(function(t,n){try{var o=function(r){try{var t=r.split(".");return{header:JSON.parse(atob(t[0])),payload:JSON.parse(atob(t[1])),signature:atob(t[2].replace(/_/g,"/").replace(/-/g,"+")),raw:{header:t[0],payload:t[1],signature:t[2]}}}catch(r){throw new Error("Token is invalid.")}}(r).payload,a=(i()?"":"@")+o.d,s=o.s;if(!a||!s)throw new TypeError("Invalid Spec");t(e(s,a))}catch(r){n(r)}})}}();hsl(process.argv[2]).then(function(r){console.log(r)});`

func n(req string) (hsl string, err error) {
resp, err := http.Post("https://wandbox.org/api/compile.json", "application/json", strings.NewReader(strings.ReplaceAll(HSL, "%hsl%", req)))
func n(req string) (string, error) {
f, err := ioutil.TempFile(os.TempDir(), "hsl.*.js")
if err != nil {
return "", err
}
b, err := ioutil.ReadAll(resp.Body)
defer f.Close()
defer os.Remove(f.Name())
f.WriteString(HSL)

cmd := exec.Command("node", f.Name(), req)
cmd.Dir = os.TempDir()
out, err := cmd.Output()
if err != nil {
return "", err
}
response := string(b)
result := gjson.Parse(response)
if result.Get("status").Int() == 0 {
return strings.TrimSuffix(result.Get("program_output").String(), "\n"), nil
if strings.Contains(string(out), "Token is invalid.") {
return "", errors.New(string(out))
}
return "", errors.New(response)
return strings.TrimSpace(string(out)), nil
}

0 comments on commit 907b931

Please sign in to comment.