ELF x64 - Nanomites - Introduction_WP
ELF x64 - Nanomites - Introduction_WP
这是运用了Debug Blocker
技术的题目
又花了些时间,终于破解了
gdb 设置跟踪父进程还是子进程
set follow-fork-mode parrent|child
当发生fork时,指示调试器执行父进程还是子进程
ptrace
在程序执行到int3
时,就会触发 SIGTRAP
信号,
long ptrace(enum __ptrace_request request,
pid_t pid,
void *addr,
void *data);
参数data:作用则根据request的不同而变化,如果需要向目标进程中写入数据,data存放的是需要写入的数据;如果从目标进程中读数据,data将存放返回的数据
strace
可以先用strace来观察在系统调用strace -i ./ch28.bin
1 | [00007fa5f9b6bf4e] read(0, toto /输入值 |
当我输入值‘toto’,触发了两次 SIGTRAP,之后退出
反编译
直接IDA PRO反编译
其他的细节都不管,就看我们需要的
1 | int __fastcall sub_400871(__int64 input) |
子进程会执行 memcpy()h函数复制到dest
的代码,src == 0x601080
指向400ac0
,所以实际复制的是400ac0
处的指令。
RDI
保存着我们输入的数据,每次读取一个字节,存入al
,之后int3
,就会触发SIGTRAP,父进程进行调试子进程。
1 | __int64 __fastcall sub_400736(__int64 dest, unsigned int pid) |
ptrace(PTRACE_GETREGS, pid, 0LL, &v3)
获取所有子进程寄存器值,存放在V3地址处。
if ( seg_6010A0[3 * i + 1 + i % 2] == v4 )
// v4 == input 表示输入值放在子进程r9中 0x7fffffffdc50
这条语句就是我们需要的,其将我们的输入值与6010A0
处的值进行比较,如果相等,则修改V6,也就是EFLAGS,将ZF置1
,JNE不跳转
,如果跳转了直接结束进程。
ptrace(PTRACE_SETREGS, pid, 0LL, &v3)
将修改后的寄存器值重新赋给子进程
从if
知道,比较共进行13次,下面编写python脚本
1 | data=[] |
ch28.txt保存6010A0
开始的数据。
make -n 显示命令,但不执行
大佬代码
1 | import gdb |
论文 想法
云攻击
让VM支持去重,然后flush+reload
建立cpu cache的随机策略
映射