# 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ì: ![image](https://hackmd.io/_uploads/rkj-VsaF1x.png) ![image](https://hackmd.io/_uploads/rJqNrjTtJx.png) ![image](https://hackmd.io/_uploads/ryAwSsaFyx.png) `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ử: ![image](https://hackmd.io/_uploads/BybI_TpKyl.png) Có vẻ như nó chỉ định máy chủ DNS là `ns1rev.lac.tf` ![image](https://hackmd.io/_uploads/HyXF8a6Yye.png) 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` ![image](https://hackmd.io/_uploads/SkbfKpat1g.png) ![image](https://hackmd.io/_uploads/rJkFK6aF1x.png) 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} ```