Compare commits

...

5 Commits

Author SHA1 Message Date
maia arson crimew 51374be92c show up to 20 posts per page 2023-12-06 18:22:37 +01:00
maia arson crimew b880767e1e huh how did this not commit
so glad that didnt ruin the talk lmao
2023-12-06 18:16:55 +01:00
maia arson crimew 17ced3a735 talkerware dekc thingiej 2023-11-29 23:50:04 +01:00
maia arson crimew fdd683ce88 fuckstalkerware wip talk 2023-11-28 21:33:39 +01:00
maia arson crimew adfc255898 add reveal.js support 2023-11-11 13:43:55 +01:00
17 changed files with 946 additions and 333 deletions

View File

@ -1,16 +1,20 @@
const path = require("node:path");
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
const pluginRss = require('@11ty/eleventy-plugin-rss');
const timeToRead = require('eleventy-plugin-time-to-read');
const safeLinks = require('@sardine/eleventy-plugin-external-links');
const eleventySass = require("@11tyrocks/eleventy-plugin-sass-lightningcss");
const related = require("eleventy-plugin-related");
const markdownIt = require("markdown-it");
const markdownItAnchor = require("markdown-it-anchor");
const sass = require("sass");
const figure = require('./src/_includes/components/figure.js');
const bounce = require('./src/_includes/components/bounce.js');
module.exports = function (eleventyConfig) {
const isDev = (process.env.ELEVENTY_ENV || "dev") == "dev";
const parseDate = (str) => {
if (str instanceof Date) {
return str;
@ -33,19 +37,30 @@ module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(syntaxHighlight);
eleventyConfig.addPlugin(timeToRead);
eleventyConfig.addPlugin(safeLinks);
eleventyConfig.addPlugin(eleventySass);
eleventyConfig.addShortcode('figure', figure(md));
eleventyConfig.addShortcode('bounce', bounce);
eleventyConfig.addPassthroughCopy({ "src/static": "/" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/dist/reveal.css": "reveal.js/reveal.css" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/dist/reveal.esm.js": "reveal.js/reveal.esm.js" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/markdown/markdown.esm.js": "reveal.js/plugin/markdown/markdown.esm.js" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/highlight/highlight.esm.js": "reveal.js/plugin/highlight/highlight.esm.js" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/highlight/monokai.css": "reveal.js/plugin/highlight/monokai.css" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/notes/notes.esm.js": "reveal.js/plugin/notes/notes.esm.js" });
eleventyConfig.addFilter("date_to_datetime", async (obj) => {
if (!obj) {
return "";
}
const date = parseDate(obj);
return date.toISOString();
});
eleventyConfig.addFilter("date_formatted", async (obj) => {
if (!obj) {
return "";
}
const date = parseDate(obj);
const month = formatPart({ month: "short" }, date);
@ -93,6 +108,38 @@ module.exports = function (eleventyConfig) {
return collection.getFilteredByGlob('src/posts/*.md').reverse()
});
eleventyConfig.addCollection('decks', collection => {
return collection.getFilteredByGlob('src/decks/*.md')
// append the raw content
.map(item => {
const content = item.template.frontMatter.content;
item.data.rawMarkdown = content || "";
return item;
});
});
eleventyConfig.addTemplateFormats("scss");
eleventyConfig.addExtension("scss", {
outputFileExtension: "css",
compile: function (inputContent, inputPath) {
let parsed = path.parse(inputPath);
let result = sass.compileString(inputContent, {
style: isDev ? "expanded" : "compressed",
loadPaths: [
parsed.dir || "."
]
});
this.addDependencies(inputPath, result.loadedUrls);
return async (data) => {
return result.css;
};
}
})
return {
templateFormats: ["njk", "md", "html"],
dir: {

333
package-lock.json generated
View File

@ -11,12 +11,13 @@
"@11ty/eleventy": "^v2.0.1",
"@11ty/eleventy-plugin-rss": "^1.2.0",
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0",
"@11tyrocks/eleventy-plugin-sass-lightningcss": "^1.1.0",
"@sardine/eleventy-plugin-external-links": "^1.4.0",
"eleventy-plugin-related": "^1.0.6",
"eleventy-plugin-time-to-read": "^1.3.0",
"markdown-it": "^13.0.2",
"markdown-it-anchor": "^8.6.7"
"markdown-it-anchor": "^8.6.7",
"reveal.js": "^5.0.1",
"sass": "^1.69.5"
}
},
"node_modules/@11ty/dependency-tree": {
@ -160,16 +161,6 @@
"url": "https://opencollective.com/11ty"
}
},
"node_modules/@11tyrocks/eleventy-plugin-sass-lightningcss": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@11tyrocks/eleventy-plugin-sass-lightningcss/-/eleventy-plugin-sass-lightningcss-1.1.0.tgz",
"integrity": "sha512-drewdlN7+ySz+wBuxSajSQauE8v8QcnfiXBDBEG2+GsnJhUOgNQvxZQDcLPoovFecLknZWGheRoA1zVNK+W5yg==",
"dependencies": {
"browserslist": "^4.22.1",
"lightningcss": "^1.22.0",
"sass": "^1.68.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
@ -530,37 +521,6 @@
"node": ">=8"
}
},
"node_modules/browserslist": {
"version": "4.22.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
"integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/browserslist"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001541",
"electron-to-chromium": "^1.4.535",
"node-releases": "^2.0.13",
"update-browserslist-db": "^1.0.13"
},
"bin": {
"browserslist": "cli.js"
},
"engines": {
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
"node_modules/call-bind": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
@ -574,25 +534,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001555",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001555.tgz",
"integrity": "sha512-NzbUFKUnJ3DTcq6YyZB6+qqhfD112uR3uoEnkmfzm2wVzUNsFkU7AwBjKQ654Sp5cau0JxhFyRSn/tQZ+XfygA==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@ -761,17 +702,6 @@
"node": ">= 0.6.0"
}
},
"node_modules/detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
"bin": {
"detect-libc": "bin/detect-libc.js"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/dev-ip": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
@ -858,11 +788,6 @@
"node": ">=0.10.0"
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.569",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz",
"integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg=="
},
"node_modules/eleventy-plugin-related": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/eleventy-plugin-related/-/eleventy-plugin-related-1.0.6.tgz",
@ -924,14 +849,6 @@
"errno": "cli.js"
}
},
"node_modules/escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"engines": {
"node": ">=6"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@ -1516,203 +1433,6 @@
"node": ">=6"
}
},
"node_modules/lightningcss": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.22.0.tgz",
"integrity": "sha512-+z0qvwRVzs4XGRXelnWRNwqsXUx8k3bSkbP8vD42kYKSk3z9OM2P3e/gagT7ei/gwh8DTS80LZOFZV6lm8Z8Fg==",
"dependencies": {
"detect-libc": "^1.0.3"
},
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"lightningcss-darwin-arm64": "1.22.0",
"lightningcss-darwin-x64": "1.22.0",
"lightningcss-freebsd-x64": "1.22.0",
"lightningcss-linux-arm-gnueabihf": "1.22.0",
"lightningcss-linux-arm64-gnu": "1.22.0",
"lightningcss-linux-arm64-musl": "1.22.0",
"lightningcss-linux-x64-gnu": "1.22.0",
"lightningcss-linux-x64-musl": "1.22.0",
"lightningcss-win32-x64-msvc": "1.22.0"
}
},
"node_modules/lightningcss-darwin-arm64": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.22.0.tgz",
"integrity": "sha512-aH2be3nNny+It5YEVm8tBSSdRlBVWQV8m2oJ7dESiYRzyY/E/bQUe2xlw5caaMuhlM9aoTMtOH25yzMhir0qPg==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-darwin-x64": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.22.0.tgz",
"integrity": "sha512-9KHRFA0Y6mNxRHeoQMp0YaI0R0O2kOgUlYPRjuasU4d+pI8NRhVn9bt0yX9VPs5ibWX1RbDViSPtGJvYYrfVAQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-freebsd-x64": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.22.0.tgz",
"integrity": "sha512-xaYL3xperGwD85rQioDb52ozF3NAJb+9wrge3jD9lxGffplu0Mn35rXMptB8Uc2N9Mw1i3Bvl7+z1evlqVl7ww==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-linux-arm-gnueabihf": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.22.0.tgz",
"integrity": "sha512-epQGvXIjOuxrZpMpMnRjK54ZqzhiHhCPLtHvw2fb6NeK2kK9YtF0wqmeTBiQ1AkbWfnnXGTstYaFNiadNK+StQ==",
"cpu": [
"arm"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-linux-arm64-gnu": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.22.0.tgz",
"integrity": "sha512-AArGtKSY4DGTA8xP8SDyNyKtpsUl1Rzq6FW4JomeyUQ4nBrR71uPChksTpj3gmWuGhZeRKLeCUI1DBid/zhChg==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-linux-arm64-musl": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.22.0.tgz",
"integrity": "sha512-RRraNgP8hnBPhInTTUdlFm+z16C/ghbxBG51Sw00hd7HUyKmEUKRozyc5od+/N6pOrX/bIh5vIbtMXIxsos0lg==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-linux-x64-gnu": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.22.0.tgz",
"integrity": "sha512-grdrhYGRi2KrR+bsXJVI0myRADqyA7ekprGxiuK5QRNkv7kj3Yq1fERDNyzZvjisHwKUi29sYMClscbtl+/Zpw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-linux-x64-musl": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.22.0.tgz",
"integrity": "sha512-t5f90X+iQUtIyR56oXIHMBUyQFX/zwmPt72E6Dane3P8KNGlkijTg2I75XVQS860gNoEFzV7Mm5ArRRA7u5CAQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-win32-x64-msvc": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.22.0.tgz",
"integrity": "sha512-64HTDtOOZE9PUCZJiZZQpyqXBbdby1lnztBccnqh+NtbKxjnGzP92R2ngcgeuqMPecMNqNWxgoWgTGpC+yN5Sw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/linkedom": {
"version": "0.13.7",
"resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.13.7.tgz",
@ -2006,11 +1726,6 @@
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node_modules/node-releases": {
"version": "2.0.13",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -2128,11 +1843,6 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@ -2439,6 +2149,14 @@
"node": ">=0.10.0"
}
},
"node_modules/reveal.js": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-5.0.1.tgz",
"integrity": "sha512-cgbEasV/Yh8QIRyCCiOHRtio6uxAwmOAhyr80vegX2P69/iwE1FX77EXJ9NAPvcODxoIyYrgvxAaPxR5TKcsFw==",
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@ -2713,35 +2431,6 @@
"node": ">= 0.8"
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/browserslist"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"escalade": "^3.1.1",
"picocolors": "^1.0.0"
},
"bin": {
"update-browserslist-db": "cli.js"
},
"peerDependencies": {
"browserslist": ">= 4.21.0"
}
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",

