OpenSecurityTraining2 Learning Paths: Vulnerability Hunting & Exploitation
python:https://www.learnpython.org/
路径图:https://ost2.fyi/OST2_LP_Vulns_Exploits.pdf
Debuggers 1012:Introductory GDB(与 python ) --> Architecture 1001:x86-64 Assembly --> Reverse Engineering 3201:Symbolic Analysis
Download & Install
设置 Ubuntu 系统
VMWare Workstation Player 16: x86-64 Ubuntu 20.04 VM
https://www.youtube.com/watch?v=wGL-IFr-8Is
https://ubuntu.com/download/desktop
VirtualBox 6.1: x86-64 Ubuntu 20.04 VM
https://apps.p.ost2.fyi/learning/course/course-v1:OpenSecurityTraining2+Lab_Setup_x86-64_Ubuntu+2021_v1/home
安装 gcc 和 gdb
sudo apt-get install -y gcc gdb
gcc –v
gdb –version
Create Test Executable
Compiling Test Programs fibber.c and echo.c
将以下代码复制并粘贴到名为 fibber.c 文件中
// fibber.c: A simple recursive Fibbonacci sequence calculation program
#include <stdio.h>
unsigned int fibbonacci(unsigned int n){
if(n <= 1){
return n;
}
else{
return (fibbonacci(n-1) + fibbonacci(n-2));
}
}
int main(){
unsigned int n = 10;
printf("First %d elements of the Fibbonacci sequence: ", n);
for(unsigned int i = 0; i < n; i++){
printf("%d ", fibbonacci(i));
}
printf("\n");
return 0;
}
编译它
gcc -ggdb fibber.c -o fibber_bin # -ggdb 将GDB debugging symbols添加到二进制文件中
通过运行“./fibber_bin”(不带引号)确认其已执行。
复制并粘贴以下代码到名为 echo.c 的文件中
// echo.c: A simple program to take input on the command line and echo it back out
#include <stdio.h>
void main(int argc, char ** argv){
if(argv[1] != NULL && argv[1] != ""){
printf("You entered %s for argv[1]\n", argv[1]);
} else {
printf("You didn't enter an argv[1]\n");
}
}
Compile it with:
gcc -ggdb echo.c -o echo_bin
通过运行“./echo_bin yo”(不带引号)确认其执行。
Loading Binaries
Loading a Binary from Disk
从文件系统加载二进制文件:选项 1
user@ubuntu:~$ gdb --quiet ./fibber_bin
Reading symbols from ./fibber_bin...
(No debugging symbols found in ./fibber_bin)
(gdb)
--quiet is equivalent to -q
从文件系统加载二进制文件:选项 2
user@ubuntu:~$ gdb -q
(gdb) file ./fibber_bin
Reading symbols from ./fibber_bin...
(No debugging symbols found in ./fibber_bin)
(gdb)
退出 GDB
user@ubuntu:~$ gdb -q
(gdb) quit
user@ubuntu:~$
Starting, Stopping, Restarting Binaries
Commands: run, start, continue
运行(或重新运行)程序
run(简称:r)命令将运行程序
https://www.sourceware.org/gdb/current/onlinedocs/gdb
https://web.archive.org/web/20221209001604/http://www.sourceware.org/gdb/current/onlinedocs/gdb/Starting.html#Starting
运行需要 CLI 参数的程序
如果您的程序需要 CLI 参数,则可以在运行命令后传递它们,就像您直接调用程序一样。
比如:./echo_bin yo
user@ubuntu:~$ gdb ./echo_bin -q
Reading symbols from ./echo_bin...
(gdb) r
Starting program: /home/user/echo_bin
You didn't enter an argv[1]
[Inferior 1 (process 60868) exited with code 034]
(gdb) r hi
Starting program: /home/user/echo_bin hi
You entered hi for argv[1]
[Inferior 1 (process 60872) exited with code 033]
(gdb) r yo
Starting program: /home/user/echo_bin yo
You entered yo for argv[1]
[Inferior 1 (process 60873) exited with code 033]
启动程序并在其入口点中断
start 命令类似于 run,只不过它在程序的入口点设置断点。(后面的二进制课程将教你如何自己找到入口点。)
user@ubuntu:~$ gdb ./fibber_bin -q
Reading symbols from ./fibber_bin...
(gdb) start
Temporary breakpoint 1 at 0x1189
Starting program: /home/user/fibber_bin
Temporary breakpoint 1, 0x0000555555555189 in main ()
(gdb)
与运行类似,您可以在启动命令后指定其他 CLI 参数:
user@ubuntu:~$ gdb ./echo_bin -q
Reading symbols from ./echo_bin...
(No debugging symbols found in ./echo_bin)
(gdb) start hi
Temporary breakpoint 1 at 0x1169
Starting program: /home/user/echo_bin hi
Temporary breakpoint 1, 0x0000555555555169 in main ()
(gdb)
继续执行在断点处停止的程序
如果你使用 start 启动了程序,那么可以使用 continue(缩写:c)从程序设置的临时断点继续执行。
user@ubuntu:~$ gdb ./echo_bin -q
Reading symbols from ./echo_bin...
(gdb) start hi
Temporary breakpoint 1 at 0x1169
Starting program: /home/user/echo_bin hi
Temporary breakpoint 1, 0x0000555555555169 in main ()
(gdb) c
Continuing.
You entered hi for argv[1]
[Inferior 1 (process 60985) exited with code 033]
(gdb)
Working with Breakpoints in Source & Assembly Debugging
Code Breakpoints: Setting, Listing, and Deleting
设置代码断点:
可以使用 break 命令(缩写:b)设置断点。
(gdb) break main
Breakpoint 1 at 0x11a9
(gdb) b fibbonacci
Breakpoint 2 at 0x1169
列出代码断点:
可以使用 info breakpoints 或更短的形式 info break 和 info b 列出断点
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000011a9 <main>
2 breakpoint keep y 0x0000000000001169 <fibbonacci>
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000011a9 <main>
2 breakpoint keep y 0x0000000000001169 <fibbonacci>
取消设置代码断点:
clear <address>
命令可以删除地址处的断点,该地址由符号名称或 * 后跟绝对内存地址指定。
(gdb) clear *0x00000000000011a9
(gdb) info b
Deleted breakpoint 1 Num Type Disp Enb Address What
2 breakpoint keep y 0x0000000000001169 <fibbonacci>
(gdb) clear fibbonacci
(gdb) info b
Deleted breakpoint 2 No breakpoints or watchpoints.
delete <breakpoint number from info breakpoints>
(缩写:d)将删除“info b”输出中指定的编号所给出的特定断点。
(gdb) b main
Breakpoint 3 at 0x11a9
(gdb) info b
Num Type Disp Enb Address What
3 breakpoint keep y 0x00000000000011a9 <main>
(gdb) delete 3
(gdb) info b
No breakpoints or watchpoints.
Breakpoints as offets vs. addresses in memory 断点作为偏移量 VS 内存中的地址
请注意,当断点最初打印出来时,它们是较小的数字。但是当程序启动并再次打印出来时,它们是较大的数字。这是因为在程序运行之前,“地址”实际上只是可执行文件代码执行开始处的偏移量。调试器还不知道程序将在内存中的哪个位置加载,直到它实际执行。这也是因为操作系统可能会随机化可执行文件在内存中的加载位置(一种称为地址空间布局随机化 (ASLR) 的机制,旨在帮助缓解一些安全漏洞。)因此,在可执行文件启动后,调试器现在可以显示可执行文件在内存中加载并启动后的真实地址。(注意:如果您执行相同的步骤,您的地址通常会与下面显示的不同。)
sec875@ubuntu:~$ gdb ./fibber_bin -q
Reading symbols from ./fibber_bin...
(gdb) b main
Breakpoint 1 at 0x11a9: file fibber.c, line 13.
(gdb) break fibbonacci
Breakpoint 2 at 0x1169: file fibber.c, line 4.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000011a9 in main at fibber.c:13
2 breakpoint keep y 0x0000000000001169 in fibbonacci at fibber.c:4
(gdb) r
Starting program: /home/sec875/fibber_bin
Breakpoint 1, main () at fibber.c:13
13 int main(){
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00005555555551a9 in main at fibber.c:13
breakpoint already hit 1 time
2 breakpoint keep y 0x0000555555555169 in fibbonacci at fibber.c:4
(gdb) delete 2
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00005555555551a9 in main at fibber.c:13
breakpoint already hit 1 time
(gdb) clear *0x00005555555551a9
(gdb) info b
Deleted breakpoint 1 No breakpoints or watchpoints.
(gdb) b main
Breakpoint 3 at 0x5555555551a9: file fibber.c, line 13.
(gdb) delete 3
(gdb) info b
No breakpoints or watchpoints.
(gdb) quit
A debugging session is active.
Inferior 1 [process 6761] will be killed.
Quit anyway? (y or n) y
sec875@ubuntu:~$
检查符号表:https://sourceware.org/gdb/current/onlinedocs/gdb.html/Symbols.html#Symbols
查询程序中定义的符号(变量、函数和类型的名称)。此信息是程序文本中固有的,不会随着程序的执行而改变。GDB 会在程序的符号表、启动 GDB 时指定的文件中(请参阅选择文件)或文件管理命令之一(请参阅指定文件的命令)中找到它。
sec875@ubuntu:~$ gdb ./fibber_bin1 -q
Reading symbols from ./fibber_bin1...
(No debugging symbols found in ./fibber_bin1)
(gdb) p 'main'
$1 = {<text variable, no debug info>} 0x11a9 <main>
(gdb) p 'fibbonacci'
$2 = {<text variable, no debug info>} 0x1169 <fibbonacci>
(gdb) info address main
Symbol "main" is at 0x11a9 in a file compiled without debugging.
(gdb) info address fibbonacci
Symbol "fibbonacci" is at 0x1169 in a file compiled without debugging.
(gdb) b main
Breakpoint 1 at 0x11a9
(gdb) b fibbonacci
Breakpoint 2 at 0x1169
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000011a9 <main>
2 breakpoint keep y 0x0000000000001169 <fibbonacci>
(gdb) info symbol 0x11a9
main in section .text
(gdb) info symbol 0x1169
fibbonacci in section .text
(gdb)
无符号(fibber_bin1)与有符号(fibber_bin)
gcc -ggdb fibber.c -o fibber_bin # -ggdb 将GDB debugging symbols添加到二进制文件中
sec875@ubuntu:~$ gdb ./fibber_bin1 -q
Reading symbols from ./fibber_bin1...
(No debugging symbols found in ./fibber_bin1)
(gdb) p './fibber.c'::main
No symbol table is loaded. Use the "file" command.
(gdb) p 'fibber.c'::main
No symbol table is loaded. Use the "file" command.
(gdb) file fibber.bin1
fibber.bin1: No such file or directory.
(gdb) file fibber.c
"/home/sec875/fibber.c": not in executable format: file format not recognized
(gdb) file fibber_bin1
Reading symbols from fibber_bin1...
(No debugging symbols found in fibber_bin1)
(gdb) q
sec875@ubuntu:~$ gdb ./fibber_bin -q
Reading symbols from ./fibber_bin...
(gdb) p 'fibber.c'::main
$1 = {int ()} 0x11a9 <main>
(gdb) p 'fibber.c'::return
No symbol "return" in specified context.
(gdb) p 'fibber.c'::fibbonacci
$2 = {unsigned int (unsigned int)} 0x1169 <fibbonacci>
(gdb) b main
Breakpoint 1 at 0x11a9: file fibber.c, line 13.
(gdb) c
The program is not being run.
(gdb) r
Starting program: /home/sec875/fibber_bin
Breakpoint 1, main () at fibber.c:13
13 int main(){
(gdb) p 'fibber.c'::main
$3 = {int ()} 0x5555555551a9 <main>
(gdb)