第五章 Linux二进制分析
在提交第一题后,会生成第二题
$ ./oracle 84b34c124b2ba5ca224af8e33b077e9e
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| Level 1 completed, unlocked lvl2 |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
Run oracle with -h to show a hint
第二题:分析lvl2文件
$ file lvl2
lvl2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=457d7940f6a73d6505db1f022071ee7368b67ce9, stripped
$ ./lvl2
f6
binary@binary-VirtualBox:~/code/chapter5/second$ ./lvl2
4f
binary@binary-VirtualBox:~/code/chapter5/second$ ./lvl2
6c
binary@binary-VirtualBox:~/code/chapter5/second$ ./lvl2
6c
binary@binary-VirtualBox:~/code/chapter5/second$ ./lvl2
81
binary@binary-VirtualBox:~/code/chapter5/second$ ./lvl2
81
binary@binary-VirtualBox:~/code/chapter5/second$ ./lvl2
88
binary@binary-VirtualBox:~/code/chapter5/second$ ./lvl2
d3
多次执行lvl2,发现每次结果不一样
$ ltrace ./lvl2
__libc_start_main(0x400500, 1, 0x7ffda5435098, 0x400640 <unfinished ...>
time(0) = 1690701220
srand(0x64c60da4, 0x7ffda5435098, 0x7ffda54350a8, 0) = 0
rand(0x7fcac6f73620, 0x7ffda5434f7c, 0x7fcac6f730a4, 0x7fcac6f7311c) = 0x5e2391d
puts("6c"6c
) = 3
+++ exited (status 0) +++
发现lvl2调用了随机函数,想到可以利用LD_PRELOAD劫持rand函数,让其不再随机
编写unrandom.c如下:
int rand(){
return 0;
}
编写shell脚本如下:
#!/bin/bash
current_val=0
export LD_PRELOAD='./unrandom.so'
for ((i=1; i<=20; i++))
do
# 编译生成共享库
gcc -shared -fPIC unrandom.c -o unrandom.so
# 等待0.1s
sleep 1
# 执行lvl2程序
./lvl2
# 修改unrandom.c中rand函数的返回值为前一次的返回值加一
sed -i "s/return $current_val;/return $((current_val + 1));/" unrandom.c
# current_val加一
current_val=$((current_val + 1))
done
# 修改unrandom.c中rand函数的返回值为0
sed -i "s/return $current_val;/return 0;/" unrandom.c
运行go.sh,结果如下:
$ ./go.sh
03
4f
c4
f6
a5
36
f2
bf
74
f8
d6
d3
81
6c
df
88
03
4f
c4
f6
发现一共16个值,把前16个连起来得到flag=034fc4f6a536f2bf74f8d6d3816cdf88
$ ./oracle 034fc4f6a536f2bf74f8d6d3816cdf88
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| Level 2 completed, unlocked lvl3 |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
Run oracle with -h to show a hint
成功!
另外,这些字符串其实可以直接找到:
$ objdump -s --section .rodata lvl2
lvl2: file format elf64-x86-64
Contents of section .rodata:
4006c0 01000200 30330034 66006334 00663600 ....03.4f.c4.f6.
4006d0 61350033 36006632 00626600 37340066 a5.36.f2.bf.74.f
4006e0 38006436 00643300 38310036 63006466 8.d6.d3.81.6c.df
4006f0 00383800 .88.
放入ida pro,反编译反汇编后的代码如下:
查看对象s:
跳转到4006C4即可找到字符串内容