View File

@ -11,11 +11,12 @@
"@11ty/eleventy": "^v2.0.1",
"@11ty/eleventy-plugin-rss": "^1.2.0",
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0",
"@11tyrocks/eleventy-plugin-sass-lightningcss": "^1.1.0",
"@sardine/eleventy-plugin-external-links": "^1.4.0",
"eleventy-plugin-related": "^1.0.6",
"eleventy-plugin-time-to-read": "^1.3.0",
"markdown-it": "^13.0.2",
"markdown-it-anchor": "^8.6.7"
"markdown-it-anchor": "^8.6.7",
"reveal.js": "^5.0.1",
"sass": "^1.69.5"
}
}

View File

@ -0,0 +1 @@
<!-- empty until we can move away from pagination work around -->

View File

@ -0,0 +1,6 @@
$bg: rgb(254, 175, 214);
$text: rgb(92, 53, 124);
$accent: rgb(146, 0, 80);
$active-links: rgb(124, 6, 160);
$divider: rgb(219, 103, 167);
$semi-bg: rgba(221, 116, 174, 0.211);

View File

@ -0,0 +1,30 @@
// Exposes theme's variables for easy re-use in CSS for plugin authors
:root {
--r-background-color: #{$backgroundColor};
--r-main-font: #{$mainFont};
--r-main-font-size: #{$mainFontSize};
--r-main-color: #{$mainColor};
--r-block-margin: #{$blockMargin};
--r-heading-margin: #{$headingMargin};
--r-heading-font: #{$headingFont};
--r-heading-color: #{$headingColor};
--r-heading-line-height: #{$headingLineHeight};
--r-heading-letter-spacing: #{$headingLetterSpacing};
--r-heading-text-transform: #{$headingTextTransform};
--r-heading-text-shadow: #{$headingTextShadow};
--r-heading-font-weight: #{$headingFontWeight};
--r-heading1-text-shadow: #{$heading1TextShadow};
--r-heading1-size: #{$heading1Size};
--r-heading2-size: #{$heading2Size};
--r-heading3-size: #{$heading3Size};
--r-heading4-size: #{$heading4Size};
--r-code-font: #{$codeFont};
--r-link-color: #{$linkColor};
--r-link-color-dark: #{darken($linkColor , 15% )};
--r-link-color-hover: #{$linkColorHover};
--r-selection-background-color: #{$selectionBackgroundColor};
--r-selection-color: #{$selectionColor};
--r-overlay-element-bg-color: #{$overlayElementBgColor};
--r-overlay-element-fg-color: #{$overlayElementFgColor};
}

