当前位置: 首页 > 工具软件 > Haskell GHC > 使用案例 >

记一次haskell程序逆向过程

孔理
2023-12-01

已同步到个人博客:www.radishes.top

2016年CISCN一道150分的逆向

下载文件后发现是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
            <tag 1> -> 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 <flag>")
    )

rkl_info = \rkl_info_arg_0 ->
    case rkl_info_arg_0 of
        <tag 1> -> [],
        sA0_info_case_tag_DEFAULT_arg_0@_DEFAULT -> case sA0_info_case_tag_DEFAULT_arg_1 of
            <tag 1> -> 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 <index 0 in s#_info_case_tag_DEFAULT>)
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}

 类似资料: