# LACTF 2025
## rev/McFlagChecker
> Trong giải mình ko làm ra mấy bài này, giờ làm lại thôi lets go
Đề bài như sau:
> I found this really fun datapack! If you give it the flag (somehow??), you get a special prize! Unfortunately, the datapack is very inconveniently long.... ;)
NOTE: this datapack is compiled for Minecraft version 1.20.4. It will likely not work on other versions. Also, when loading the datapack on a Minecraft 1.20.4 client, it may tell you the datapack is outdated; ignore this message. The datapack will work.
NOTE: You DO NOT need to purchase Minecraft to solve this challenge. You can download a free Minecraft server .jar [here](https://mcversions.net/) to test commands and data packs, without purchasing an account. There are also many open-source Minecraft bot clients that can log into an offline server without needing authentication.
[chall.zip](https://chall-files.lac.tf/uploads/4ba068b9bba202dd9d66d67f06de1b397b5c209e06ff815fba3ddd7c0eecc671/chall.zip)
Phần quan trọng nhất nằm ở thư mục chall (như cái tên):
```
❯ tree
.
└── functions
├── check_flag.mcfunction
├── f1.mcfunction
├── f2.mcfunction
├── f3.mcfunction
├── f4.mcfunction
├── f5.mcfunction
├── f6.mcfunction
├── line007
│ └── while1.mcfunction
├── line019
│ └── execute2.mcfunction
├── line028
│ ├── else4.mcfunction
│ ├── else5.mcfunction
│ └── execute3.mcfunction
├── line049
│ └── for006.mcfunction
├── line1771
│ └── execute7.mcfunction
└── reset.mcfunction
7 directories, 15 files
```
Mở check_flag ra thử xem có gì, thì đọc đến đoạn cuối là tới khúc check flag:
``` c
scoreboard players set Global var4 1
execute unless score Global Reg0 matches 137 run scoreboard players set Global var4 0
execute unless score Global Reg1 matches 193 run scoreboard players set Global var4 0
execute unless score Global Reg2 matches 59 run scoreboard players set Global var4 0
execute unless score Global Reg3 matches 168 run scoreboard players set Global var4 0
execute unless score Global Reg4 matches 164 run scoreboard players set Global var4 0
execute unless score Global Reg5 matches 129 run scoreboard players set Global var4 0
execute unless score Global Reg6 matches 35 run scoreboard players set Global var4 0
execute unless score Global Reg7 matches 165 run scoreboard players set Global var4 0
execute unless score Global Reg8 matches 159 run scoreboard players set Global var4 0
execute unless score Global Reg9 matches 193 run scoreboard players set Global var4 0
execute unless score Global Reg10 matches 12 run scoreboard players set Global var4 0
execute unless score Global Reg11 matches 170 run scoreboard players set Global var4 0
execute unless score Global Reg12 matches 90 run scoreboard players set Global var4 0
execute unless score Global Reg13 matches 182 run scoreboard players set Global var4 0
execute unless score Global Reg14 matches 156 run scoreboard players set Global var4 0
execute unless score Global Reg15 matches 214 run scoreboard players set Global var4 0
execute unless score Global Reg16 matches 172 run scoreboard players set Global var4 0
execute unless score Global Reg17 matches 62 run scoreboard players set Global var4 0
execute unless score Global Reg18 matches 59 run scoreboard players set Global var4 0
execute unless score Global Reg19 matches 106 run scoreboard players set Global var4 0
execute unless score Global Reg20 matches 175 run scoreboard players set Global var4 0
execute unless score Global Reg21 matches 186 run scoreboard players set Global var4 0
execute unless score Global Reg22 matches 174 run scoreboard players set Global var4 0
execute unless score Global Reg23 matches 231 run scoreboard players set Global var4 0
execute unless score Global Reg24 matches 160 run scoreboard players set Global var4 0
execute unless score Global Reg25 matches 56 run scoreboard players set Global var4 0
execute unless score Global Reg26 matches 67 run scoreboard players set Global var4 0
execute unless score Global Reg27 matches 221 run scoreboard players set Global var4 0
execute unless score Global Reg28 matches 44 run scoreboard players set Global var4 0
execute unless score Global Reg29 matches 68 run scoreboard players set Global var4 0
execute unless score Global Reg30 matches 90 run scoreboard players set Global var4 0
execute unless score Global Reg31 matches 244 run scoreboard players set Global var4 0
execute unless score Global Reg32 matches 192 run scoreboard players set Global var4 0
execute unless score Global Reg33 matches 123 run scoreboard players set Global var4 0
execute unless score Global Reg34 matches 140 run scoreboard players set Global var4 0
execute unless score Global Reg35 matches 245 run scoreboard players set Global var4 0
execute unless score Global Reg36 matches 218 run scoreboard players set Global var4 0
execute unless score Global Reg37 matches 169 run scoreboard players set Global var4 0
execute unless score Global Reg38 matches 58 run scoreboard players set Global var4 0
execute unless score Global Reg39 matches 8 run scoreboard players set Global var4 0
execute if score Global var4 matches 1 run function chall:line1771/execute7
```
Nếu pass được tất cả các đoạn check, thì nó chạy hàm chall:line1771/execute7:
``` c
give @s minecraft:diamond 4
say "You get 4 diamond"
```
Như ở đề bài `If you give it the flag (somehow??), you get a special prize!` vậy nên khi flag đúng thì nó quăng cho chúng ta 4 cục kim cương.
Flow hàm check_flag:
``` c
scoreboard players set Global var1 106
scoreboard players operation Global Param0 = Global var1
function chall:f4
scoreboard players operation Global var1 = Global ReturnValue
scoreboard players operation Global var2 = Global Reg0
scoreboard players operation Global Param0 = Global var2
scoreboard players operation Global Param1 = Global var1
function chall:f1
scoreboard players operation Global var3 = Global ReturnValue
scoreboard players operation Global Reg0 = Global var3
scoreboard players operation Global Param0 = Global var1
...
function chall:f4
scoreboard players operation Global var1 = Global ReturnValue
scoreboard players operation Global var2 = Global Reg39
scoreboard players operation Global Param0 = Global var2
scoreboard players operation Global Param1 = Global var1
function chall:f1
scoreboard players operation Global var3 = Global ReturnValue
scoreboard players operation Global Reg39 = Global var3
scoreboard players operation Global var2 = Global Reg0
scoreboard players set Global Param0 6
scoreboard players operation Global Param1 = Global var2
scoreboard players set Global Param2 251
...
function chall:f5
scoreboard players operation Global var3 = Global ReturnValue
scoreboard players operation Global Reg0 = Global var3
scoreboard players operation Global var2 = Global Reg1
scoreboard players set Global Param0 6
scoreboard players operation Global Param1 = Global var2
scoreboard players set Global Param2 251
...
function chall:f5
scoreboard players operation Global var3 = Global ReturnValue
scoreboard players operation Global Reg39 = Global var3
function chall:f6
...
Check từ Reg0 -> Reg39
```
Hàm chall:f4:
``` c
scoreboard players operation Global s = Global Param0
scoreboard players operation Global s *= c97 Constant
scoreboard players add Global s 129
scoreboard players operation Global s %= c256 Constant
scoreboard players operation Global ReturnValue = Global s
-> ReturnValue = ((Param0 * 97) + 129) % 256
```
Chall:f1:
``` c
scoreboard players operation Global y = Global Param1
scoreboard players operation Global x = Global Param0
scoreboard players set Global foobar 0
scoreboard players set Global bar 1
scoreboard players operation Global Param0 = Global x
scoreboard players operation Global Param1 = Global y
function chall:f3
scoreboard players operation Global barfoo = Global ReturnValue
execute if score Global barfoo matches 1.. run function chall:line007/while1
scoreboard players operation Global ReturnValue = Global foobar
```
f3:
``` c
scoreboard players operation Global y = Global Param1
scoreboard players operation Global x = Global Param0
scoreboard players set Global f3_scratch0 1
execute if score Global x > Global y run function chall:line019/execute2
execute if score Global f3_scratch0 matches 1.. run scoreboard players operation Global ReturnValue = Global y
```
line019/execute2:
``` c
scoreboard players operation Global ReturnValue = Global x
scoreboard players set Global f3_scratch0 0
```
Vậy f3 nó sẽ trả về thằng lớn nhất.
while1:
``` c
scoreboard players operation Global f1_scratch0 = Global x
scoreboard players operation Global f1_scratch0 %= c2 Constant
scoreboard players operation Global Param0 = Global f1_scratch0
scoreboard players operation Global f1_scratch1 = Global y
scoreboard players operation Global f1_scratch1 %= c2 Constant
scoreboard players operation Global Param1 = Global f1_scratch1
function chall:f2
scoreboard players operation Global m = Global bar
scoreboard players operation Global m *= Global ReturnValue
scoreboard players operation Global foobar += Global m
scoreboard players operation Global bar *= c2 Constant
scoreboard players operation Global barfoo /= c2 Constant
scoreboard players operation Global x /= c2 Constant
scoreboard players operation Global y /= c2 Constant
execute if score Global barfoo matches 1.. run function chall:line007/while1
```
f2:
``` c
scoreboard players operation Global yin = Global Param1
scoreboard players operation Global xin = Global Param0
scoreboard players set Global foo 0
scoreboard players set Global f2_scratch0 1
execute if score Global xin matches 1 if score Global yin matches 1 run function chall:line028/execute3
execute if score Global f2_scratch0 matches 1.. if score Global xin matches 1 if score Global yin matches 0 run function chall:line028/else4
execute if score Global f2_scratch0 matches 1.. if score Global xin matches 0 if score Global yin matches 1 run function chall:line028/else5
execute if score Global f2_scratch0 matches 1.. run scoreboard players set Global foo 0
scoreboard players operation Global ReturnValue = Global foo
```
execute3:
``` c
scoreboard players set Global foo 0
scoreboard players set Global f2_scratch0 0
```
else4:
``` c
scoreboard players set Global foo 1
scoreboard players set Global f2_scratch0 0
```
else5:
``` c
scoreboard players set Global foo 1
scoreboard players set Global f2_scratch0 0
```
Quan sát thì nếu xin ^ yin = 1 thì returnValue = foo = 1
Implement lại f1 và while thì trông đại khái như này:
``` python
#!/usr/bin/python3
def f1(Param0, Param1):
x, y = Param0, Param1
foobar = 0
bar = 1
# barfoo = f3(Param0, Param1)
barfoo = max(x, y)
if barfoo >= 1:
while1()
return foobar
def while1():
while barfoo >= 1:
f1_scratch0 = x % 2
f1_scratch1 = y % 2
returnValue = f2(f1_scratch0, f1_scratch1)
# returnValue = f1_scratch0 ^ f1_scratch1
m = bar
m *= returnValue
foobar += m
bar *= 2
barfoo >>= 1
x >>= 1
y >>= 1
# barfoo /= 2
# x /= 2
# y /= 2
```
Tới đây thì rõ rồi, f1 đơn giản là xor của Param0 và Param1 thôi.
Còn hàm f4 thì xử lí cũng đơn giản:
``` c
scoreboard players set Global var1 106
scoreboard players operation Global Param0 = Global var1
function chall:f4
scoreboard players operation Global Param0 = Global var1
function chall:f4
scoreboard players operation Global Param0 = Global var1
function chall:f4
```
Và hàm f4 chỉ nhận Param0 nên gtri này là cố định.
Sau khi xử lí xong f4, f1 thì ta còn f5 và f6.
f5:
``` c
scoreboard players operation Global var3 = Global ReturnValue
scoreboard players operation Global Reg39 = Global var3
scoreboard players operation Global var2 = Global Reg0
scoreboard players set Global Param0 6
scoreboard players operation Global Param1 = Global var2
scoreboard players set Global Param2 251
function chall:f5
scoreboard players operation Global var3 = Global ReturnValue
scoreboard players operation Global Reg0 = Global var3
...
Tương tự đến Reg39
```
chall:f5:
``` c
scoreboard players operation Global c = Global Param2
scoreboard players operation Global b = Global Param1
scoreboard players operation Global a = Global Param0
scoreboard players set Global d 1
scoreboard players set Global i 1
execute if score Global i <= Global b run function chall:line049/for006
scoreboard players operation Global ReturnValue = Global d
```
line049/for006:
``` c
scoreboard players operation Global d *= Global a
scoreboard players operation Global d %= Global c
scoreboard players add Global i 1
execute if score Global i <= Global b run function chall:line049/for006
```
implement lại f5:
``` python
def f5(Param0, Param1, Param2):
a, b, c = Param0, Param1, Param2
d = 1
i = 1
while i <= b:
d = (d * a) % c
i += 1
return d
```
Vậy $f5 = a ^ b MOD c$.
Với a = 6, b = Reg(i), c = 251.
Rồi giờ còn f6 thui, flow đại khái như này:
``` c
scoreboard players set Global s 0
execute store result score Global m run data get block 0 0 0 RecordItem.tag.Storage
scoreboard players operation Global f = Global Reg0
scoreboard players operation Global f6_scratch0 = Global m
scoreboard players operation Global f6_scratch0 *= Global f
scoreboard players operation Global s += Global f6_scratch0
scoreboard players operation Global s %= c251 Constant
...
execute store result score Global m run data get block 0 0 39 RecordItem.tag.Storage
scoreboard players operation Global f = Global Reg39
scoreboard players operation Global f6_scratch0 = Global m
scoreboard players operation Global f6_scratch0 *= Global f
scoreboard players operation Global s += Global f6_scratch0
scoreboard players operation Global s %= c251 Constant
scoreboard players operation Global TempReg0 = Global s
scoreboard players set Global s 0
execute store result score Global m run data get block 1 0 0 RecordItem.tag.Storage
scoreboard players operation Global f = Global Reg0
scoreboard players operation Global f6_scratch0 = Global m
scoreboard players operation Global f6_scratch0 *= Global f
scoreboard players operation Global s += Global f6_scratch0
scoreboard players operation Global s %= c251 Constant
...
execute store result score Global m run data get block 1 0 39 RecordItem.tag.Storage
scoreboard players operation Global f = Global Reg39
scoreboard players operation Global f6_scratch0 = Global m
scoreboard players operation Global f6_scratch0 *= Global f
scoreboard players operation Global s += Global f6_scratch0
scoreboard players operation Global s %= c251 Constant
scoreboard players operation Global TempReg1 = Global s
...
execute store result score Global m run data get block 39 0 39 RecordItem.tag.Storage
scoreboard players operation Global f = Global Reg39
scoreboard players operation Global f6_scratch0 = Global m
scoreboard players operation Global f6_scratch0 *= Global f
scoreboard players operation Global s += Global f6_scratch0
scoreboard players operation Global s %= c251 Constant
scoreboard players operation Global TempReg39 = Global s
scoreboard players operation Global TempReg39 = Global s
scoreboard players operation Global Reg0 = Global TempReg0
scoreboard players operation Global Reg1 = Global TempReg1
scoreboard players operation Global Reg2 = Global TempReg2
scoreboard players operation Global Reg3 = Global TempReg3
scoreboard players operation Global Reg4 = Global TempReg4
scoreboard players operation Global Reg5 = Global TempReg5
scoreboard players operation Global Reg6 = Global TempReg6
scoreboard players operation Global Reg7 = Global TempReg7
scoreboard players operation Global Reg8 = Global TempReg8
scoreboard players operation Global Reg9 = Global TempReg9
scoreboard players operation Global Reg10 = Global TempReg10
scoreboard players operation Global Reg11 = Global TempReg11
scoreboard players operation Global Reg12 = Global TempReg12
scoreboard players operation Global Reg13 = Global TempReg13
scoreboard players operation Global Reg14 = Global TempReg14
scoreboard players operation Global Reg15 = Global TempReg15
scoreboard players operation Global Reg16 = Global TempReg16
scoreboard players operation Global Reg17 = Global TempReg17
scoreboard players operation Global Reg18 = Global TempReg18
scoreboard players operation Global Reg19 = Global TempReg19
scoreboard players operation Global Reg20 = Global TempReg20
scoreboard players operation Global Reg21 = Global TempReg21
scoreboard players operation Global Reg22 = Global TempReg22
scoreboard players operation Global Reg23 = Global TempReg23
scoreboard players operation Global Reg24 = Global TempReg24
scoreboard players operation Global Reg25 = Global TempReg25
scoreboard players operation Global Reg26 = Global TempReg26
scoreboard players operation Global Reg27 = Global TempReg27
scoreboard players operation Global Reg28 = Global TempReg28
scoreboard players operation Global Reg29 = Global TempReg29
scoreboard players operation Global Reg30 = Global TempReg30
scoreboard players operation Global Reg31 = Global TempReg31
scoreboard players operation Global Reg32 = Global TempReg32
scoreboard players operation Global Reg33 = Global TempReg33
scoreboard players operation Global Reg34 = Global TempReg34
scoreboard players operation Global Reg35 = Global TempReg35
scoreboard players operation Global Reg36 = Global TempReg36
scoreboard players operation Global Reg37 = Global TempReg37
scoreboard players operation Global Reg38 = Global TempReg38
scoreboard players operation Global Reg39 = Global TempReg39
```
Uk tới khúc này thì nhìn giống ptrinh tuyến tính hay nhân ma trận gì ý. Mỗi TempReg đều đc biểu diễn bởi công thức sau:
tempReg[i] =$(\sum_{j=0}^{k=39}m[i][j]*Reg[j] )MOD 251$
M là số lấy từ đoạn lệnh:
``` c
execute store result score Global m run data get block 0 0 0 RecordItem.tag.Storage
```
Những số này thì nằm ở file reset:
``` c
data merge block 39 0 24 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 182}}}
data merge block 39 0 25 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 167}}}
data merge block 39 0 26 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 248}}}
data merge block 39 0 27 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 71}}}
data merge block 39 0 28 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 180}}}
data merge block 39 0 29 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 62}}}
data merge block 39 0 30 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 190}}}
data merge block 39 0 31 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 140}}}
data merge block 39 0 32 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 246}}}
data merge block 39 0 33 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 252}}}
data merge block 39 0 34 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 209}}}
data merge block 39 0 35 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 129}}}
data merge block 39 0 36 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 146}}}
data merge block 39 0 37 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 30}}}
data merge block 39 0 38 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 96}}}
data merge block 39 0 39 {RecordItem:{id:"minecraft:stone",Count:1b,tag:{Storage: 159}}}
```
Viết script lấy ma trận từ đó là đc. Giờ bài toán quy về tìm ma trận B sao cho A * B = X. Có ma trận B rồi thì rev hàm f5, xong rồi rev f1, f4 là ra input.
Theo như mình học trên dreamhack thì bài toán ma trận này gọi tên là Linear Congruences.
Cách tìm ma trận B ez nhất là ném vô [sage](https://sagecell.sagemath.org/):
``` python
M = [[22, 31, 224, 191, 160, 143, 101, 173, 255, 239, 140, 63, 139, 17, 22, 206, 120, 114, 221, 115, 198, 66, 13, 181, 161, 156, 111, 40, 10, 5, 7, 188, 155, 120, 253, 103, 51, 94, 72, 63], [37, 6, 237, 26, 169, 62, 173, 163, 99, 89, 130, 44, 151, 121, 55, 191, 221, 253, 205, 232, 79, 186, 1, 137, 1, 104, 228, 231, 200, 177, 35, 37, 206, 30, 132, 46, 63, 115, 66, 147], [39, 251, 58, 168, 15, 4, 190, 16, 105, 190, 29, 36, 121, 190, 49, 66, 42, 107, 160, 193, 54, 156, 169, 65, 37, 198, 9, 80, 160, 159, 73, 54, 81, 157, 220, 162, 158, 126, 83, 130], [251, 87, 166, 230, 213, 64, 201, 92, 220, 87, 152, 221, 229, 99, 212, 154, 137, 152, 138, 138, 56, 79, 135, 94, 189, 97, 129, 199, 208, 16, 230, 35, 3, 74, 108, 92, 5, 236, 7, 141], [175, 62, 85, 95, 117, 160, 108, 93, 238, 113, 197, 191, 23, 92, 188, 125, 49, 100, 87, 48, 173, 247, 230, 240, 109, 34, 58, 148, 232, 154, 233, 34, 10, 105, 105, 181, 217, 136, 73, 89], [223, 180, 63, 11, 95, 171, 252, 145, 17, 171, 155, 213, 223, 206, 46, 178, 102, 70, 219, 45, 165, 48, 173, 215, 125, 235, 190, 12, 244, 41, 189, 19, 195, 63, 100, 13, 43, 238, 112, 25], [27, 44, 71, 106, 165, 208, 11, 101, 162, 15, 65, 254, 107, 153, 176, 45, 62, 87, 71, 84, 226, 167, 209, 94, 121, 168, 230, 104, 236, 212, 178, 192, 240, 115, 86, 65, 81, 163, 141, 58], [43, 234, 129, 248, 62, 194, 144, 145, 138, 86, 223, 115, 161, 166, 57, 161, 118, 168, 121, 85, 179, 68, 117, 207, 108, 34, 142, 3, 221, 170, 189, 29, 42, 68, 200, 205, 16, 221, 35, 223], [181, 54, 186, 172, 171, 141, 47, 134, 87, 22, 195, 180, 65, 64, 79, 24, 137, 250, 102, 208, 96, 144, 146, 140, 227, 128, 191, 87, 168, 167, 240, 85, 130, 104, 58, 25, 203, 252, 18, 85], [186, 150, 21, 105, 16, 170, 167, 222, 149, 139, 222, 205, 85, 220, 186, 207, 226, 102, 77, 187, 13, 253, 46, 244, 206, 66, 129, 205, 154, 66, 119, 8, 254, 2, 160, 74, 238, 197, 160, 125], [177, 2, 147, 99, 14, 200, 209, 58, 4, 86, 214, 28, 131, 136, 131, 195, 85, 93, 34, 40, 183, 96, 144, 101, 55, 15, 25, 26, 166, 10, 200, 53, 21, 71, 192, 206, 200, 21, 17, 66], [1, 246, 244, 136, 107, 231, 215, 7, 231, 53, 220, 10, 233, 127, 61, 8, 223, 84, 170, 129, 6, 208, 152, 236, 54, 155, 161, 85, 25, 15, 207, 107, 239, 208, 126, 56, 30, 83, 34, 23], [79, 204, 45, 215, 29, 240, 167, 63, 67, 230, 20, 132, 44, 4, 189, 135, 126, 63, 255, 162, 130, 244, 158, 222, 158, 12, 53, 48, 113, 205, 9, 233, 91, 91, 195, 38, 58, 246, 210, 187], [38, 164, 215, 80, 117, 92, 187, 131, 100, 217, 8, 160, 126, 189, 4, 46, 113, 51, 111, 205, 201, 50, 89, 37, 28, 92, 38, 40, 131, 111, 55, 113, 221, 51, 125, 214, 28, 97, 104, 7], [16, 208, 78, 189, 123, 145, 51, 128, 119, 28, 23, 220, 123, 218, 186, 244, 196, 112, 89, 172, 212, 221, 188, 10, 175, 16, 185, 21, 228, 7, 136, 246, 130, 124, 180, 168, 233, 198, 204, 150], [237, 10, 109, 189, 163, 105, 179, 123, 17, 58, 230, 14, 205, 76, 86, 10, 113, 25, 205, 56, 237, 134, 167, 118, 227, 153, 156, 173, 237, 13, 145, 104, 121, 59, 95, 57, 133, 29, 21, 246], [154, 207, 232, 255, 84, 106, 243, 65, 224, 69, 229, 17, 47, 30, 16, 31, 197, 139, 211, 3, 73, 79, 24, 201, 212, 172, 239, 183, 242, 231, 72, 113, 163, 187, 71, 250, 102, 161, 31, 152], [95, 24, 249, 71, 129, 15, 170, 89, 252, 207, 236, 32, 16, 32, 139, 207, 152, 81, 214, 167, 94, 85, 247, 138, 226, 50, 248, 124, 183, 70, 9, 3, 240, 190, 221, 59, 21, 94, 123, 17], [167, 183, 249, 72, 228, 96, 45, 58, 63, 188, 80, 72, 176, 52, 156, 148, 72, 185, 171, 121, 38, 238, 40, 190, 34, 31, 191, 9, 246, 46, 88, 155, 128, 36, 87, 73, 158, 172, 38, 244], [16, 218, 10, 36, 147, 253, 206, 2, 2, 253, 199, 123, 29, 208, 180, 76, 254, 186, 150, 119, 20, 1, 186, 45, 45, 44, 209, 175, 12, 169, 182, 109, 153, 58, 229, 15, 189, 13, 100, 49], [132, 219, 69, 29, 19, 49, 46, 140, 189, 10, 130, 35, 77, 167, 68, 106, 193, 5, 31, 16, 134, 181, 14, 118, 106, 70, 15, 44, 1, 28, 223, 121, 63, 121, 121, 113, 179, 133, 203, 74], [87, 53, 122, 225, 219, 30, 96, 110, 219, 187, 179, 19, 85, 97, 80, 195, 138, 183, 31, 249, 1, 57, 112, 72, 176, 51, 137, 223, 160, 45, 132, 233, 205, 242, 84, 41, 15, 37, 125, 180], [10, 60, 250, 242, 88, 252, 147, 71, 215, 131, 70, 104, 75, 134, 35, 107, 19, 116, 150, 133, 144, 201, 56, 249, 27, 254, 1, 87, 155, 135, 67, 25, 144, 180, 68, 226, 167, 137, 93, 49], [25, 5, 165, 16, 199, 92, 100, 52, 42, 63, 49, 118, 75, 67, 232, 216, 218, 177, 199, 205, 194, 187, 132, 226, 151, 126, 22, 23, 205, 157, 31, 180, 70, 38, 51, 54, 178, 38, 130, 220], [179, 243, 147, 70, 25, 124, 81, 255, 114, 153, 211, 94, 5, 248, 19, 186, 156, 225, 105, 169, 217, 47, 176, 47, 203, 190, 71, 71, 13, 133, 170, 139, 53, 113, 11, 248, 70, 0, 122, 79], [28, 248, 39, 0, 168, 193, 136, 51, 40, 29, 88, 51, 161, 152, 147, 113, 203, 204, 67, 118, 235, 192, 224, 90, 120, 251, 63, 58, 205, 163, 0, 26, 246, 108, 57, 43, 53, 79, 193, 107], [137, 169, 40, 18, 185, 159, 120, 192, 144, 206, 181, 44, 107, 115, 78, 132, 220, 199, 20, 141, 45, 252, 213, 189, 23, 229, 67, 31, 131, 214, 9, 45, 55, 148, 198, 184, 119, 16, 187, 215], [121, 93, 23, 246, 210, 234, 60, 143, 216, 121, 18, 70, 102, 180, 19, 7, 139, 199, 68, 144, 88, 22, 42, 56, 241, 233, 224, 122, 173, 197, 104, 107, 202, 34, 14, 193, 40, 123, 51, 173], [10, 240, 51, 83, 156, 41, 97, 207, 11, 255, 160, 124, 135, 108, 125, 213, 137, 159, 188, 203, 16, 208, 115, 53, 118, 142, 253, 171, 65, 170, 251, 154, 12, 191, 62, 204, 3, 246, 62, 21], [168, 182, 29, 169, 32, 132, 161, 175, 142, 190, 237, 43, 215, 81, 204, 151, 251, 37, 73, 242, 18, 71, 43, 140, 28, 41, 236, 229, 232, 132, 79, 175, 34, 132, 121, 22, 49, 223, 184, 220], [186, 230, 180, 255, 213, 179, 254, 40, 46, 123, 46, 250, 246, 226, 115, 198, 217, 248, 126, 79, 208, 192, 166, 71, 16, 124, 180, 214, 67, 202, 1, 252, 8, 86, 247, 234, 35, 8, 113, 235], [146, 205, 202, 240, 86, 84, 227, 74, 241, 208, 76, 251, 223, 85, 38, 56, 99, 163, 209, 215, 123, 158, 183, 230, 123, 245, 43, 216, 79, 237, 33, 90, 80, 19, 223, 13, 75, 134, 90, 101], [218, 15, 55, 79, 147, 13, 33, 170, 42, 187, 198, 99, 84, 191, 85, 68, 26, 98, 196, 126, 68, 169, 48, 225, 75, 91, 218, 27, 204, 15, 78, 93, 196, 17, 50, 193, 146, 145, 243, 14], [105, 107, 115, 139, 62, 65, 119, 43, 91, 142, 222, 133, 19, 113, 77, 253, 96, 40, 253, 125, 48, 138, 157, 128, 144, 225, 178, 12, 104, 231, 129, 59, 134, 102, 224, 216, 185, 110, 104, 77], [70, 200, 5, 118, 184, 188, 114, 228, 218, 13, 134, 199, 225, 74, 171, 209, 35, 8, 116, 86, 65, 160, 184, 173, 130, 13, 70, 126, 141, 153, 110, 78, 68, 51, 104, 37, 12, 187, 97, 206], [7, 213, 143, 135, 45, 82, 60, 97, 195, 38, 54, 23, 166, 50, 24, 170, 86, 40, 227, 239, 58, 242, 160, 32, 36, 182, 103, 51, 222, 115, 166, 94, 144, 70, 145, 126, 143, 30, 122, 51], [224, 100, 172, 240, 58, 75, 14, 225, 85, 77, 146, 92, 99, 105, 208, 244, 254, 16, 162, 155, 140, 149, 28, 115, 219, 84, 172, 159, 207, 152, 235, 76, 95, 90, 199, 208, 28, 160, 216, 170], [166, 6, 251, 49, 91, 42, 101, 204, 51, 14, 148, 9, 17, 90, 192, 250, 157, 27, 152, 49, 90, 31, 218, 10, 192, 11, 87, 7, 195, 112, 10, 216, 3, 252, 29, 194, 214, 169, 71, 37], [137, 132, 120, 218, 251, 123, 210, 249, 196, 63, 191, 33, 185, 148, 6, 101, 201, 10, 176, 139, 129, 111, 32, 152, 38, 230, 82, 81, 37, 230, 192, 161, 216, 106, 201, 167, 115, 5, 51, 164], [130, 8, 19, 5, 183, 252, 84, 85, 201, 129, 11, 135, 167, 10, 180, 184, 117, 75, 181, 152, 194, 16, 197, 169, 182, 167, 248, 71, 180, 62, 190, 140, 246, 252, 209, 129, 146, 30, 96, 159]]
n = 40
mod = 251
Zm = Zmod(mod)
res = [137, 193, 59, 168, 164, 129, 35, 165, 159, 193, 12, 170, 90, 182, 156, 214, 172, 62, 59, 106, 175, 186, 174, 231, 160, 56, 67, 221, 44, 68, 90, 244, 192, 123, 140, 245, 218, 169, 58, 8]
M = Matrix(Zm, M)
res = vector(Zm, res)
flag = M.solve_right(res)
flag = [ZZ(k) for k in flag]
print(flag)
```
Final script:
``` python
#!/usr/bin/python3
def f4(x):
return ((x * 97) + 129) % 256
x = 106
rev_f4 = []
for i in range(40):
x = f4(x)
rev_f4.append(x)
flag = [234, 157, 189, 28, 46, 2, 67, 39, 153, 230, 133, 83, 39, 165, 39, 190, 200, 67, 173, 231, 23, 128, 185, 162, 27, 186, 124, 152, 169, 159, 242, 145, 32, 223, 134, 19, 96, 144, 40, 239]
rev_f5 = []
for i in range(40):
for c in range(33, 127):
if pow(6, c ^ rev_f4[i], 251) == flag[i]:
print(chr(c), end = "")
# lactf{y4Y_th1s_fl4g_g1v3s_y0u_4_d14m0nd}
```
Vì nếu rev chỉ f5 thôi nó sẽ ra nhiều số khác nhau thỏa flag, nên còn cách là rev 1 lần f4 vs f5 luôn.
## rev/1000xREV
> This program is taking forever to check my flag! It's been running for over 24 hours, and it's still not done. Can you take a look?
In some cases, the program may not work locally. In that case, try running it on https://shell.cloud.google.com/.
Một bài flag checker, khi nhập đúng 37 kí tự thì nó chạy mất vài thập kỉ (chắc vậy)
``` linux
❯ ./1000xREV
Enter the flag: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Checking (this may take a while)..............................
```
Vì đọc code rất ảo nên mình sẽ debug để xem nó làm gì:



`res_query` được gọi ở đoạn có `len.rev.lac.tf`, `%d.rev.lac.tf`.
Còn `res_state` là ntn ?
Cái này bí quá hỏi chatGPT thử:

Có vẻ như nó chỉ định máy chủ DNS là `ns1rev.lac.tf`

Khi gọi DNS query với 0.rev.lac.tf thì ta được '9611289;0,0'
Rồi ở đây có 1 đoạn check:
``` c
v16 = strtok(0LL, ";");
v17 = v16;
if ( v22 )
{
v18 = v22;
v23 = v16;
v19 = strtol(v18, 0LL, 10);
v17 = v23;
v21 = v19;
if ( !v23 )
goto LABEL_23;
goto LABEL_22;
}
if ( v16 )
{
LABEL_22:
if ( (unsigned int)__isoc99_sscanf(v17, "%d,%d", &v25, &v26) == 2 )
{
v24 = v25;
if ( v24 < 8 * strlen(s) )
{
v20 = s[v24 >> 3];
if ( _bittest(&v20, ~(_BYTE)v24 & 7) )
{
if ( !v26 )
{
LABEL_31:
puts("\nIncorrect.");
return 0xFFFFFFFFLL;
}
}
else if ( v26 == 1 )
{
goto LABEL_31;
}
}
}
LABEL_23:
sleep(1u);
putchar(46);
if ( v21 == -1 )
{
puts("Correct!");
return 0LL;
}
}
else
{
sleep(1u);
putchar(46);
}
```
Tới đây mình thấy là nếu v16 ko rỗng, thì từ đó tách ra 2 số từ dấu ',' rồi dùng để check input.
Để ý đoạn đầu thì là chỉ định máy chủ DNS `ns1rev.lac.tf`, xong rồi thực hiện truy vấn vs `%d.rev.lac.tf` rồi lấy data để check flag. Đây cũng là lí do đoạn check flag chạy chậm vcl. Mình hỏi con chatGPT thử làm sao để thực hiện các truy vấn từ máy chủ DNS đó với các tên miền `%d.rev.lac.tf`


Ra được cái file hơn 100mb vãi đạn...
Final script:
``` python
#!/usr/bin/python3
from pwn import *
meow = [0] * 37
txt = open("dns.txt", "r").read().split('\n')
bruh = []
mp = {}
for x in txt:
if '.rev.lac.tf.' in x and 'TXT' in x:
try:
y = int(x[:x.find('.rev.lac.tf')])
mp[y] = x
except:
continue
cur = 0
cnt = 0
while True:
if cur == -1 or cur not in mp:
break
x = mp[cur]
y = x[x.find('"') + 1:-1]
cur = int(y[:y.find(';')])
if y.find(';') == len(y) - 1:
continue
x1 = int(y[y.find(';') + 1:y.find(',')])
x2 = int(y[y.find(',') + 1:])
if x2 == 1:
meow[x1 >> 3] |= 1 << (~x1 & 7)
print(bytes(meow))
# lactf{b1t_by_b1t_0r_jus7_411_4t_0nc3}
```