View File

@ -0,0 +1,45 @@
@mixin vertical-gradient( $top, $bottom ) {
background: $top;
background: -moz-linear-gradient( top, $top 0%, $bottom 100% );
background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) );
background: -webkit-linear-gradient( top, $top 0%, $bottom 100% );
background: -o-linear-gradient( top, $top 0%, $bottom 100% );
background: -ms-linear-gradient( top, $top 0%, $bottom 100% );
background: linear-gradient( top, $top 0%, $bottom 100% );
}
@mixin horizontal-gradient( $top, $bottom ) {
background: $top;
background: -moz-linear-gradient( left, $top 0%, $bottom 100% );
background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) );
background: -webkit-linear-gradient( left, $top 0%, $bottom 100% );
background: -o-linear-gradient( left, $top 0%, $bottom 100% );
background: -ms-linear-gradient( left, $top 0%, $bottom 100% );
background: linear-gradient( left, $top 0%, $bottom 100% );
}
@mixin radial-gradient( $outer, $inner, $type: circle ) {
background: $outer;
background: -moz-radial-gradient( center, $type cover, $inner 0%, $outer 100% );
background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) );
background: -webkit-radial-gradient( center, $type cover, $inner 0%, $outer 100% );
background: -o-radial-gradient( center, $type cover, $inner 0%, $outer 100% );
background: -ms-radial-gradient( center, $type cover, $inner 0%, $outer 100% );
background: radial-gradient( center, $type cover, $inner 0%, $outer 100% );
}
@mixin light-bg-text-color( $color ) {
section.has-light-background {
&, h1, h2, h3, h4, h5, h6 {
color: $color;
}
}
}
@mixin dark-bg-text-color( $color ) {
section.has-dark-background {
&, h1, h2, h3, h4, h5, h6 {
color: $color;
}
}
}

