rust逆向初探初探初探

 Starctf有一道SIMPLEX-WMM,和rust有关,看了两天wp没看出来,我真是操了。于是,无情的博客搬运机器,又来了。题目链接如下:链接

 Rust的配置与安装见链接1

0x00 beginner:属于菜鸟的rust

image-20230905110015442

 一般lea rcx, xxx中的xxx就是main函数。进入主函数中,一般看不出来啥,这是因为编译器自己加了点东西,如下所示:

image-20230905110233161

 用gdb调试一波。发现触发panic的函数一直向下调用到了read_line。如下所示:

image-20230905140246260

 发现此时输入的字符串在rsp+8的位置,转为代码后,可以发现是v28(这里有个疑问,rsp不是变化的吗?总之技能get)。如下所示:

image-20230905140644670

 并发现并未对v28做操作,如下所示:

image-20230905141221823

 继续向下分析,发现程序把输入中的每个char都变成了4字节。如下所示:

image-20230905143837578

 接下来,保证每一个字符都小于0x7F,如下所示:

image-20230905144408580

 之后,发现重点:

image-20230905144701554

result要等于22。最后写程序:

1
2
3
4
5
6
7
8
import idc
addr = 0x7FFFF7826000
flag = []
for i in range(0x22):
flag.append((idc.get_wide_dword(addr+4*i)>>2)^0xa)
for i in flag:
print(chr(i), end = "")
# INS{y0ur_a_r3a1_h4rdc0r3_r3v3rs3r}

0x01 checkin-rs

 找main函数,如下:

image-20230905152712996

 其中有几个比较重要的函数:

函数名 作用
std::thread::spawn::xxx 创建线程
std::thread::JoinHandle 将线程加入处理队列
std::sync::mpsc::Receiver 主线程接收子线程数据,mpsc是Multiple Producer Single Consumer,就是多个线程发送数据,然后单个线程接收数据

 继续分析,Receiver函数返回值v12,若此值为1,则输出正确,否则输出错误。

image-20230905164050033

 经过查询,Sender 或 SyncSender 用于向 Receiver 发送数据。所以查找Sender相关的函数,查找到:sync::mpsc::Sender$LT$T$GT$::send。查找其调用,发现sys_common::backtrace::__rust_begin_short_backtrace。分析此函数。

 如下所示,首先对输入进行翻转。

image-20230905175301544

 之后,对输入进行xor处理。

image-20230905182629815

 接下来,进行flag^i处理。

image-20230905182732017

 最后,经过bcmp比较。

image-20230905180435241

 重点在于,比较的值在哪里获得?这是在Sender的参数a1中。跟踪a1,发现调用此函数的是:/rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/thread/mod.rs

 最后,猜测在调用thread::spawn函数时,a1当作参数被传入此函数,如下所示:

image-20230905185840243

 经过分析,字符串存放位置如下:

image-20230905185939633

 最终,可写j脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
data1 = "7A7D79536279566E726824252223207D"
data3 = "7A68786E687F467B7F73767F7A7C4E62"
data2 = "R~[PE@]LF\\ZHI^"
data = []
for i in range(len(data1)//2)[::-1]:
d = data1[i*2:i*2+2]
d = int(d, 16)
data.append(d)
for i in range(len(data3)//2)[::-1]:
d = data3[i*2:i*2+2]
d = int(d, 16)
data.append(d)
for d in data2:
data.append(ord(d))
for i in range(len(data)):
i = len(data) - i - 1
print(chr(i^data[i]), end = "")
# secpunk{easy_reverse_checkin_rust_is_fun!!!!!}

0x02 rvm

 2022年鹏城杯,rust+vm。

 根据beginner题目中main函数的定位,sub_7C40函数是main函数。发现是while..switch..case..结构。可以动调。

 首先,经过分析,总共输入8次内容,每一次输入的代码结构为:

image-20230906102228730

 调了两天,没搞出来,但是看完了wp,也搞懂了。感觉主要是自己没集中精神看。

参考链接:

[1] https://wsxk.github.io/Rust%E9%80%86%E5%90%91%E5%88%9D%E6%8E%A2/

[2] https://www.cnblogs.com/Here-is-SG/p/17216822.html

[3] https://blog.fullstackpentest.com/a-rust-reverse-writeup.html

[4] https://www.xunflash.top/archives/rustvm.html

留言

© 2024 wd-z711

⬆︎TOP