Analyse
既然题目名为easyrop,那么这道题的利用方法和rop脱不了太大干系,尝试运行
可能刚开始不知道这个程序是做什么的,但是貌似程序是将我们的输入当作路径来处理的,我们通过IDA静态分析看看
main函数
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__int64 v3; // rax
FILE *v5; // rdi
char v6[1032]; // [rsp+10h] [rbp-420h] BYREF
__int64 v7; // [rsp+418h] [rbp-18h]
char v8; // [rsp+427h] [rbp-9h]
__int64 v9; // [rsp+428h] [rbp-8h]
dword_6030A0 = 0;
sub_400FC4();
sub_401968();
fwrite(">> ", 1uLL, 3uLL, stdout);
fflush(stdout);
v9 = 0LL;
wh...
笔者的ubuntu18.04发生这个错误是因为同时安装了两个python3(python3.6和python3.8)
step1
删除python3.6
sudo apt-get remove python3.6
sudo apt-get remove --auto-remove python3.6
sudo apt-get purge python3.6
step2
删除python3-pip
sudo apt-get remove python3-pip
step3
重新安装python3-pip
sudo apt-get install python3-pip
此时运行pip3可能还是会报错
mykonos@DESKTOP-H37I3CV:~/pwndbg$ pip3
Traceback (most recent call last):
File "/usr/local/bin/pip3", line 7, in <module>
from pip._internal.cli.main import main
ModuleNotFoundError: N...
翻到以前的笔记,整理一下
堆
使用动态分配的内存
多线程与Arena
维护多个堆
chunk的结构
Bin的结构
内存分配流程
内存释放流程
堆
elf中的堆和算法提到的堆不是一个东西,elf中提到的堆是被分配到的一块内存区域,和栈的区别主要是在于堆内存是动态分配的。也就是说,程序可以从heap段请求一块内存,或者释放一块内存
堆内存是全局的,即在程序的任意位置都可以访问堆,并不一定是要在malloc那个函数里访问,因为C语言使用指针指向动态分配的内存。但相比访问栈上的静态局部变量,使用指针也会带来一定的开销
(从低地址 $$\rightarrow$$ 高地址)
使用动态分配的内存
GLibc采用ptmalloc2内存分配器管理堆内存,增加了对多线程的支持
mmap
用于创建私有的匿名映射段,主要是为了分配一块新的内存,且这块内存只有调用mmap的进程可以使用,所以为私有的,与之相反的操作是munmap(),删除一块内存区域上的映射
多线程与Arena
每个线程要维护一些独立的数据结构,并且对这些数据结构的访问是需要加锁的。在ptmalloc2中,每个线程拥有自己...
今天看到一道题,checksec的时候会检测出Canary,但是实际上栈上并没有canary的值,故还是可以栈溢,好奇怎么实现的
起初我是采用__attribute__((noreturn)),这个是GCC的一个属性,用于告诉编译器该函数不会返回到调用者,可以帮助编译器进行优化,并消除用于函数缺少返回语句而可能产生的警告
void __attribute__((noreturn)) __stack_chk_fail_local(void) {
}
我想着将__stack_chk_fail_local函数重定义为空,但是这样编译时会出错
(.text+0x0): multiple definition of `__stack_chk_fail_local'; /tmp/ccZi1uB3.o:test.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
于是我想着编译时--wrap来对__stack_chk_fail_local函数进行替换
gcc -s...
Analyse
文件分析
exe程序,可以通过exeinfo对其架构进行查看
可以看到程序为64位,检测出存在UPX加壳
解题
1. 脱壳
存在UPX加壳,尝试使用UPX脱壳工具,但是均未果
这道题采用了一些技巧防止直接脱壳,也是一个可以学习的知识点,具体可以看参考链接
使用010editor打开Re2.exe,观察发现
这里需要对UPX加壳后的数据特征有一定的了解。UPX在加壳时,会修改文件的结构,以便在运行时动态地解压原始的代码和数据。为实现这一点,UPX会在加壳后的文件中添加一些新的段。
UPX0:这个段包含了被压缩的原始数据,在文件中,这个段的大小通常是0,因为它只是一个占位符,当程序运行时,这个段会被解压到内存中
UPX1:这个段包含了被压缩的原始代码。和UPX0一样,它在文件中的大小也可能是0,但在程序运行时,这个段会被压到内存中
UPX2:(如果存在的话)这个段包含了UPX的解压缩代码。当加了壳的程序启动时,这段代码首先会被执行,以解压UPX0,UPX1的数据和代码
所以这里UPX脱壳失败的原因应该是将区段名UPX0,UPX1修改成了FUK0,F...
Handmake
Analyse
1. 查看文件类型
m1sceden4@DESKTOP-H37I3CV:/reverse/Handmake$ file challenge
challenge: ASCII text, with CRLF line terminators
发现是文本文件,cat一下
可以看到这是go代码,篇幅很长,共有15w行之多。将文件后缀改为.go,通过任意编辑器打开文件
2. 分析文件内容
这段go代码定义了很多很多函数,在不知道题目意思的情况下,大概可以感觉这些函数应该是起到混淆和加大逆向难度的作用
找到main函数,代码如下:
func main() {
var nFAzj, CuSkl string
jjxXf := []byte{
37, 73, 151, 135, 65, 58, 241, 90, 33, 86, 71, 41, 102, 241, 213, 234, 67, 144, 139, 20, ...