View File

@ -0,0 +1,50 @@
// Base settings for all themes that can optionally be
// overridden by the super-theme
// Background of the presentation
$backgroundColor: #2b2b2b;
// Primary/body text
$mainFont: 'Lato', sans-serif;
$mainFontSize: 40px;
$mainColor: #eee;
// Vertical spacing between blocks of text
$blockMargin: 20px;
// Headings
$headingMargin: 0 0 $blockMargin 0;
$headingFont: 'League Gothic', Impact, sans-serif;
$headingColor: #eee;
$headingLineHeight: 1.2;
$headingLetterSpacing: normal;
$headingTextTransform: uppercase;
$headingTextShadow: none;
$headingFontWeight: normal;
$heading1TextShadow: $headingTextShadow;
$heading1Size: 3.77em;
$heading2Size: 2.11em;
$heading3Size: 1.55em;
$heading4Size: 1.00em;
$codeFont: monospace;
// Links and actions
$linkColor: #13DAEC;
$linkColorHover: lighten( $linkColor, 20% );
// Text selection
$selectionBackgroundColor: #FF5E99;
$selectionColor: #fff;
// Colors used for UI elements that are overlaid on top of
// the presentation
$overlayElementBgColor: 240, 240, 240;
$overlayElementFgColor: 0, 0, 0;
// Generates the presentation background, can be overridden
// to return a background image or gradient
@mixin bodyBackground() {
background: $backgroundColor;
}

View File

