第五章 Linux二进制分析
第一题:分析payload文件
$ file payload
payload: ASCII text
$ head payload
H4sIABzY61gAA+xaD3RTVZq/Sf+lFJIof1r+2aenKKh0klJKi4MmJaUvWrTSFlgR0jRN20iadpKX
UljXgROKjbUOKuOfWWfFnTlzZs/ZXTln9nTRcTHYERhnZ5c/R2RGV1lFTAFH/DNYoZD9vvvubd57
bcBl1ln3bL6e9Hvf9+733e/+v+/en0dqId80WYAWLVqI3LpooUXJgUpKFy6yEOsCy6KSRQtLLQsW
EExdWkIEyzceGVA4JLmDgkCaA92XTXel9/9H6ftVNcv0Ot2orCe3E5RiJhuVbUw/fH3SxkbKSS78
v47MJtkgZynS2YhNxYeZa84NLF0G/DLhV66X5XK9TcVnsXSc6xQ8S1UCm4o/M5moOCHCqB3Geny2
rD0+u1HFD7I4junVdnpmN8zshll6zglPr1eXL5P96pm+npWLcwdL51CkR6r9UGrGZ8O1zN+1NhUv
ZelKNXb3gl02+fpkZnwFyy9VvQgsfs55O3zH72sqK/2Ov3m+3xcId8/vLi+bX1ZaHOooLqExmVna
6rsbaHpejwKLeQqR+wC+n/ePA3n/duKu2kNvL175+MxD7z75W8GC76aSZLv1xgSdkGnLRV0+/KbD
7+UPnnhwadWbZ459b/Wsl/o/NZ468olxo3P9wOXK3Qe/a8fRmwhvcTVdl0J/UDe+nzMp9M4U+n9J
oX8jhT5HP77+ZIr0JWT8+NvI+OnvTpG+NoV/Qwr9Vyn0b6bQkxTl+ixF+p+m0N+qx743k+wWGlX6
# 从上述结果可以看出该文件为base64加密过的
$ base64 -d payload > decode_payload
$ file decode_payload
decode_payload: gzip compressed data, last modified: Mon Apr 10 19:08:12 2017, from Unix
# 该文件是被压缩文件,尝试用tar解压
$ tar xvzf decode_payload
ctf
67b8601
目前得到两个文件,ctf和67b8601,首先分析ctf
$ file ctf
ctf: 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]=29aeb60bcee44b50d1db3a56911bd1de93cd2030, stripped
$ ./ctf
./ctf: error while loading shared libraries: lib5ae9b7f.so: cannot open shared object file: No such file or directory
$ ldd ./ctf
linux-vdso.so.1 => (0x00007ffdc0bb9000)
lib5ae9b7f.so => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f355e381000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f355e16b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f355dda1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f355da98000)
/lib64/ld-linux-x86-64.so.2 (0x00007f355e703000)
目前可以确定ctf为可执行文件,但是缺少库lib5ae9b7f.so无法执行
$ file 67b8601
67b8601: PC bitmap, Windows 3.x format, 512 x 512 x 24
$ head 67b8601
# 中间有如下内容:
__gmon_start___init_fini_ITM_deregisterTMCloneTable_ITM_registerTMCloneTable__cxa_finalize_Jv_RegisterClasses_ZSt19__throw_logic_errorPKc_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_createERmmmemcpy__stack_chk_fail_Z11rc4_encryptP11rc4_state_tPhi_Z11rc4_encryptP11rc4_state_tRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmalloc_Z11rc4_decryptP11rc4_state_tPhi_Z11rc4_decryptP11rc4_state_tRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE_Z6ui4_ini@�t)Lq��X�@te_tPhilibstdc++.so.6libc.so.6_edata__bss_start_endGLIBC_2.14GLIBC_2.4GLIBC_2.2.5GLIBCXX_3.4GLIBCXX_3.4.21
$ xxd 67b8601 | head
00000000: 424d 3800 0c00 0000 0000 3600 0000 2800 BM8.......6...(.
00000010: 0000 0002 0000 0002 0000 0100 1800 0000 ................
00000020: 0000 0200 0c00 c01e 0000 c01e 0000 0000 ................
00000030: 0000 0000 7f45 4c46 0201 0100 0000 0000 .....ELF........
00000040: 0000 0000 0300 3e00 0100 0000 7009 0000 ......>.....p...
00000050: 0000 0000 4000 0000 0000 0000 7821 0000 ....@.......x!..
00000060: 0000 0000 0000 0000 4000 3800 0700 4000 ........@.8...@.
00000070: 1b00 1a00 0100 0000 0500 0000 0000 0000 ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000090: 0000 0000 f40e 0000 0000 0000 f40e 0000 ................
# 说明67b8601也是一个可执行文件
# 提取其中的ELF头部
# 可以看到是从0x34开始的,即52,提取64个字节
$ dd skip=52 count=64 if=67b8601 of=file_head bs=1
64+0 records in
64+0 records out
64 bytes copied, 0.0040406 s, 15.8 kB/s
$ readelf -h file_head
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x970
Start of program headers: 64 (bytes into file)
Start of section headers: 8568 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 7
Size of section headers: 64 (bytes)
Number of section headers: 27
Section header string table index: 26
# 文件共有27个节,每个节有64字节,共计1728个字节,节头开始于8568字节处,故文件大小为10296比特
$ dd skip=52 count=10296 if=67b8601 of=newfile bs=1
10296+0 records in
10296+0 records out
10296 bytes (10 kB, 10 KiB) copied, 0.0511744 s, 201 kB/s
$ file newfile
newfile: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5279389c64af3477ccfdf6d3293e404fd9933817, stripped
# 可以看出该文件是一个动态链接库文件
# 考虑到ctf文件缺少动态链接库lib5ae9b7f.so,怀疑即为该文件
$ mv newfile lib5ae9b7f.so
$ export LD_LIBRARY_PATH=`pwd`
$ ./ctf
$ echo $?
1
通过上述的操作,ctf成功执行,但是错误返回,需要进一步逆向
放入ida pro后,main函数部分如下:
if ( a1 <= 1 )
{
if ( dword_6020B4 )
__printf_chk(1LL, "DEBUG: argv[1] = %s", a2[1]);
LABEL_3:
v4 = 1;
goto LABEL_4;
}
v3 = a2[1];
__printf_chk(1LL, "checking '%s'\n", v3);
if ( strcmp(v3, "show_me_the_flag") )
goto LABEL_3;
意味着需要函数执行时添加参数show_me_the_flag
$ ./ctf show_me_the_flag
checking 'show_me_the_flag'
ok
还是得不到flag,进一步分析
如图,输出ok后,程序从&unk_40117B获取了name,并对其进行了解密,从63行来看,name是一个环境变量,如果没有设置,程序则会返回。之后,由从&unk_401183获取了v19,同样进行了解密,最后判断了v6和v19是否相等。
接下来,使用gdb进行动态分析,定位到63行对应的汇编代码为mov rdi, [rsp+218h+name]
,执行这步后进行系统调用call _getenv
,因此在这一步设置断点。
gdb-peda$ file ctf
Reading symbols from ctf...(no debugging symbols found)...done.
gdb-peda$ export LD_LIBRARY_PATH=`pwd`
Undefined command: "export". Try "help".
gdb-peda$ set env LD_LIBRARY_PATH=`pwd`
gdb-peda$ b 0x400D07
[----------------------------------registers-----------------------------------]
RAX: 0x7fffffffde40 --> 0x454d5353455547 ('GUESSME')
RBX: 0x7fffffffe3a5 ("show_me_the_flag")
RCX: 0x454d5353 ('SSME')
RDX: 0x7
RSI: 0x53455547 ('GUES')
RDI: 0x7fffffffde40 --> 0x454d5353455547 ('GUESSME')
可以知道,环境变量的名称为GUESSME。进一步需要知道应该设置的值是多少。
前面图中的69行对比了获取到的环境变量内容和需要的内容,其对应的汇编代码如下:
.text:0000000000400DA2 48 8D 84 24 90 00 00 00 lea rax, [rsp+218h+var_188]
.text:0000000000400DAA 48 39 C7 cmp rdi, rax
.text:0000000000400DAD 74 05 jz short loc_400DB4
.text:0000000000400DAD
因此,在gdb中调试,添加环境变量GUESSME后在0x400DAA处设置断点,结果如下
[----------------------------------registers-----------------------------------]
RAX: 0x7fffffffde40 --> 0x15
RBX: 0x7fffffffefa7 --> 0x5f434c0064636261 ('abcd')
RCX: 0x0
RDX: 0x15
RSI: 0x6150a0 ("Crackers Don't Matter")
RDI: 0x6150a0 ("Crackers Don't Matter")
因此,环境变量GUESSME=”Crackers Don’t Matter”
$ export GUESSME="Crackers Don't Matter"
$ ./ctf show_me_the_flag
checking 'show_me_the_flag'
ok
flag = 84b34c124b2ba5ca224af8e33b077e9e
得到flag为84b34c124b2ba5ca224af8e33b077e9e。
补充:
在书中,作者使用了多种工具分析了该文件:
-
使用ldd查看文件的依赖情况:ldd -v [filename]
-
使用xxd查看文件字节内容(可以使用xxd工具的-c选项修改每行显示的字节数)
-
使用dd修改二进制文件
-
使用readelf分析文件
-
使用nm解析符号
作者对lib5ae9b7f.so文件进行了额外的分析
$ nm lib5ae9b7f.so nm: lib5ae9b7f.so: no symbols $ nm -D lib5ae9b7f.so 0000000000202058 B __bss_start w __cxa_finalize ...... 0000000000000c60 T _Z11rc4_decryptP11rc4_state_tPhi 0000000000000c70 T _Z11rc4_decryptP11rc4_state_tRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 0000000000000b40 T _Z11rc4_encryptP11rc4_state_tPhi 0000000000000bc0 T _Z11rc4_encryptP11rc4_state_tRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 0000000000000cb0 T _Z8rc4_initP11rc4_state_tPhi U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_createERmm U _ZSt19__throw_logic_errorPKc $ nm -D --demangle lib5ae9b7f.so 0000000000202058 B __bss_start w __cxa_finalize ...... 0000000000000c60 T rc4_decrypt(rc4_state_t*, unsigned char*, int) 0000000000000c70 T rc4_decrypt(rc4_state_t*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) 0000000000000b40 T rc4_encrypt(rc4_state_t*, unsigned char*, int) 0000000000000bc0 T rc4_encrypt(rc4_state_t*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) 0000000000000cb0 T rc4_init(rc4_state_t*, unsigned char*, int) U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long) U std::__throw_logic_error(char const*)
-
使用strings查看字符串
-
使用strace和ltrace跟踪系统调用和库文件调用
$ strace ./ctf show_me_the_flag $ ltrace -i -C ./ctf show_me_the_flag # 书中在这里通过ltrace的结果知道了环境变量名为GUESSME
-
使用objdump检查指令集的行为
# 输出.rodta节的内容 $ objdump -s --section .rodata ctf # 反编译ctf $ objdump -d ctf