2023年SWPU NSS 秋季招新赛 CTF Reverse‘方向WP详解

base64

无壳64bit文件,,ida64分析

标准的base64,

import base64

# 要解码的 Base64 编码文本
encoded_text = "TlNTQ1RGe0lfcjNhbGx5X3cwdTFkX3U1ZV9iYXNlNjRfdDBfM25jb2RlX2ZsYWd9"

# 使用 base64 模块进行解码
decoded_bytes = base64.b64decode(encoded_text)

# 打印解码结果
print(decoded_bytes)

b'NSSCTF{I_r3ally_w0u1d_u5e_base64_t0_3ncode_flag}'

UPX

查壳,基础的UPX壳。用工具UPX脱壳

下载地址:UPX: the Ultimate Packer for eXecutables - Homepage

脱壳后,IDA打开

test your cmd

下载后,打开cmd

字节码

打开txt文件

3           0 LOAD_CONST               1 ('***************************')
              2 STORE_FAST               0 (flag)

  4           4 BUILD_LIST               0
              6 STORE_FAST               1 (s)

  5           8 BUILD_LIST               0
             10 LOAD_CONST               2 ((177, 171, 170, 185, 167, 180, 126, 136, 126, 147, 150, 146, 122, 126, 142, 129, 139, 137, 142, 117, 122, 130, 195, 132, 116, 109, 104))
             12 LIST_EXTEND              1
             14 STORE_FAST               2 (tmp)

  6          16 LOAD_GLOBAL              0 (range)
             18 LOAD_GLOBAL              1 (len)
             20 LOAD_FAST                0 (flag)
             22 CALL_FUNCTION            1
             24 CALL_FUNCTION            1
             26 GET_ITER
        >>   28 FOR_ITER                30 (to 60)
             30 STORE_FAST               3 (i)

  7          32 LOAD_FAST                1 (s)
             34 LOAD_METHOD              2 (append)
             36 LOAD_CONST               3 (255)
             38 LOAD_GLOBAL              3 (ord)
             40 LOAD_FAST                0 (flag)
             42 LOAD_FAST                3 (i)
             44 BINARY_SUBSCR
             46 CALL_FUNCTION            1
             48 LOAD_FAST                3 (i)
             50 BINARY_ADD
             52 BINARY_XOR
             54 CALL_METHOD              1
             56 POP_TOP
             58 JUMP_ABSOLUTE           28

  8     >>   60 LOAD_FAST                2 (tmp)
             62 LOAD_FAST                1 (s)
             64 COMPARE_OP               2 (==)
             66 POP_JUMP_IF_FALSE       78

  9          68 LOAD_GLOBAL              4 (print)
             70 LOAD_CONST               4 ('you are right')
             72 CALL_FUNCTION            1
             74 POP_TOP
             76 JUMP_FORWARD             8 (to 86)

 11     >>   78 LOAD_GLOBAL              4 (print)
             80 LOAD_CONST               5 ('this is wrang')
             82 CALL_FUNCTION            1
             84 POP_TOP
        >>   86 LOAD_CONST               0 (None)

一步一步反编译下;得到

flag = '***************************'
s =''
tmp = [177, 171, 170, 185, 167, 180, 126, 136, 126, 147, 150, 146, 122, 126, 142, 129, 139, 137, 142, 117, 122, 130, 195, 132, 116, 109, 104]
for i in range(len(tmp)):
    s.append(255-ord(flag[i]+i))
if s == tmp:
    print('you are right')
else:
    print('this is wrang')

逆向一下

tmp = [177, 171, 170, 185, 167, 180, 126, 136, 126, 147, 150, 146, 122, 126, 142, 129, 139, 137, 142, 117, 122, 130, 195, 132, 116, 109, 104]

ascii_strr = ''.join([chr(255 - byte - i) for i, byte in enumerate(tmp)])
print(ascii_strr)

NSSCTF{pyc_bytcode_wqh&dsy}

关于python字节码,下次会写个详细点的。

Junk Code

花指令的一道题目,很简单。前面我写过一篇花指令的文章,

CTF逆向Reverse 花指令介绍 and NSSCTF靶场入门题目复现_Sciurdae的博客-CSDN博客

看看呗~

看汇编去,Option-General打开

把花指令跳转的E9修改为nop

继续往下看,下面也是jz和jnz互补跳转