@ -0,0 +1,331 @@
// Base theme template for reveal.js
/*********************************************
* GLOBAL STYLES
*********************************************/
@import "./exposer";
.reveal-viewport {
@include bodyBackground();
background-color: var(--r-background-color);
}
.reveal {
font-family: var(--r-main-font);
font-size: var(--r-main-font-size);
font-weight: normal;
color: var(--r-main-color);
}
.reveal ::selection {
color: var(--r-selection-color);
background: var(--r-selection-background-color);
text-shadow: none;
}
.reveal ::-moz-selection {
color: var(--r-selection-color);
background: var(--r-selection-background-color);
text-shadow: none;
}
.reveal .slides section,
.reveal .slides section>section {
line-height: 1.3;
font-weight: inherit;
}
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: var(--r-heading-margin);
color: var(--r-heading-color);
font-family: var(--r-heading-font);
font-weight: var(--r-heading-font-weight);
line-height: var(--r-heading-line-height);
letter-spacing: var(--r-heading-letter-spacing);
text-transform: var(--r-heading-text-transform);
text-shadow: var(--r-heading-text-shadow);
word-wrap: break-word;
}
.reveal h1 {font-size: var(--r-heading1-size); }
.reveal h2 {font-size: var(--r-heading2-size); }
.reveal h3 {font-size: var(--r-heading3-size); }
.reveal h4 {font-size: var(--r-heading4-size); }
.reveal h1 {
text-shadow: var(--r-heading1-text-shadow);
}
/*********************************************
* OTHER
*********************************************/
.reveal p {
margin: var(--r-block-margin) 0;
line-height: 1.3;
}
/* Remove trailing margins after titles */
.reveal h1:last-child,
.reveal h2:last-child,
.reveal h3:last-child,
.reveal h4:last-child,
.reveal h5:last-child,
.reveal h6:last-child {
margin-bottom: 0;
}
/* Ensure certain elements are never larger than the slide itself */
.reveal img,
.reveal video,
.reveal iframe {
max-width: 95%;
max-height: 95%;
}
.reveal strong,
.reveal b {
font-weight: bold;
}
.reveal em {
font-style: italic;
}
.reveal ol,
.reveal dl,
.reveal ul {
display: inline-block;
text-align: left;
margin: 0 0 0 1em;
}
.reveal ol {
list-style-type: decimal;
}
.reveal ul {
list-style-type: disc;
}
.reveal ul ul {
list-style-type: square;
}
.reveal ul ul ul {
list-style-type: circle;
}
.reveal ul ul,
.reveal ul ol,
.reveal ol ol,
.reveal ol ul {
display: block;
margin-left: 40px;
}
.reveal dt {
font-weight: bold;
}
.reveal dd {
margin-left: 40px;
}
.reveal blockquote {
display: block;
position: relative;
width: 70%;
margin: var(--r-block-margin) auto;
padding: 5px;
font-style: italic;
background: rgba(255, 255, 255, 0.05);
box-shadow: 0px 0px 2px rgba(0,0,0,0.2);
}
.reveal blockquote p:first-child,
.reveal blockquote p:last-child {
display: inline-block;
}
.reveal q {
font-style: italic;
}
.reveal pre {
display: block;
position: relative;
width: 90%;
margin: var(--r-block-margin) auto;
text-align: left;
font-size: 0.55em;
font-family: var(--r-code-font);
line-height: 1.2em;
word-wrap: break-word;
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
}
.reveal code {
font-family: var(--r-code-font);
text-transform: none;
tab-size: 2;
}
.reveal pre code {
display: block;
padding: 5px;
overflow: auto;
max-height: 400px;
word-wrap: normal;
}
.reveal .code-wrapper {
white-space: normal;
}
.reveal .code-wrapper code {
white-space: pre;
}
.reveal table {
margin: auto;
border-collapse: collapse;
border-spacing: 0;
}
.reveal table th {
font-weight: bold;
}
.reveal table th,
.reveal table td {
text-align: left;
padding: 0.2em 0.5em 0.2em 0.5em;
border-bottom: 1px solid;
}
.reveal table th[align="center"],
.reveal table td[align="center"] {
text-align: center;
}
.reveal table th[align="right"],
.reveal table td[align="right"] {
text-align: right;
}
.reveal table tbody tr:last-child th,
.reveal table tbody tr:last-child td {
border-bottom: none;
}
.reveal sup {
vertical-align: super;
font-size: smaller;
}
.reveal sub {
vertical-align: sub;
font-size: smaller;
}
.reveal small {
display: inline-block;
font-size: 0.6em;
line-height: 1.2em;
vertical-align: top;
}
.reveal small * {
vertical-align: top;
}
.reveal img {
margin: var(--r-block-margin) 0;
}
/*********************************************
* LINKS
*********************************************/
.reveal a {
color: var(--r-link-color);
text-decoration: none;
transition: color .15s ease;
}
.reveal a:hover {
color: var(--r-link-color-hover);
text-shadow: none;
border: none;
}
.reveal .roll span:after {
color: #fff;
// background: darken( var(--r-link-color), 15% );
background: var(--r-link-color-dark);
}
/*********************************************
* Frame helper
*********************************************/
.reveal .r-frame {
border: 4px solid var(--r-main-color);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
}
.reveal a .r-frame {
transition: all .15s linear;
}
.reveal a:hover .r-frame {
border-color: var(--r-link-color);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
}
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls {
color: var(--r-link-color);
}
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0,0,0,0.2);
color: var(--r-link-color);
}
/*********************************************
* PRINT BACKGROUND
*********************************************/
@media print {
.backgrounds {
background-color: var(--r-background-color);
}
}

40
src/css/reveal-maia.scss Normal file
View File

