# PicoCTF - Powershelly ## Background [Powershell 命令提示字元比較](https://zh.wikipedia.org/zh-tw/PowerShell#%E5%91%BD%E4%BB%A4%E6%8F%90%E7%A4%BA%E5%AD%97%E5%85%83%E6%AF%94%E8%BE%83) [What is '@{}' meaning in PowerShell](https://stackoverflow.com/questions/56965510/what-is-meaning-in-powershell) [What does @() mean in Powershell?](https://stackoverflow.com/questions/28732025/what-does-mean-in-powershell) [[Python] 學習使用集合 (Set)](https://wenyuangg.github.io/posts/python3/python-set.html) ## Source code :::spoiler Source Code ```bash= $input = ".\input.txt" $out = Get-Content -Path $input $enc = [System.IO.File]::ReadAllBytes("$input") $encoding = [system.Text.Encoding]::UTF8 $total = 264 $t = ($total + 1) * 5 #1325 $numLength = ($total * 30 ) + $t # 9245 if ($out.Length -gt 5 -or $enc.count -ne $numLength) { Write-Output "Wrong format 5" Exit } else { for($i=0; $i -lt $enc.count ; $i++) { if (($enc[$i] -ne 49) -and ($enc[$i] -ne 48) -and ($enc[$i] -ne 10) -and ($enc[$i] -ne 13) -and ($enc[$i] -ne 32)) { Write-Output "Wrong format 1/0/" Exit } } } $blocks = @{} for ($i=0; $i -lt $out.Length ; $i++) { $r = $out[$i].Split(" ") if ($i -gt 0) { for ($j=0; $j -lt $r.Length ; $j++) { if ($r[$j].Length -ne 6) { Write-Output "Wrong Format 6" $r[$j].Length Exit } $blocks[$j] += $r[$j] } } else { for ($j=0; $j -lt $r.Length ; $j++) { if ($r[$j].Length -ne 6) { Write-Output "Wrong Format 6" $r[$j].Length Exit } $blocks[$j] = @() $blocks[$j] += $r[$j] } } } function Exit { exit } function Random-Gen { $list1 = @() for ($i=1; $i -lt ($blocks.count + 1); $i++) { $y = ((($i * 327) % 681 ) + 344) % 313 $list1 += $y } return $list1 } function Scramble { param ( $block, $seed ) $raw = [system.String]::Join("", $block) $bm = "10 " * $raw.Length $bm = $bm.Split(" ") for ($i=0; $i -lt $raw.Length ; $i++) { $y = ($i * $seed) % $raw.Length $n = $bm[$y] while ($n -ne "10") { $y = ($y + 1) % $raw.Length $n = $bm[$y] } if ($raw[$i] -eq "1" ) { $n = "11" } else { $n = "00" } $bm[$y] = $n } $raw2 = [system.String]::Join("", $bm) $b = [convert]::ToInt64($raw2,2) return $b } $result = 0 $seeds = @() for ($i=1; $i -lt ($blocks.count +1); $i++) { $seeds += ($i * 127) % 500 } $randoms = Random-Gen $output_file = @() for ($i=0; $i -lt $blocks.count ; $i++) { $fun = Scramble -block $blocks[$i] -seed $seeds[$i] if($i -eq 263) { Write-Output $seeds[$i] Write-Output $randoms[$i] Write-Output $fun } $result = $fun -bxor $result -bxor $randoms[$i] $output_file += $result } Add-Content -Path output_test.txt -Value $output_file ``` ::: ## Recon 這一題太難了,花了好多時間,不看[^pico-reverse-powershelly-wp-IRS-Cybersec]的WP大概猜到了六七成,不過最後的部分才是關鍵,再加上不是很懂powershell的語法 1. Check File Format 首先他先檢查input.txt的格式,可以從這邊看出來他應該是一個==5列的content==,以及總字元數(所有bytes的數量)是9245,接著他判斷每個字元是否都符合`0`, `1`, `carriage return`, `\n`, `<space>` ```bash if ($out.Length -gt 5 -or $enc.count -ne $numLength) ... if (($enc[$i] -ne 49) -and ($enc[$i] -ne 48) -and ($enc[$i] -ne 10) -and ($enc[$i] -ne 13) -and ($enc[$i] -ne 32)) ``` 另外他還會檢查每一個row中,用空格split的每一個element是不是都符合6個字元,簡單解釋一下下面在幹嘛,他先創一個dictionary,叫做\$blocks,然後把\$out第一個row,先用空格格開,再比對每一個element是否都是6個字元,實際跑過之後他會長下面這樣 :::spoiler $blocks的格式 ``` Name Value ---- ----- 263 {110011, 100011, 110011, 110011...} 262 {100001, 001100, 001100, 001100...} 261 {110011, 100011, 110011, 110011...} 260 {110011, 100011, 110011, 110011...} 259 {110011, 100011, 110011, 110011...} 258 {110011, 100011, 110011, 110011...} 257 {110011, 100011, 110011, 110011...} 256 {100001, 001100, 001100, 001100...} 255 {110011, 100011, 110011, 110011...} 254 {100001, 001100, 001100, 001100...} 253 {100001, 001100, 001100, 001100...} 252 {100001, 001100, 001100, 001100...} 251 {100001, 001100, 001100, 001100...} 250 {110011, 100011, 110011, 110011...} 249 {100001, 001100, 001100, 001100...} 248 {100001, 001100, 001100, 001100...} 247 {100001, 001100, 001100, 001100...} 246 {100001, 001100, 001100, 001100...} 245 {110011, 100011, 110011, 110011...} 244 {110011, 100011, 110011, 110011...} 243 {100001, 001100, 001100, 001100...} 242 {110011, 100011, 110011, 110011...} 241 {110011, 100011, 110011, 110011...} 240 {100001, 001100, 001100, 001100...} 239 {110011, 100011, 110011, 110011...} 238 {100001, 001100, 001100, 001100...} 237 {110011, 100011, 110011, 110011...} 236 {100001, 001100, 001100, 001100...} 235 {100001, 001100, 001100, 001100...} 234 {110011, 100011, 110011, 110011...} 233 {110011, 100011, 110011, 110011...} 232 {100001, 001100, 001100, 001100...} 231 {100001, 001100, 001100, 001100...} 230 {100001, 001100, 001100, 001100...} 229 {100001, 001100, 001100, 001100...} 228 {110011, 100011, 110011, 110011...} 227 {100001, 001100, 001100, 001100...} 226 {110011, 100011, 110011, 110011...} 225 {110011, 100011, 110011, 110011...} 224 {100001, 001100, 001100, 001100...} 223 {100001, 001100, 001100, 001100...} 222 {100001, 100011, 001100, 001100...} 221 {110011, 001100, 110011, 110011...} 220 {100001, 001100, 001100, 001100...} 219 {100001, 001100, 001100, 001100...} 218 {110011, 100011, 110011, 110011...} 217 {100001, 001100, 001100, 001100...} 216 {100001, 001100, 001100, 001100...} 215 {100001, 001100, 001100, 001100...} 214 {110011, 100011, 110011, 110011...} 213 {100001, 001100, 001100, 001100...} 212 {100001, 001100, 001100, 001100...} 211 {110011, 100011, 110011, 110011...} 210 {110011, 100011, 110011, 110011...} 209 {110011, 100011, 110011, 110011...} 208 {100001, 001100, 001100, 001100...} 207 {110011, 100011, 110011, 110011...} 206 {110011, 100011, 110011, 110011...} 205 {100001, 001100, 001100, 001100...} 204 {100001, 001100, 001100, 001100...} 203 {110011, 100011, 110011, 110011...} 202 {110011, 100011, 110011, 110011...} 201 {100001, 001100, 001100, 001100...} 200 {100001, 001100, 001100, 001100...} 199 {110011, 100011, 110011, 110011...} 198 {110011, 100011, 110011, 110011...} 197 {110011, 100011, 110011, 110011...} 196 {100001, 001100, 001100, 001100...} 195 {110011, 100011, 110011, 110011...} 194 {110011, 100011, 110011, 110011...} 193 {110011, 100011, 110011, 110011...} 192 {100001, 001100, 001100, 001100...} 191 {110011, 100011, 110011, 110011...} 190 {110011, 100011, 110011, 110011...} 189 {110011, 100011, 110011, 110011...} 188 {110011, 100011, 110011, 110011...} 187 {100001, 001100, 001100, 001100...} 186 {110011, 100011, 110011, 110011...} 185 {110011, 100011, 110011, 110011...} 184 {100001, 001100, 001100, 001100...} 183 {100001, 001100, 001100, 001100...} 182 {100001, 001100, 001100, 001100...} 181 {100001, 001100, 001100, 001100...} 180 {100001, 001100, 001100, 001100...} 179 {110011, 100011, 110011, 110011...} 178 {110011, 100011, 110011, 110011...} 177 {110011, 100011, 110011, 110011...} 176 {100001, 001100, 001100, 001100...} 175 {110011, 100011, 110011, 110011...} 174 {110011, 100011, 110011, 110011...} 173 {110011, 100011, 110011, 110011...} 172 {110011, 100011, 110011, 110011...} 171 {110011, 100011, 110011, 110011...} 170 {100001, 001100, 001100, 001100...} 169 {110011, 100011, 110011, 110011...} 168 {100001, 001100, 001100, 001100...} 167 {100001, 001100, 001100, 001100...} 166 {110011, 100011, 110011, 110011...} 165 {100001, 001100, 001100, 001100...} 164 {100001, 001100, 001100, 001100...} 163 {110011, 100011, 110011, 110011...} 162 {110011, 100011, 110011, 110011...} 161 {100001, 001100, 001100, 001100...} 160 {100001, 001100, 001100, 001100...} 159 {110011, 100011, 110011, 110011...} 158 {110011, 100011, 110011, 110011...} 157 {110011, 100011, 110011, 110011...} 156 {110011, 100011, 110011, 110011...} 155 {110011, 100011, 110011, 110011...} 154 {100001, 001100, 001100, 001100...} 153 {110011, 100011, 110011, 110011...} 152 {100001, 001100, 001100, 001100...} 151 {110011, 100011, 110011, 110011...} 150 {100001, 001100, 001100, 001100...} 149 {100001, 001100, 001100, 001100...} 148 {110011, 100011, 110011, 110011...} 147 {110011, 100011, 110011, 110011...} 146 {110011, 100011, 110011, 110011...} 145 {110011, 100011, 110011, 110011...} 144 {100001, 001100, 001100, 001100...} 143 {100001, 001100, 001100, 001100...} 142 {100001, 001100, 001100, 001100...} 141 {100001, 001100, 001100, 001100...} 140 {100001, 001100, 001100, 001100...} 139 {100001, 001100, 001100, 001100...} 138 {100001, 001100, 001100, 001100...} 137 {110011, 100011, 110011, 110011...} 136 {100001, 001100, 001100, 001100...} 135 {110011, 100011, 110011, 110011...} 134 {110011, 100011, 110011, 110011...} 133 {110011, 100011, 110011, 110011...} 132 {100001, 001100, 001100, 001100...} 131 {110011, 100011, 110011, 110011...} 130 {110011, 100011, 110011, 110011...} 129 {110011, 100011, 110011, 110011...} 128 {100001, 001100, 001100, 001100...} 127 {100001, 001100, 001100, 001100...} 126 {100001, 001100, 001100, 001100...} 125 {100001, 001100, 001100, 001100...} 124 {110011, 100011, 110011, 110011...} 123 {100001, 001100, 001100, 001100...} 122 {110011, 100011, 110011, 110011...} 121 {110011, 100011, 110011, 110011...} 120 {100001, 001100, 001100, 001100...} 119 {110011, 100011, 110011, 110011...} 118 {110011, 100011, 110011, 110011...} 117 {110011, 100011, 110011, 110011...} 116 {100001, 001100, 001100, 001100...} 115 {100001, 001100, 001100, 001100...} 114 {110011, 100011, 110011, 110011...} 113 {110011, 100011, 110011, 110011...} 112 {100001, 001100, 001100, 001100...} 111 {110011, 100011, 110011, 110011...} 110 {100001, 001100, 001100, 001100...} 109 {100001, 001100, 001100, 001100...} 108 {110011, 100011, 110011, 110011...} 107 {100001, 001100, 001100, 001100...} 106 {110011, 100011, 110011, 110011...} 105 {110011, 100011, 110011, 110011...} 104 {100001, 001100, 001100, 001100...} 103 {100001, 001100, 001100, 001100...} 102 {100001, 001100, 001100, 001100...} 101 {100001, 001100, 001100, 001100...} 100 {110011, 100011, 110011, 110011...} 99 {100001, 001100, 001100, 001100...} 98 {110011, 100011, 110011, 110011...} 97 {110011, 100011, 110011, 110011...} 96 {100001, 001100, 001100, 001100...} 95 {100001, 001100, 001100, 001100...} 94 {100001, 001100, 001100, 001100...} 93 {100001, 001100, 001100, 001100...} 92 {110011, 100011, 110011, 110011...} 91 {110011, 100011, 110011, 110011...} 90 {110011, 100011, 110011, 110011...} 89 {100001, 001100, 001100, 001100...} 88 {100001, 001100, 001100, 001100...} 87 {110011, 100011, 110011, 110011...} 86 {100001, 001100, 001100, 001100...} 85 {100001, 001100, 001100, 001100...} 84 {100001, 001100, 001100, 001100...} 83 {110011, 100011, 110011, 110011...} 82 {110011, 100011, 110011, 110011...} 81 {100001, 001100, 001100, 001100...} 80 {100001, 001100, 001100, 001100...} 79 {100001, 001100, 001100, 001100...} 78 {100001, 001100, 001100, 001100...} 77 {100001, 001100, 001100, 001100...} 76 {100001, 001100, 001100, 001100...} 75 {110011, 100011, 110011, 110011...} 74 {110011, 100011, 110011, 110011...} 73 {100001, 001100, 001100, 001100...} 72 {100001, 001100, 001100, 001100...} 71 {100001, 001100, 001100, 001100...} 70 {110011, 100011, 110011, 110011...} 69 {100001, 001100, 001100, 001100...} 68 {100001, 001100, 001100, 001100...} 67 {110011, 100011, 110011, 110011...} 66 {110011, 100011, 110011, 110011...} 65 {100001, 001100, 001100, 001100...} 64 {100001, 001100, 001100, 001100...} 63 {110011, 100011, 110011, 110011...} 62 {110011, 100011, 110011, 110011...} 61 {100001, 001100, 001100, 001100...} 60 {110011, 100011, 110011, 110011...} 59 {110011, 100011, 110011, 110011...} 58 {110011, 100011, 110011, 110011...} 57 {110011, 100011, 110011, 110011...} 56 {100001, 001100, 001100, 001100...} 55 {100001, 001100, 001100, 001100...} 54 {110011, 100011, 110011, 110011...} 53 {110011, 100011, 110011, 110011...} 52 {100001, 001100, 001100, 001100...} 51 {100001, 001100, 001100, 001100...} 50 {100001, 001100, 001100, 001100...} 49 {110011, 100011, 110011, 110011...} 48 {100001, 001100, 001100, 001100...} 47 {100001, 001100, 001100, 001100...} 46 {100001, 001100, 001100, 001100...} 45 {110011, 100011, 110011, 110011...} 44 {100001, 001100, 001100, 001100...} 43 {110011, 100011, 110011, 110011...} 42 {100001, 001100, 001100, 001100...} 41 {110011, 100011, 110011, 110011...} 40 {100001, 001100, 001100, 001100...} 39 {110011, 100011, 110011, 110011...} 38 {110011, 100011, 110011, 110011...} 37 {100001, 001100, 001100, 001100...} 36 {100001, 001100, 001100, 001100...} 35 {100001, 001100, 001100, 001100...} 34 {100001, 001100, 001100, 001100...} 33 {110011, 100011, 110011, 110011...} 32 {100001, 001100, 001100, 001100...} 31 {110011, 100011, 110011, 110011...} 30 {110011, 100011, 110011, 110011...} 29 {110011, 100011, 110011, 110011...} 28 {110011, 100011, 110011, 110011...} 27 {100001, 001100, 001100, 001100...} 26 {110011, 100011, 110011, 110011...} 25 {110011, 100011, 110011, 110011...} 24 {100001, 001100, 001100, 001100...} 23 {110011, 100011, 110011, 110011...} 22 {110011, 100011, 110011, 110011...} 21 {100001, 001100, 001100, 001100...} 20 {100001, 001100, 001100, 001100...} 19 {100001, 001100, 001100, 001100...} 18 {110011, 100011, 110011, 110011...} 17 {110011, 100011, 110011, 110011...} 16 {100001, 001100, 001100, 001100...} 15 {110011, 100011, 110011, 110011...} 14 {100001, 001100, 001100, 001100...} 13 {100001, 001100, 001100, 001100...} 12 {110011, 100011, 110011, 110011...} 11 {100001, 001100, 001100, 001100...} 10 {110011, 100011, 110011, 110011...} 9 {110011, 100011, 110011, 110011...} 8 {100001, 001100, 001100, 001100...} 7 {100001, 001100, 001100, 001100...} 6 {100001, 001100, 001100, 001100...} 5 {100001, 001100, 001100, 001100...} 4 {100001, 001100, 001100, 001100...} 3 {110011, 100011, 110011, 110011...} 2 {110011, 100011, 110011, 110011...} 1 {110011, 100011, 110011, 110011...} 0 {100001, 001100, 001100, 001100...} ``` ::: ```python=27 $blocks = @{} for ($i=0; $i -lt $out.Length ; $i++) { $r = $out[$i].Split(" ") if ($i -gt 0) { for ($j=0; $j -lt $r.Length ; $j++) { if ($r[$j].Length -ne 6) { Write-Output "Wrong Format 6" $r[$j].Length Exit } $blocks[$j] += $r[$j] } } else { for ($j=0; $j -lt $r.Length ; $j++) { if ($r[$j].Length -ne 6) { Write-Output "Wrong Format 6" $r[$j].Length Exit } $blocks[$j] = @() $blocks[$j] += $r[$j] } } } ``` Note: `$out.Length`在只有一列的情況下會return那一列的字元數,但如果列的數量大於一,就會return列的數量,例如:假設input.txt目前有三列,則`$out==3`,但如果現在只有一列,而此列上寫了10個字元,則`$out==10` 2. Before Encryption 在執行加密之前,他會運算seeds和random number以便後續的運算 ```bash=111 for ($i=1; $i -lt ($blocks.count +1); $i++) { $seeds += ($i * 127) % 500 } ``` ```bash=65 function Random-Gen { $list1 = @() for ($i=1; $i -lt ($blocks.count + 1); $i++) { $y = ((($i * 327) % 681 ) + 344) % 313 $list1 += $y } return $list1 } ``` 3. Encryption 實際加密的步驟是:計算\$fun,他先create一個list,然後先存'10'*\$raw.Length,然後用\$seed計算index(隨機的),如果\$raw[\$index]是`1`,那就改成`11`,相反,如果是`0`,就改成`00`。接著他會和\$result以及\$randoms[\$i]做xor,就得到最後的ciphertext 4. Decryption 1. 我們的目標是要還原出一開始input file中的內容,這樣我們才知道最後的flag的形式長怎麼,所以做法就是逆著做回去,先算出\$fun是多少,一開始的\$result是`0`,所以我們可以直接再做xor,就得到\$fun, ```python=11 fun = int(output[i].strip()) ^ result ^ randoms[i] ``` Note: \$seeds和\$randoms可以直接用他給的code section用PS跑看看再存成檔案,也可以直接用python實作,答案會是一樣的 2. 接著,因為他原本是存成binary的形式,所以轉成binary之後要把他split成兩兩一組,再進行之前說的`1`$\iff$`11`和`0`$\iff$`00`轉換,也就是先計算前面提到的random index by `(j * seeds[i]) % len(tmpFlagSplit)`,再看對應的array是00還是11 ```python=17 for j in range(len(tmpFlagSplit)): y = (j * seeds[i]) % len(tmpFlagSplit) if tmpFlagSplit[y] == 'x': while(tmpFlagSplit[y] == 'x'): y = (y + 1) % len(tmpFlagSplit) if tmpFlagSplit[y] == '00': finalFlag += "0" tmpFlagSplit[y] = 'x' elif tmpFlagSplit[y] == '11': finalFlag += "1" tmpFlagSplit[y] = 'x' ``` 3. 前面提到他是一個擁有五個列as content的file,然後每一列都會每六個字元用空格隔開的形式,因此我們也要把結果變成這樣才對。 ```python=32 finalFlagArr = [[], [], [], [], []] for i in range(len(finalFlag)): finalFlagArr[i % 5].append(finalFlag[i]) ``` 5. Find Flag 透過上述的形式,我們已經把input.txt還原出來了,仔細觀察會發現每一個row,都只有包含兩種字串,舉例:第一個row就只包含`100001`和`110011`而已,而第二個row則只有包含`001100`和`100011`,寫CTF也這麼久了,直覺就是一個binary encoding,試著把`100001`當成`0`,另外一個當成`1`,再傳換成utf-8應該就會產生flag了 ## Exploit ```python= output = open('./PicoCTF/Reverse/Powershelly/output.txt', 'r').readlines() finalFlag = [] tmpFlagSplit = [] randoms = [45, 59, 18, 32, 304, 5, 277, 291, 250, 264, 223, 237, 196, 210, 169, 183, 142, 156, 115, 129, 88, 102, 61, 75, 34, 48, 62, 21, 35, 307, 8, 280, 294, 253, 267, 226, 240, 199, 213, 172, 186, 145, 159, 118, 132, 91, 105, 64, 78, 37, 51, 65, 24, 38, 310, 11, 283, 297, 256, 270, 229, 243, 202, 216, 175, 189, 148, 162, 121, 135, 94, 108, 67, 81, 40, 54, 68, 27, 41, 0, 14, 286, 300, 259, 273, 232, 246, 205, 219, 178, 192, 151, 165, 124, 138, 97, 111, 70, 84, 43, 57, 71, 30, 44, 3, 17, 289, 303, 262, 276, 235, 249, 208, 222, 181, 195, 154, 168, 127, 141, 100, 114, 73, 87, 46, 60, 74, 33, 47, 6, 20, 292, 306, 265, 279, 238, 252, 211, 225, 184, 198, 157, 171, 130, 144, 103, 117, 76, 90, 49, 63, 77, 36, 50, 9, 23, 295, 309, 268, 282, 241, 255, 214, 228, 187, 201, 160, 174, 133, 147, 106, 120, 79, 93, 52, 66, 80, 39, 53, 12, 26, 298, 312, 271, 285, 244, 258, 217, 231, 190, 204, 163, 177, 136, 150, 109, 123, 82, 96, 55, 69, 83, 42, 56, 15, 29, 301, 2, 274, 288, 247, 261, 220, 234, 193, 207, 166, 180, 139, 153, 112, 126, 85, 99, 58, 72, 31, 45, 59, 18, 32, 304, 5, 277, 291, 250, 264, 223, 237, 196, 210, 169, 183, 142, 156, 115, 129, 88, 102, 61, 75, 34, 48, 62, 21, 35, 307, 8, 280, 294, 253, 267, 226, 240] seeds = [127, 254, 381, 8, 135, 262, 389, 16, 143, 270, 397, 24, 151, 278, 405, 32, 159, 286, 413, 40, 167, 294, 421, 48, 175, 302, 429, 56, 183, 310, 437, 64, 191, 318, 445, 72, 199, 326, 453, 80, 207, 334, 461, 88, 215, 342, 469, 96, 223, 350, 477, 104, 231, 358, 485, 112, 239, 366, 493, 120, 247, 374, 1, 128, 255, 382, 9, 136, 263, 390, 17, 144, 271, 398, 25, 152, 279, 406, 33, 160, 287, 414, 41, 168, 295, 422, 49, 176, 303, 430, 57, 184, 311, 438, 65, 192, 319, 446, 73, 200, 327, 454, 81, 208, 335, 462, 89, 216, 343, 470, 97, 224, 351, 478, 105, 232, 359, 486, 113, 240, 367, 494, 121, 248, 375, 2, 129, 256, 383, 10, 137, 264, 391, 18, 145, 272, 399, 26, 153, 280, 407, 34, 161, 288, 415, 42, 169, 296, 423, 50, 177, 304, 431, 58, 185, 312, 439, 66, 193, 320, 447, 74, 201, 328, 455, 82, 209, 336, 463, 90, 217, 344, 471, 98, 225, 352, 479, 106, 233, 360, 487, 114, 241, 368, 495, 122, 249, 376, 3, 130, 257, 384, 11, 138, 265, 392, 19, 146, 273, 400, 27, 154, 281, 408, 35, 162, 289, 416, 43, 170, 297, 424, 51, 178, 305, 432, 59, 186, 313, 440, 67, 194, 321, 448, 75, 202, 329, 456, 83, 210, 337, 464, 91, 218, 345, 472, 99, 226, 353, 480, 107, 234, 361, 488, 115, 242, 369, 496, 123, 250, 377, 4, 131, 258, 385, 12, 139, 266, 393, 20, 147, 274, 401, 28] result = 0 for i in range(len(output)): fun = int(output[i].strip()) ^ result ^ randoms[i] result = int(output[i].strip()) tmp = bin(fun)[2:] tmpFlagSplit = [tmp[i:i+2] for i in range(0, len(tmp), 2)] assert len(tmpFlagSplit) == 30 for j in range(len(tmpFlagSplit)): y = (j * seeds[i]) % len(tmpFlagSplit) if tmpFlagSplit[y] == 'x': while(tmpFlagSplit[y] == 'x'): y = (y + 1) % len(tmpFlagSplit) if tmpFlagSplit[y] == '00': finalFlag += "0" tmpFlagSplit[y] = 'x' elif tmpFlagSplit[y] == '11': finalFlag += "1" tmpFlagSplit[y] = 'x' finalFlag = "".join(finalFlag) finalFlag = [finalFlag[i:i+6] for i in range(0, len(finalFlag), 6)] print(finalFlag) finalFlagArr = [[], [], [], [], []] for i in range(len(finalFlag)): finalFlagArr[i % 5].append(finalFlag[i]) for i in range(len(finalFlagArr)): tmp_arr = set(finalFlagArr[i]) tmp_arr_single_row = " ".join(finalFlagArr[i]) bit = "0" for j in tmp_arr: tmp_arr_single_row = tmp_arr_single_row.replace(j, bit) bit = '1' finalFlagArr[i] = tmp_arr_single_row.replace(" ", "") print(bytes.fromhex(hex(int(finalFlagArr[0], 2))[2:]).decode('cp437')) ``` Flag: `picoCTF{2018highw@y_2_pow3r$hel!}` ## Reference [^pico-reverse-powershelly-wp-IRS-Cybersec]:[Powershelly [180 Points] - 101 Solves](https://github.com/IRS-Cybersec/ctfdump/tree/master/picoCTF/2021/RE/Powershelly)