每修一个就会有新的代码出现,一直修复就好,遇到黄色的就按C恢复成代码

修完后就好啦,写个exp

# 输入的字符串
input_str = "NRQ@PC}Vdn4tHV4Yi9cd#\\}jsXz3LMuaaY0}nj]`4a5&WoB4glB7~u"

# 循环异或的数字
xor_numbers = list(range(9))

# 循环异或并输出ASCII字符
output_str = ""

for char in input_str:
    xor_key = xor_numbers.pop(0)
    xor_numbers.append(xor_key)  # 将当前数字移到列表末尾以循环使用
    xor_result = ord(char) ^ xor_key
    output_str += chr(xor_result)

print(output_str)

蟒蛇中文破解绿色版

依次打开看看。

secret是flag,main是我自己改了一点点的。demo和base_class随便看看,

其实就是教了一个分数和一个list列表的创建,主要看list部分,

list = [
    str(分数(ord(_), 1) * a) if i % 2 == 0 else str(分数(ord(_), 1) * b)
    for i, _ in enumerate(__import__("secret").flag)
]

意思就是:如果索引为偶数就*a否则*b。从上面可以知道a是二分之一,b是三分之一,那么我们逆向的话就是乘以2或3就好。博主python不好,写来写出都有点问题,最后还是手撸了。

flag = [78,83,83,67,84,70,123,116,104,49,115,95,49,115,95,112,121,95,119,111,114,108,100,33,95,105,116,105,115,117,52,102,97,108,33,125]
for i in range(len(flag)):
    flagg.append(chr(flag[i]))

print("".join(flagg))

# NSSCTF{th1s_1s_py_world!_itisu4fal!}

Char And Int

ida64打开;找到NSS函数

        

Exp

enc1 = [0xA, 0xBB, 0xCCC, 0xDDDD, 0xEEEEE, 0xFFFFFF, 0xEEEEE, 0xDDDD, 0xCCC, 0xBB, 0xA]
enc2 = [1129534276, 1719355119, 1664497065, 758561980, 1651301078,
        1707657426, 963363804, 875424228, 943287802, 1647785949,
        2100836670]

flag = []
xor = []
for i in range(len(enc1)):
    xor.append(enc1[i] ^ enc2[i])
hex_xor = [hex(x)[2:] for x in xor]
# print(hex_xor)
# ['4353534e', '667b4654', '63363965', '2d366161', '62623438', '6537372d', '39652d32', '342d3439', '38396136', '62373766', '7d383934']
for hex_xor in hex_xor:
    reverse_xor = ([hex_xor[i:i+2] for i in range(0,len(hex_xor),2)][::-1])
    ascii_string = ''.join([chr(int(hex_str, 16)) for hex_str in reverse_xor])
    flag.append(ascii_string)
print("".join(flag))

# NSSCTF{fe96caa6-84bb-77e2-e994-46a98f77b498}

这道题不难,但花的时间还是蛮多的,跟难度不成比例hhh,因为博主python不是很好,直接转换成ascii的话超出范围限制了;赶紧取恶补了下python切片的内容,算是研究出来了;

Robbie Wanna

一道unity游戏逆向的题目;一开始没有什么思路的,第一次接触这种题目/(ㄒoㄒ)/~~

后来骨骼了一下unity游戏逆向,浅浅的学习了几道题,算是搞明白了!

不会的推荐一篇文章

奇安信攻防社区-浅谈CTF中的unity游戏逆向

大佬写的,真的很牛讲的好详细!

接下来看题目

运行游戏看看

hhhh森林冰火人 吃三个宝石,然后到右上角有个门,进入就可以得到flag

逆向思路一般是,用dnSpy逆向Assembly-CSharp.dll文件。

这里打开看看

就可以看到PlayerHealth和 Movement了,我的思路是修改人物无敌,和跳跃限制,一路飞过去就好。

中间一大块全部删掉就好,都没有死亡判定了,不是无敌是什么。

右键编辑类: 全部选中删掉,然后点击编译

先保存一下模块,再调试一下,看看成功没,进入游戏可以看到我们已经是无敌状态了,成功了

在PlayerMovement这里就可以看到一些关于跳跃能力之类的移动常量。一一修改后发现,进入游戏依旧是没有用,那么就思考一下,是不是哪里被限制住了?

往下面看一看代码;

看到一个MidAirMovement,翻译过来是空中运动。往下看可以发现:

