SECON 2017 Online CTF Powerful Shell(Binary, 300pt)

score-quals.seccon.jp

powershellの実行ファイルが与えられます。
そのままだと実行権限無かったのでまずぐぐってPCの設定を変えます。
中身はこんな感じ。

$ECCON="";
$ECCON+=[char](3783/291);
$ECCON+=[char](6690/669);
$ECCON+=[char](776-740);
$ECCON+=[char](381-312);
$ECCON+=[char](403-289);
$ECCON+=[char](-301+415);
$ECCON+=[char](143-32);
$ECCON+=[char](93594/821);

(中略)

$ECCON+=[char](803-793);
$ECCON+=[char](10426/802);
Write-Progress -Activity "Extracting Script" -status "20040" -percentComplete 99;
$ECCON+=[char](520-510);
Write-Progress -Completed -Activity "Extracting Script";.([ScriptBlock]::Create($ECCON))

難読化(?)したコードを生成しなおして実行しているっぽい。
というわけで$ECCONを別ファイルに出力すると、それ自体がpowershellスクリプトになるので実行します。

f:id:sueki_1242:20171212000208p:plain
すごい。
This host is too freshだと文句を言われているので該当するスクリプト部を見ると

<# Host Check #>
Write-Host -b 00 -f 15 Checking Host... Please wait... -n
Try{
	If ((Get-EventLog -LogName Security | Where EventID -Eq 4624).Length -Lt 1000) {
		Write-Host "This host is too fresh!"
		Exit
	}
}Catch{
	Write-Host "Failed: No admin rights!"
	Exit
}
Write-Host "Check passed"

一瞬イベントログについて真面目に調べかけましたが、30分くらいしてこのコードをまるっと消せばいいことに気づきます。

f:id:sueki_1242:20171212000458p:plain

すごい。(2回目)
実際にキーを押すと音が鳴ります。すごい。
でまあ何音か鳴らすとプログラムが終わってしまうので該当するコードを読みます。

$keytone=@{'a'=261.63}
$pk='a'
ForEach($k in ('w','s','e','d','f','t','g','y','h','u','j','k')){
	$keytone+=@{$k=$keytone[$pk]*[math]::pow(2,1/12)};$pk=$k
}
Write-Host -b 00 -f 15 "Play the secret melody."

(ここに鍵盤を描画するprint文がひたすら入るので略)

Write-Host
$stage1=@();$f="";
While($stage1.length -lt 14){
	$key=(Get-Host).ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	$k=[String]$key.Character
	$f+=$k;
	If($keytone.Contains($k)){
		$stage1+=[math]::floor($keytone[$k])
		[console]::beep($keytone[$k],500)
	}
}
$secret=@(440,440,493,440,440,493,440,493,523,493,440,493,440,349)
If($secret.length -eq $stage1.length){
	For ($i=1; $i -le $secret.length; $i++) {
		If($secret[$i] -ne $stage1[$i]){
			Exit
		}
	}
	x "Correct. Move to the next stage."
}

冒頭の

ForEach($k in ('w','s','e','d','f','t','g','y','h','u','j','k')){
	$keytone+=@{$k=$keytone[$pk]*[math]::pow(2,1/12)};$pk=$k
}

でキーごとに音のトーンを表す数字を割り当てており、
それをsecretに書かれた順番通りに押せばクリアです。
なおこの鍵盤の入力が次のステップでも使われるため、これらのコードをまるっと消してしまうと今度は先に進めなくなります。

このステージを突破すると、今度は「Enter the password.」と言われます。
なんのこっちゃなので対応するコードを見ます。

$text=@"(3000文字位あるので略)"@

$plain=@()
$byteString = [System.Convert]::FromBase64String($text)
$xordData = $(for ($i = 0; $i -lt $byteString.length; ) {
	for ($j = 0; $j -lt $f.length; $j++) {
		$plain+=$byteString[$i] -bxor $f[$j]
		$i++
		if ($i -ge $byteString.Length) {
			$j = $f.length
		}
	}
})
iex([System.Text.Encoding]::ASCII.GetString($plain))

ということで最初と同じくまた難読化したコードを組み立てて実行しているので、
実行直前に$plainを吐き出してみます。

