已同步到个人博客:www.radishes.top
下载文件后发现是64位ELF文件,运行一遍发先需要传入命令行参数,没想那么多,直接拖入IDA中查看反汇编出来的代码
emmm,发现代码居多,一层套一层,想着通过关键字符串反着找到该程序的关键代码,但是找了一番之后真是找不到呀,用gdb动态调试,最后也是无果,emmmm头大。
在网上找了一波资料之后发现该程序是由haskell语言写的,之前没遇到过
haskell简介:Haskell是一种标准化的、通用纯函数式编程语言,有非限定性语义和强静态类型。它的命名源自美国逻辑学家Haskell Brooks Curry,他在数学逻辑方面的工作使得函数式编程语言有了广泛的基础。在Haskell中,函数是一等公民。作为函数式编程语言,主要控制结构是函数。Haskell语言是1990年在编程语言Miranda的基础上标准化的,并且以λ演算(Lambda-Calculus)为基础发展而来。具有“证明即程序、结论公式即程序类型”的特征。这也是Haskell语言以希腊字母「λ」(Lambda)作为自己标志的原因。Haskell语言的最主要的执行环境是GHC。
简介中也提出该语言是基于纯函数式的编程语言,函数确实有点多呀!
当然还是有解决办法的,在github上有一个针对Haskell语言的反编译脚本hsdecomp
下载好之后直接反编译程序
一筐萝卜 ➜ hsdecomp git:(master) python3 runner.py ~/Desktop/re_test
Main_main_closure = >>= $fMonadIO
getArgs
(\sz_info_arg_0 ->
case /= $fEqInt (length sz_info_arg_0) (I# 1) of
-> case == ($fEq[] $fEqChar) (rkl_info (!! sz_info_arg_0 (I# 0))) (unpackCString# "bk_vefuhfuhfuha1n4shaqcz") of
False -> $ putStrLn (unpackCString# "Nope"),
True -> putStrLn (unpackCString# "Congratz"),
sPh_info_case_tag_DEFAULT_arg_0@_DEFAULT -> putStrLn (unpackCString# "Usage: ./task ")
)
rkl_info = \rkl_info_arg_0 ->
case rkl_info_arg_0 of
-> [],
sA0_info_case_tag_DEFAULT_arg_0@_DEFAULT -> case sA0_info_case_tag_DEFAULT_arg_1 of
-> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030896 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030912 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030864 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030880 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030960 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030976 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030928 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030944 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030848 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030992 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031056 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031072 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031088 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031104 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031008 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031024 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031200 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031264 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031296 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031040 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031120 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031136 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031152 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031216 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031232 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031248 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031168 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7031184 of
False -> case == $fEqChar sA0_info_case_tag_DEFAULT_arg_0 loc_7030816 of
False -> : sA0_info_case_tag_DEFAULT_arg_0 [],
True -> : loc_7030848 [],
True -> : loc_7030976 [],
True -> : loc_7031072 [],
True -> : loc_7031120 [],
True -> : loc_7031152 [],
True -> : loc_7031232 [],
True -> : loc_7031088 [],
True -> : loc_7031104 [],
True -> : loc_7031136 [],
True -> : loc_7030992 [],
True -> : loc_7031248 [],
True -> : loc_7030912 [],
True -> : loc_7031168 [],
True -> : loc_7031008 [],
True -> : loc_7031024 [],
True -> : loc_7030896 [],
True -> : loc_7030928 [],
True -> : loc_7030944 [],
True -> : loc_7030960 [],
True -> : loc_7031200 [],
True -> : loc_7030816 [],
True -> : loc_7031184 [],
True -> : loc_7030864 [],
True -> : loc_7031216 [],
True -> : loc_7030880 [],
True -> : loc_7031264 [],
True -> : loc_7031296 [],
True -> : loc_7031056 [],
True -> : loc_7031040 [],
s#_info_case_tag_DEFAULT_arg_0@_DEFAULT -> ++ (rkl_info (: sA0_info_case_tag_DEFAULT_arg_0 [])) (rkl_info )
loc_7031040 = C# 109
loc_7031056 = C# 110
loc_7031296 = C# 125
loc_7031264 = C# 123
loc_7030880 = C# 99
loc_7031216 = C# 120
loc_7030864 = C# 98
loc_7031184 = C# 118
loc_7030816 = C# 95
loc_7031200 = C# 119
loc_7030960 = C# 104
loc_7030944 = C# 103
loc_7030928 = C# 102
loc_7030896 = C# 100
loc_7031024 = C# 108
loc_7031008 = C# 107
loc_7031168 = C# 117
loc_7030912 = C# 101
loc_7031248 = C# 122
loc_7030992 = C# 106
loc_7031136 = C# 115
loc_7031104 = C# 113
loc_7031088 = C# 112
loc_7031232 = C# 121
loc_7031152 = C# 116
loc_7031120 = C# 114
loc_7031072 = C# 111
loc_7030976 = C# 105
loc_7030848 = C# 97
反编译出来的代码有点感动呀,还算清晰
分析一波发现其实程序主要实现的是一个字符串替换的算法
反推出来flag:
data = {"m":"d","n":"e","}":"b","{":"c","c":"h","x":"i","b":"f","v":"g","_":"a","w":"j","h":"n","g":"o","f":"p","d":"q","l":"k","k":"l","u":"w","e":"{","z":"}","j":"m","s":"r","q":"s","p":"t","y":"x","t":"y","r":"z","o":"u","i":"v","a":"_"}
current = "bk_vefuhfuhfuha1n4shaqcz"
flag = ""
for x in range(len(current)):
try:
flag += data[current[x]]
except BaseException:
flag += current[x]
print flag
得出flag:flag{pwnpwnpwn_1e4rn_sh}