这里对跳跃时间做了限制,即停留在空中的时间,也一样把限制删掉;

然后保存模块调试一下:可以看到已经可以在空中飞了,接下来通关就好了。

还有一种逆向思路应该是通过加密算法的,好像有个RC4,但是我没有尝试,感兴趣的钻研看看

IDA动态调试

感觉很简单的一道题,怎么第二波才放出来了,而且好像nssctf没什么人打一样,解的人也不多。

打开后随便下个断点;

在这里走完,f9一下,v2就是了

Easy SMC

ELF文件,64bit,是SMC的话动调,要用到remote linux debugger

 远程调试的方法网上很多,随便搜一搜关键字就有【

这里就不讲了,先将文件复制到linux工作台,并将linux上的服务打开,

下个断点,准备调试:

随便输入一下flag;

成功断下来了;

之后一直单步,直到进入这个GetNextNumber函数

单步走几步看看

出来了,这里选中no。选中endbr64,用U未定义一下;

之后选中所有数据一直到最底下的retn处

用C转化为代码,这里要选中Forcce

🆗了,这里就是全提出来,然后写个exp就好了

v2 = [78, 82, 81, 64, 80, 65, 117, 97, 43, 44, 79, 37, 106, 92, 52, 93, 49, 101, 58, 34, 75, 28, 88, 93, 27, 89, 75, 26, 88, 76, 80, 72, 63, 82, 17, 14, 66, 58, 71, 9, 60, 8, 60, 78, 51, 54, 2, 53, 3, 46, -1, 5, 35, 30, 18, 13, 30, -6, 59, -4, 51, 6, 22, 62]

v2 = [chr(v2[i] + i) for i in range(len(v2))]

result = ''.join(v2)
print(result)

# NSSCTF{h35Y0viBlAvL5_1nt3re5ting_s31f_m0d1fy_c0d3_18WSHDV3u7oCT}

Redirect

没难度的题目,aaa为什么没人写

from Crypto.Cipher import ARC4
arr = [ 0x4F, 0x11, 0x28, 0x6A, 0x51, 0x8C, 0x30, 0xA1, 0x1D, 0xAD, 0xA3, 0x73, 0xE9, 0x79, 0xDE, 0x78
        , 0x2F, 0xB3, 0x1D, 0x10, 0x18, 0x50, 0x6E, 0x68, 0x6A, 0x20, 0x5A, 0x51, 0x82, 0x82, 0x9C, 0xDB
        , 0xE1, 0xA7, 0xEE, 0xA4, 0x4C, 0xD3, 0x0B, 0x68, 0xE6, 0xD8, 0x2B, 0x6C, 0xDF, 0x76, 0xE3, 0x1B
        , 0x52, 0x89, 0xCE, 0x4B, 0x47, 0x4F, 0x42, 0x83, 0x72, 0x9B, 0xB6, 0x94, 0x19, 0x32, 0x85, 0xE1]
arrBytes = bytes(arr)
key = b"nSsCtf2023"
enc = ARC4.new(key)
flag = enc.decrypt(arrBytes)
print(flag)

# NSSCTF{S3HrpMjdDMO_r3direct_1nput_t0_4n_ennpty_fi13_aUMkzemgoJB}

就是一个RC4,连混淆遮掩都没有,就甩脸上了..

Funny CSharp

尝试过反编译exe了,没有什么可以看的信息;

用dnSpy反编译 .dll文件看看

在很明显的地方就看到了:
 

data = [116, 94, 80, 127, 49, 71, 101, 106, 115, 97, 57, 83, 94, 109, 58, 98,
        75, 86, 40, 100, 61, 123, 110, 57, 123, 89, 86, 121, 123, 104, 97, 60,
        86, 74, 86, 112, 103, 103, 124, 111, 86, 99, 107, 56, 93, 71, 96, 106,
        69, 49, 112, 59, 103, 124, 90, 65, 71, 114, 79, 93, 74, 90, 90, 71]

result = [chr(byte ^ 0x09) for byte in data][::-1]
print("".join(result))

# NSSCTF{NHSun2y8LciNT1bj_funny_C_5harp_Pr0gr4m!_Bk3dWZ0hzclN8vYW}

异或9后再逆序一下,iu🆗了

就到这里了,还差一题SeeingSharp/(ㄒoㄒ)/~~ 还没有思路,博主也是刚学,坐等官方wp了

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sciurdae.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值