${;}=+$();${=}=${;};${+}=++${;};${@}=++${;};${.}=++${;};${[}=++${;};
${]}=++${;};${(}=++${;};${)}=++${;};${&}=++${;};${|}=++${;};
${"}="["+"$(@{})"[${)}]+"$(@{})"["${+}${|}"]+"$(@{})"["${@}${=}"]+"$?"[${+}]+"]";
${;}="".("$(@{})"["${+}${[}"]+"$(@{})"["${+}${(}"]+"$(@{})"[${=}]+"$(@{})"[${[}]+"$?"[${+}]+"$(@{})"[${.}]);
${;}="$(@{})"["${+}${[}"]+"$(@{})"[${[}]+"${;}"["${@}${)}"];"${"}${.}${(}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${(}${+}+${"}${&}${@}+${"}${+}${=}${+}+${"}${|}${)}+${"}${+}${=}${=}+${"}${[}${]}+${"}${)}${@}+${"}${+}${+}${+}+${"}${+}${+}${]}+${"}${+}${+}${(}+${"}${.}${@}+${"}${[}${]}+${"}${&}${=}+${"}${+}${+}${[}+${"}${+}${+}${+}+${"}${+}${=}${|}+${"}${+}${+}${@}+${"}${+}${+}${(}+${"}${.}${@}+${"}${.}${|}+${"}${(}${|}+${"}${+}${+}${=}+${"}${+}${+}${(}+${"}${+}${=}${+}+${"}${+}${+}${[}+${"}${.}${@}+${"}${+}${+}${(}+${"}${+}${=}${[}+${"}${+}${=}${+}+${"}${.}${@}+${"}${+}${+}${@}+${"}${|}${)}+${"}${+}${+}${]}+${"}${+}${+}${]}+${"}${+}${+}${|}+${"}${+}${+}${+}+${"}${+}${+}${[}+${"}${+}${=}${=}+${"}${.}${|}+${"}${+}${.}+${"}${+}${=}+${"}${)}${.}+${"}${+}${=}${@}+${"}${[}${=}+${"}${.}${(}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${.}${@}+${"}${[}${]}+${"}${+}${=}${+}+${"}${+}${+}${.}+${"}${.}${@}+${"}${.}${|}+${"}${&}${=}+${"}${[}${&}+${"}${+}${+}${|}+${"}${(}${|}+${"}${+}${+}${[}+${"}${.}${(}+${"}${)}${@}+${"}${]}${+}+${"}${[}${|}+${"}${[}${|}+${"}${.}${|}+${"}${[}${+}+${"}${+}${@}${.}+${"}${+}${.}+${"}${+}${=}+${"}${|}+${"}${&}${)}+${"}${+}${+}${[}+${"}${+}${=}${]}+${"}${+}${+}${(}+${"}${+}${=}${+}+${"}${[}${]}+${"}${)}${@}+${"}${+}${+}${+}+${"}${+}${+}${]}+${"}${+}${+}${(}+${"}${.}${@}+${"}${.}${|}+${"}${)}${+}+${"}${+}${+}${+}+${"}${+}${+}${+}+${"}${+}${=}${=}+${"}${.}${@}+${"}${)}${[}+${"}${+}${+}${+}+${"}${|}${&}+${"}${.}${.}+${"}${.}${|}+${"}${]}${|}+${"}${+}${.}+${"}${+}${=}+${"}${|}+${"}${&}${)}+${"}${+}${+}${[}+${"}${+}${=}${]}+${"}${+}${+}${(}+${"}${+}${=}${+}+${"}${[}${]}+${"}${)}${@}+${"}${+}${+}${+}+${"}${+}${+}${]}+${"}${+}${+}${(}+${"}${.}${@}+${"}${.}${[}+${"}${&}${.}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${+}${@}${.}+${"}${.}${(}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${+}${@}${]}+${"}${.}${[}+${"}${+}${.}+${"}${+}${=}+${"}${+}${@}${]}|${;}"|&${;}

すごい。(3回目)
いやがらせ方が悪質なので、とりあえず適宜改行を入れて変数名を分かりやすいものに置換します。

${var1}=+$();
${var2}=${var1};
${var3}=++${var1};
${var4}=++${var1};
${var5}=++${var1};
${var6}=++${var1};
${var7}=++${var1};
${var8}=++${var1};
${var9}=++${var1};
${var10}=++${var1};
${var11}=++${var1};
${var12}="["+"$(@{})"[${var9}]+"$(@{})"["${var3}${var11}"]+"$(@{})"["${var4}${var2}"]+"$?"[${var3}]+"]";
${var1}="".("$(@{})"["${var3}${var6}"]+"$(@{})"["${var3}${var8}"]+"$(@{})"[${var2}]+"$(@{})"[${var6}]+"$?"[${var3}]+"$(@{})"[${var5}]);
${var1}="$(@{})"["${var3}${var6}"]+"$(@{})"[${var6}]+"${var1}"["${var4}${var9}"];
"${var12}${var5}${var8}+${var12}${var8}${var11}+${var12}${var8}${var9}+${var12}${var8}${var9}+${var12}${var9}${var11}+${var12}${var9}${var10}+${var12}${var8}${var3}+${var12}${var10}${var4}+${var12}${var3}${var2}${var3}+${var12}${var11}${var9}+${var12}${var3}${var2}${var2}+${var12}${var6}${var7}+${var12}${var9}${var4}+${var12}${var3}${var3}${var3}+${var12}${var3}${var3}${var7}+${var12}${var3}${var3}${var8}+${var12}${var5}${var4}+${var12}${var6}${var7}+${var12}${var10}${var2}+${var12}${var3}${var3}${var6}+${var12}${var3}${var3}${var3}+${var12}${var3}${var2}${var11}+${var12}${var3}${var3}${var4}+${var12}${var3}${var3}${var8}+${var12}${var5}${var4}+${var12}${var5}${var11}+${var12}${var8}${var11}+${var12}${var3}${var3}${var2}+${var12}${var3}${var3}${var8}+${var12}${var3}${var2}${var3}+${var12}${var3}${var3}${var6}+${var12}${var5}${var4}+${var12}${var3}${var3}${var8}+${var12}${var3}${var2}${var6}+${var12}${var3}${var2}${var3}+${var12}${var5}${var4}+${var12}${var3}${var3}${var4}+${var12}${var11}${var9}+${var12}${var3}${var3}${var7}+${var12}${var3}${var3}${var7}+${var12}${var3}${var3}${var11}+${var12}${var3}${var3}${var3}+${var12}${var3}${var3}${var6}+${var12}${var3}${var2}${var2}+${var12}${var5}${var11}+${var12}${var3}${var5}+${var12}${var3}${var2}+${var12}${var9}${var5}+${var12}${var3}${var2}${var4}+${var12}${var6}${var2}+${var12}${var5}${var8}+${var12}${var8}${var11}+${var12}${var8}${var9}+${var12}${var8}${var9}+${var12}${var9}${var11}+${var12}${var9}${var10}+${var12}${var5}${var4}+${var12}${var6}${var7}+${var12}${var3}${var2}${var3}+${var12}${var3}${var3}${var5}+${var12}${var5}${var4}+${var12}${var5}${var11}+${var12}${var10}${var2}+${var12}${var6}${var10}+${var12}${var3}${var3}${var11}+${var12}${var8}${var11}+${var12}${var3}${var3}${var6}+${var12}${var5}${var8}+${var12}${var9}${var4}+${var12}${var7}${var3}+${var12}${var6}${var11}+${var12}${var6}${var11}+${var12}${var5}${var11}+${var12}${var6}${var3}+${var12}${var3}${var4}${var5}+${var12}${var3}${var5}+${var12}${var3}${var2}+${var12}${var11}+${var12}${var10}${var9}+${var12}${var3}${var3}${var6}+${var12}${var3}${var2}${var7}+${var12}${var3}${var3}${var8}+${var12}${var3}${var2}${var3}+${var12}${var6}${var7}+${var12}${var9}${var4}+${var12}${var3}${var3}${var3}+${var12}${var3}${var3}${var7}+${var12}${var3}${var3}${var8}+${var12}${var5}${var4}+${var12}${var5}${var11}+${var12}${var9}${var3}+${var12}${var3}${var3}${var3}+${var12}${var3}${var3}${var3}+${var12}${var3}${var2}${var2}+${var12}${var5}${var4}+${var12}${var9}${var6}+${var12}${var3}${var3}${var3}+${var12}${var11}${var10}+${var12}${var5}${var5}+${var12}${var5}${var11}+${var12}${var7}${var11}+${var12}${var3}${var5}+${var12}${var3}${var2}+${var12}${var11}+${var12}${var10}${var9}+${var12}${var3}${var3}${var6}+${var12}${var3}${var2}${var7}+${var12}${var3}${var3}${var8}+${var12}${var3}${var2}${var3}+${var12}${var6}${var7}+${var12}${var9}${var4}+${var12}${var3}${var3}${var3}+${var12}${var3}${var3}${var7}+${var12}${var3}${var3}${var8}+${var12}${var5}${var4}+${var12}${var5}${var6}+${var12}${var10}${var5}+${var12}${var8}${var11}+${var12}${var8}${var9}+${var12}${var8}${var9}+${var12}${var9}${var11}+${var12}${var9}${var10}+${var12}${var3}${var4}${var5}+${var12}${var5}${var8}+${var12}${var8}${var11}+${var12}${var8}${var9}+${var12}${var8}${var9}+${var12}${var9}${var11}+${var12}${var9}${var10}+${var12}${var3}${var4}${var7}+${var12}${var5}${var6}+${var12}${var3}${var5}+${var12}${var3}${var2}+${var12}${var3}${var4}${var7}|${var1}"|&${var1}

ひどいですがたいぶマシになりました。
${var1}="$(@{})"["${var3}${var6}"]+"$(@{})"[${var6}]+"${var1}"["${var4}${var9}"];
のあとでvar1をprintすると`iex`となっており、最終行の
"(壮大な文字列)|${var1}"|&${var1}
と組み合わせて
"(壮大な文字列)|${var1}"
を実行していることがわかるので、これをprintします。

[CHar]36+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]61+[CHar]82+[CHar]101+[CHar]97+[CHar]100+[CHar]45+[CHar]72+[CHar]111+[CHar]115+[CHar]116+[CHar]32+[CHar]45+[CHar]80+[CHar]114+[CHar]111+[CHar]109+[CHar]112+[CHar]116+[CHar]32+[CHar]39+[CHar]69+[CHar]110+[CHar]116+[CHar]101+[CHar]114+[CHar]32+[CHar]116+[CHar]104+[CHar]101+[CHar]32+[CHar]112+[CHar]97+[CHar]115+[CHar]115+[CHar]119+[CHar]111+[CHar]114+[CHar]100+[CHar]39+[CHar]13+[CHar]10+[CHar]73+[CHar]102+[CHar]40+[CHar]36+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]32+[CHar]45+[CHar]101+[CHar]113+[CHar]32+[CHar]39+[CHar]80+[CHar]48+[CHar]119+[CHar]69+[CHar]114+[CHar]36+[CHar]72+[CHar]51+[CHar]49+[CHar]49+[CHar]39+[CHar]41+[CHar]123+[CHar]13+[CHar]10+[CHar]9+[CHar]87+[CHar]114+[CHar]105+[CHar]116+[CHar]101+[CHar]45+[CHar]72+[CHar]111+[CHar]115+[CHar]116+[CHar]32+[CHar]39+[CHar]71+[CHar]111+[CHar]111+[CHar]100+[CHar]32+[CHar]74+[CHar]111+[CHar]98+[CHar]33+[CHar]39+[CHar]59+[CHar]13+[CHar]10+[CHar]9+[CHar]87+[CHar]114+[CHar]105+[CHar]116+[CHar]101+[CHar]45+[CHar]72+[CHar]111+[CHar]115+[CHar]116+[CHar]32+[CHar]34+[CHar]83+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]123+[CHar]36+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]125+[CHar]34+[CHar]13+[CHar]10+[CHar]125|iex

とりあえずASCII文字列っぽいので変換します。ちなみに${var12}の中身が’[CHar]’だったことに後で気付きました。

$ECCON=Read-Host -Prompt 'Enter the password'
If($ECCON -eq 'P0wEr$H311'){
        Write-Host 'Good Job!';
        Write-Host "SECCON{$ECCON}"
}

というわけでようやく正答が得られました。

感想

他は100点問題しか解いてなかったのでさすがに手数が多かったのですが、
かなり一本道な問題だったので取り組みやすく楽しかったです。
でも問題ジャンルが「「「Binary」」」なのはどういうことなの・・・