@ -0,0 +1,40 @@
/**
* maia site theme for reveal.js.
*/
@import "../_includes/scss/mixins";
@import "../_includes/scss/settings";
@import "../_includes/scss/colors.scss";
// Override theme settings (see ../template/settings.scss)
$backgroundColor: $bg;
$mainColor: $text;
$headingColor: $text;
$mainFontSize: 30px;
$mainFont: monospace, serif, sans-serif;
$headingFont: monospace, serif, sans-serif;
$headingTextShadow: none;
$headingLetterSpacing: normal;
$headingTextTransform: normal;
$headingFontWeight: 600;
$linkColor: $accent;
$linkColorHover: $active-links;
$selectionBackgroundColor: lighten( $linkColor, 25% );
$heading1Size: 2.5em;
$heading2Size: 1.6em;
$heading3Size: 1.3em;
$heading4Size: 1.0em;
$overlayElementBgColor: 0, 0, 0;
$overlayElementFgColor: 240, 240, 240;
// Change text colors against dark slide backgrounds
@include dark-bg-text-color(#fff);
// Theme template ------------------------------
@import "../_includes/scss/theme";
// ---------------------------------------------

View File

@ -1,9 +1,4 @@
$bg: rgb(254, 175, 214);
$text: rgb(92, 53, 124);
$accent: rgb(146, 0, 80);
$active-links: rgb(124, 6, 160);
$divider: rgb(219, 103, 167);
$semi-bg: rgba(221, 116, 174, 0.211);
@import "../_includes/scss/colors.scss";
html {
background-color: $bg;

58
src/decks.njk Normal file
View File

@ -0,0 +1,58 @@
---
pagination:
data: collections.decks
size: 1
permalink: /decks/{{ pagination.items[0].fileSlug }}/index.html
---
{% for deck in pagination.items %}
<!DOCTYPE html>
<html lang="{{ site.language }}">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ deck.data.title if deck.data.title else site.title }}</title>
{% bounce { path: '/css/style.css', check_path: 'src/css' } %}
<meta name="theme-color" content="#eca9cb">
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
<link rel="shortcut icon" href="/favicon.ico">
{% if env.environment.isProd %}
<script async src="https://umami.crimew.gay/script.js" data-website-id="fa7a72e7-acbc-488d-beb2-213886be0262"></script>
{% endif %}
{% bounce { path: '/reveal.js/reveal.css', check_path: 'node_modules/reveal.js/dist/reveal.css' } %}
{% bounce { path: '/css/reveal-maia.css', check_path: 'src/css' } %}
<!-- TODO: custom code theme -->
{% bounce { path: '/reveal.js/plugin/highlight/monokai.css', check_path: 'node_modules/reveal.js/plugin/highlight/monokai.css' } %}
<script type="module">
import Reveal from '/reveal.js/reveal.esm.js';
import Markdown from '/reveal.js/plugin/markdown/markdown.esm.js';
import RevealHighlight from '/reveal.js/plugin/highlight/highlight.esm.js';
import RevealNotes from '/reveal.js/plugin/notes/notes.esm.js';
let deck = new Reveal({
plugins: [ Markdown, RevealHighlight, RevealNotes ],
hash: true,
controlsTutorial: false
})
deck.initialize();
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown>
<textarea data-template>
{{ deck.data.rawMarkdown }}
</textarea>
</section>
<div>
<div>
</body>
</html>
{% endfor %}

4
src/decks/decks.json Normal file
View File

@ -0,0 +1,4 @@
{
"layout": "layouts/deck",
"permalink": "decks/{{ page.fileSlug }}/blank.html"
}

View File

