Fork me on GitHub

一道Rust逆向Writeup

A Rust Reverse Writeup

在CTF竞赛中,为了考察参选手的快速学习能力,不时会采用非常见语言程序来出题。当然这类问题一般都有如下特点:

  • 不会太复杂
  • 即使没有相关知识,根据提示通过搜索引擎也能获取必要的解体信息

今日刷到的这道Reverse题,亦是如此。

题目描述

A babyrust to become a hardcore reverser.

出题人都说“硬核”,自然对新人不太友好,解题花了不少时间。

解体步骤

了解Rust

首先搜索一下Rust,了解到“Rust是一门系统编程语言,专注于安全,尤其是并发安全,支持函数式和命令式以及泛型等编程范式的多范式语言”,当然从汇编层面来说,Rust会在程序中插入大量与程序逻辑无关的代码,所以对逆向解题还是容易造成一定干扰的。
时间充足的情况下可以写个Hello World Rust体验下,也可以把编译好的二进制文件拖到IDA Pro里观察下。然后就会发现题目给的附件应该就是rust编译后的二进制文件。

hello_world.rs

1
2
3
4
fn main() {
let s = "hello world, Rust!";
println!("{}", s);
}

编译运行rust程序

1
2
3
[/Users/test]rustc hello_world.rs
[/Users/test]./hello_world
Hello world, Rust!

那么,就不需要花更多精力去了解Rust语法了, 直接针对二进制文件还是分析。

逆向分析文件

(1)先把附件中的二进制文件拖到IDA Pro中分析,会有一个报错提示,但可忽略,继续等IDA Pro软件分析。


reverse_rust1
reverse_rust2

(2)文件分析完成后,IDA Pro会自动跳转到main函数。


reverse_rust3

由图可知main函数功能比较少。

_ZN15beginer_reverse4main17h80fa15281f646bc1E,这个main函数看起来逻辑很复杂,实际上真正有用的部分也在这里面。

(3)在IDA Pro中按F5,显示pesudocode。在line 220发现了移位和异或运算,这在普通代码中不常见。

reverse_rust4

(4)根据上面的代码找到变量v33,是一个数组,重点看v0的赋值。


reverse_rust5

由编码可知,line 54是在汇编指令里面写的,line46-53这部的赋值可能是被申明为了全局变量。

双击看v0赋值:

reverse_rust6

(5)解析flag
然后再回来看关键代码

1
2
3
4
5
6
7
8
9
10
do
{
if ( v15 == v22 )
break;
v25 = ((*((_DWORD *)v30 + v23) >> 2) ^ 0xA) == *(_DWORD *)&v15[4 * v23];
// if we set a breakpoint here, v15 is the input but is unsigned extended to DWORD array
++v23;
v24 += v25;
v22 -= 4;
}

这段被加密过的字符串解密方式为(data[i] >> 2) ^ 0xA(即是每4个字节向右移2位再与A进行异或),data是uint32_t类型的数组,解密之后的字符串即为flag,然后拿来和自己输入的字符串作比较。

如果是熟练使用gdb,可以直接加断点操作。

1
2
3
4
5
6
Python>flag = ""
Python>for p in range(0x51000, 0x51080, 4) + range(0x6722, 0x672a, 4):
Python> flag += chr((Dword(p) >> 2) ^0xA)
Python>
Python>flag
INS{y0ur_a_r3a1_h4rdc0r3_r3v3rs3r}

如果不熟悉gdb,可以就用IDA Pro来处理,打开”File”-“Script command…”,按红框操作,然后粘贴此代码并运行,即可获得flag。

1
2
3
4
flag = ""
for p in range(0x51000, 0x51080, 4) + range(0x6722, 0x672a, 4):
flag += chr((Dword(p) >> 2) ^0xA)
print(flag)


reverse_rust7

题目附件

总结

后来查询了一下,这道题是Insomni’hack teaser 2019中的一道逆向题,这个组织出得题还是有一定难度的。同时我也参考了下网上认真写过writeup的CTFer的评价,有人觉得题目难度适中,也有觉得挺简单的。但对于刚开始接触Reverse的我来说,果然还是感到苦手,又一次从侧面证明了刷题练级的重要性。

参考链接

-------------  Fin    Thanks for reading!  -------------

本文标题:一道Rust逆向Writeup

文章作者:TesterCC

发布时间:2019年12月13日 - 21:12

最后更新:2020年07月07日 - 21:07

原始链接:http://blog.fullstackpentest.com/a-rust-reverse-writeup.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。