clownflare-orig-mirror/clownflare.c

194 lines
3.4 KiB
C

#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#ifdef __OpenBSD__
#include <unistd.h>
#else
#define pledge(a,b) 0
#endif
#include "xml.h"
static XMLParser x;
static char tag[256], inputname[256];
static char jschl_vc[256];
static char jschl_answer[256];
static char pass[256];
static char script[4096];
void
xmltagstart(struct xmlparser *x, const char *t, size_t tl)
{
if (!strcmp(t, "input") || !strcmp(t, "script"))
snprintf(tag, sizeof(tag), "%s", t);
}
void
xmltagend(struct xmlparser *x, const char *t, size_t tl, int st)
{
if (!strcmp(tag, "input"))
inputname[0] = tag[0] = '\0';
else if (!strcmp(tag, "script"))
tag[0] = '\0';
}
void
xmlattr(struct xmlparser *x, const char *t, size_t tl,
const char *a, size_t al, const char *v, size_t vl)
{
if (strcmp(tag, "input"))
return;
if (!strcmp(a, "name")) {
if (!strcmp(v, "jschl_vc") || !strcmp(v, "pass"))
snprintf(inputname, sizeof(inputname), "%s", v);
} else if (inputname[0] && !strcmp(a, "value")) {
if (!strcmp(inputname, "jschl_vc"))
snprintf(jschl_vc, sizeof(jschl_vc), "%s", v);
else if (!strcmp(inputname, "pass"))
snprintf(pass, sizeof(pass), "%s", v);
}
}
void
xmlcdata(struct xmlparser *x, const char *d, size_t dl)
{
char tmp[sizeof(script)];
if (strcmp(tag, "script"))
return;
snprintf(tmp, sizeof(tmp), "%s%s", script, d);
memcpy(script, tmp, sizeof(script));
}
int
calcvalue(char *script)
{
char *stopbreaking = "s,t,o,p,b,r,e,a,k,i,n,g,f, ";
char var[32] = "", key[32] = "", varkey[64] = "";
char *p, *s;
int op, pc, cv, nv, v = 0;
if (!(s = strstr(script, stopbreaking)))
return v;
s += strlen(stopbreaking);
for (p = s; *p; p++) {
if (*p == '=') {
*p = '\0';
snprintf(var, sizeof(var), "%s", s);
*p = '=';
break;
}
}
if (!var[0])
return v;
if (!(s = strchr(p, '"')))
return v;
s++;
for (p = s; *p; p++) {
if (*p == '"') {
*p = '\0';
snprintf(key, sizeof(key), "%s", s);
*p = '"';
break;
}
}
if (!key[0])
return v;
snprintf(varkey, sizeof(varkey), "%s.%s", var, key);
if (!(s = strchr(p, ':')))
return v;
s++;
op = '+';
while (1) {
// printf("op: %c\n", op);
pc = cv = nv = 0;
for (s = p; *s; s++) {
if (*s == ';') {
nv += cv;
// printf("nv: %d\n", nv);
break;
}
switch (*s) {
case '(':
nv += cv;
cv = 0;
break;
case '!':
case '+':
if (pc == '!')
cv++;
break;
case ')':
if (pc == ')')
break;
// printf(" cv: %d\n", cv);
nv *= 10;
break;
}
// printf(" %c\n", *s);
pc = *s;
}
switch (op) {
case '-': v -= nv; break;
case '+': v += nv; break;
case '*': v *= nv; break;
}
if (!(s = strstr(p, varkey)))
return v;
p = s + strlen(varkey);
op = *p;
}
return v;
}
int
main(int argc, char *argv[])
{
int value;
if (pledge("stdio", NULL) < 0)
err(1, "pledge");
if (argc != 2) {
fprintf(stderr, "%s <hostname>\n", argv[0]);
return 1;
}
x.xmlattr = xmlattr;
x.xmlcdata = xmlcdata;
x.xmltagstart = xmltagstart;
x.xmltagend = xmltagend;
x.getnext = getchar;
xml_parse(&x);
if (!(value = calcvalue(script)))
return 1;
value += strlen(argv[1]);
snprintf(jschl_answer, sizeof(jschl_answer), "%d", value);
printf("jschl_vc = %s\n", jschl_vc);
printf("pass = %s\n", pass);
printf("jschl_answer = %s\n", jschl_answer);
printf("\n");
printf("https://%s/cdn-cgi/l/chk_jschl?jschl_vc=%s&pass=%s&jschl_answer=%s\n",
argv[1], jschl_vc, pass, jschl_answer);
return 0;
}