@ -0,0 +1,316 @@
---
title: "#FuckStalkerware at ETH"
---
<!-- .slide: data-auto-animate -->
<img src="/img/kitten_cropped.png" class="r-stretch"/>
# hacking a morally bankrupt industry
## a talk about stalkerware, hacktivism and ethics
## [maia arson crimew](https://maia.crimew.gay)
**content warning:** discussion of abuse/controlling behavior
---
<!-- .slide: data-auto-animate -->
<img src="/img/kitten_cropped.png" class="r-stretch"/>
## maia arson crimew
* is 24 years old <!-- .element: class="fragment" -->
* uses it(/she) pronouns <!-- .element: class="fragment" -->
* has been a hacktivist since 2019 <!-- .element: class="fragment" -->
* got indicted in 2021 ^-^ oopie <!-- .element: class="fragment" -->
* leaked the 2019 version of the US no fly list in 2023 <!-- .element: class="fragment" -->
* is a silly "journalist/blogger" <!-- .element: class="fragment" -->
* is literally a kitten <!-- .element: class="fragment" -->
---
<!-- .slide: data-auto-animate data-auto-animate-restart -->
## what did it do for the rest of this year
---
<!-- .slide: data-auto-animate -->
## what did it do for the rest of this year
* published thousands of emails revealing the secret US based working group behind much of current international anti-trans legislation
* reported on various hacks by other actors <!-- .element: class="fragment" -->
* a cybersecurity company pwned by a random 4chan user <!-- .element: class="fragment" -->
* kittensec leaking romanian and EU government data <!-- .element: class="fragment" -->
* a write up on various security issues in the streaming platform kick.com <!-- .element: class="fragment" -->
* an exclusive report on how rosgosstrakh got hacked <!-- .element: class="fragment" -->
---
<!-- .slide: data-auto-animate -->
## what did it do for the rest of this year
* investigative internet pop culture journalism
* an ifunny clone that isn't actually what it seems at all <!-- .element: class="fragment" -->
* how a popular tiktok meme account has a dark past and connections to the far right <!-- .element: class="fragment" -->
* guested on various political and pop culture podcasts <!-- .element: class="fragment" -->
* various other media work <!-- .element: class="fragment" -->
* <!-- .element: class="fragment" --> started the <b>#FuckStalkerware</b> project to help combat stalkerware and get an insight into the industry
Note:
pocasts such as well there's your problem, the worst of all possible worlds, red planet and many more
media work both giving interviews and portraits about myself and acting as an expert on various topics
---
## let's cover some basics
* what's hacktivism<!-- .element: class="fragment" -->
* what is my motivation<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-0/cover.jpg" data-background-opacity="0.2" data-auto-animate data-auto-animate-restart -->
## what is stalkerware
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-0/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## what is stalkerware
* commercially available spyware
* often advertised for:<!-- .element: class="fragment" -->
* "parental control" <!-- .element: class="fragment" -->
* figuring out if your partner is cheating on you<!-- .element: class="fragment" -->
* hidden from the target, often pretends to be system application<!-- .element: class="fragment" -->
* usually requires brief physical access, can be remotely installed<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-0/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## what is stalkerware
* reports activity on the victim device, such as:
* text messages sent and received<!-- .element: class="fragment" -->
* phone calls made (sometimes with recording)<!-- .element: class="fragment" -->
* websites visited<!-- .element: class="fragment" -->
* any photos taken<!-- .element: class="fragment" -->
* geolocation<!-- .element: class="fragment" -->
* ambient audio recordings<!-- .element: class="fragment" -->
* sometimes allows remote sending of text messages<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-1/cover.jpg" data-background-opacity="0.2" -->
## why is this bad?
Note:
spying on partners is bad, spying on kids is bad, trying to solve social issues with technology, stolen text messages allow theft of 2fa codes and taking over other accounts, privacy is a fucking human right for everyone no matter who they are, what they do or how old they are
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-1/cover.jpg" data-background-opacity="0.2" -->
## why we hack stalkerware providers
* legislation and courts are slow<!-- .element: class="fragment" -->
* we can collectively defend ourselves from abusive technology<!-- .element: class="fragment" -->
* most stalkerware providers have horrible security<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
<video data-autoplay src="/img/posts/fuckstalkerware-2/tizer.mp4"></video>
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
* an iranian stalkerware<!-- .element: class="fragment" -->
* users/victims all over the world<!-- .element: class="fragment" -->
* 750k users<!-- .element: class="fragment" -->
* extremely trivial to hack<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
* exposed .git directory allows stealing dashboard source code using [goop](https://github.com/nyancrimew/goop)
<img src="/img/posts/fuckstalkerware-2/goop.jpg"/>
* turns out to be a trashy php monorepo for both frontend + backend<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### trying to find something to exploit
* auth cookies are in the format of<!-- .element: class="fragment" --> `userid.passwordmd5.lang.timezone.db_type`
* user ids are sequential<!-- .element: class="fragment" -->
* yes, the password as represented in the db with the db salt and all is in the cookie<!-- .element: class="fragment" -->
* db type is either a or b, where b appears to stand for "backup", both my accounts are on type b<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### trying to find something to exploit
for auth via level2 phone app an "app key" is required, which is described by code comments as follows:
```php
// $app_key is generated in level2 app hash(md5_pass.username.private_key)
// $u_id will send from level2 app to identify target user
// $tz is level2 app phone timezone
// $lang is level2 app phone default language
```
the mentioned private key (which is actually a static salt) is<!-- .element: class="fragment" --> `asrome_intermilan_realmadrid`.
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### trying to find something to exploit
* `uploadPhoto`, `uploadRecordAmbient` and `uploadRecordCall` allow arbitrary file uploads
```php [9]
$allowed = array('3gp');
$objFile = & $file_array["recordcall"];
$filename = $objFile['name'];
$record_id = explode(".",$filename);
$record_id = explode("_",$record_id[0]);
$record_id = $record_id[2];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if(!in_array($ext,$allowed) ) {
// error_log("HACKER:".basename( $objFile["name"] ));
}
```
<!-- .element: class="fragment" -->
* <!-- .element: class="fragment" --> <code>uploadRecordAmbient</code> and <code>uploadRecordCall</code> actually note that this is a vulnerability and a check for only allowing .mp3 or .3gp files respectively exists but result is ignored
* this should work to give us code execution<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### trying to find something to exploit
* one problem left: we need a device id
* reversing a bit more of the code to figure out how to register a device to my test account<!-- .element: class="fragment" -->
* we now have a device with the very numeric id 'maia'<!-- .element: class="fragment" -->
* time to upload a "photo" (base64 encoded webshell)<!-- .element: class="fragment" -->
* as a little extra flex i use directory traveral to place it at /funky.php<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate data-autoslide="64554" -->
## example: SpyHide
### it's exploitin' time
<img src="/img/posts/fuckstalkerware-2/funkytimes.jpg"/>
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### it's exploitin' time
* compress and download all webroots hosted on this server using the webshell
* grabbing all databases using an existing adminer install<!-- .element: class="fragment" -->
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### it's exploitin' time
<img src="/img/decks/fuckstalkerware/adminer.jpg"/>
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### analysis
* over 230gb of exfiltrated data<!-- .element: class="fragment" -->
* source code, databases<!-- .element: class="fragment" -->
* photos, calls and ambient audio recordings from phones<!-- .element: class="fragment" -->
* some account owners have spied on as much as 30 different devices over the course of multiple years, stalking some people accross multiple phone changes<!-- .element: class="fragment" -->
* dataset actually makes it somewhat possible to identify victims, containing some imeis and phone numbers<!-- .element: class="fragment" -->
Note:
no journalists, victim support groups or researchers appear to have made use of that fact so far as far as im aware
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### analysis
* a look through email addresses used for registration reveals around 190 users with various government email addresses
* at least 16 us government addresses, incl .mil and various correctional officers<!-- .element: class="fragment" -->
* 5 users from colombian national police<!-- .element: class="fragment" -->
* massive amounts of users from brazilian and philippine departments of education<!-- .element: class="fragment" -->
* spyhide data retention claims are a lie<!-- .element: class="fragment" -->
* photos and recordings from as far back as 2020 found despite claims they are deleted after 3 months<!-- .element: class="fragment" -->
Note:
there is no email verification, so data may be skewed
police and correctional officer use implies possible evaluation of commercial spyware for law enforcement use, a pattern observed in other datasets as well
based on code analysis data is only deleted when operator stops paying.
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### analysis
<img src="/img/decks/fuckstalkerware/spyhide-gps-world.jpg" class="r-stretch"/>
*image credit:* [TechCrunch](https://techcrunch.com/2023/07/24/spyhide-stalkerware-android/)
Note:
a map of all recorded gps location data points in the dataset, showing spyhide being used all over the world with hotspots in europa, brazil, indonesia and the US
---
<!-- .slide: data-background-image="/img/posts/fuckstalkerware-2/cover.jpg" data-background-opacity="0.2" data-auto-animate -->
## example: SpyHide
### the result
* SpyHide briefly rebrands as Oospy<!-- .element: class="fragment" -->
* a few days after techcrunch and i published our stories hetzner takes down the spyhide backend server<!-- .element: class="fragment" -->
* paypal is contacted about the paypal account used for spyhide/oospy billing<!-- .element: class="fragment" -->
* paypal payment option disappears, we do not know if paypal took action<!-- .element: class="fragment" -->
* main known developer is confronted about the paypal account<!-- .element: class="fragment" -->
* oospy goes completely offline<!-- .element: class="fragment" -->
* as far as we can tell they have not come back online<!-- .element: class="fragment" -->
* this is not a one time thing (see LetMeSpy)<!-- .element: class="fragment" -->
---
<!-- .slide: data-auto-animate data-auto-animate-restart -->
## conclusions
---
<!-- .slide: data-auto-animate -->
## conclusions
* hacking stalkerware works, and gives effective results
* indispensable data for understanding the industry, reporting on it and fighting against it<!-- .element: class="fragment" -->
* it should not be easy and profitable to run a stalkerware business<!-- .element: class="fragment" -->
* more and more just give up instead of rebranding and keeping at it<!-- .element: class="fragment" -->
---
<!-- .slide: data-auto-animate -->
## conclusions
### morality
legality ≠ morality
Note:
victims need to be freed from, informed about and protected against stalkerware now, not in 10 years when it might be illegal in some places, giving victims and support orgs leverage and evicence to stand against not just their abusers but also the companies enabling and preying on them, we can break the market now
---
<img src="/img/kitten_cropped.png" class="r-stretch"/>
# Q & A with maia
i am unable to answer questions regarding legal proceedings concerning me, don't ask. i will also not answer any other question putting me or others at any unreasonable legal risks.

View File

@ -4,7 +4,7 @@ subhead: blog
pagination:
data: collections.posts
addAllPagesToCollections: true
size: 10
size: 20
permalink: /posts/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber }}/{% endif %}index.html
---
{% extends 'layouts/default.njk' %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB