mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-25 11:41:16 +07:00
update peda
This commit is contained in:
parent
6b41f36a7f
commit
9298ad049d
@ -53,7 +53,7 @@
|
||||
- [5.2 Pin 动态二进制插桩](doc/5.2_pin.md)
|
||||
- [5.3 angr 二进制自动化分析](doc/5.3_angr.md)
|
||||
- [5.4 反调试技术](doc/5.4_antidbg.md)
|
||||
- [5.5 Symbolic Execution 符号执行技术](doc/5.5_symbolic.md)
|
||||
- [5.5 符号执行](doc/5.5_symbolic.md)
|
||||
- [5.6 LLVM](doc/5.6_llvm.md)
|
||||
|
||||
- [六、附录](doc/6_appendix.md)
|
||||
|
@ -50,7 +50,7 @@
|
||||
* [5.2 Pin 动态二进制插桩](doc/5.2_pin.md)
|
||||
* [5.3 angr 二进制自动化分析](doc/5.3_angr.md)
|
||||
* [5.4 反调试技术](doc/5.4_antidbg.md)
|
||||
* [5.5 Symbolic Execution 符号执行](doc/5.5_symbolic.md)
|
||||
* [5.5 符号执行](doc/5.5_symbolic.md)
|
||||
* [5.6 LLVM](doc/5.6_llvm.md)
|
||||
* [六、附录](doc/6_appendix.md)
|
||||
* [6.1 更多 Linux 工具](doc/6.1_Linuxtools.md)
|
||||
|
@ -203,6 +203,13 @@ long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
|
||||
PEDA(Python Exploit Development Assistance for GDB)是一个强大的 gdb 插件。它提供了高亮显示反汇编代码、寄存器、内存信息等人性化的功能。同时,PEDA 还有一些实用的新命令,比如 checksec 可以查看程序开启了哪些安全机制等等。
|
||||
|
||||
#### 安装
|
||||
安装 peda 需要的软件包:
|
||||
```shell
|
||||
$ sudo apt-get install nasm micro-inetd
|
||||
$ sudo apt-get install libc6-dbg vim ssh
|
||||
```
|
||||
|
||||
安装 peda:
|
||||
```shell
|
||||
$ git clone https://github.com/longld/peda.git ~/peda
|
||||
$ echo "source ~/peda/peda.py" >> ~/.gdbinit
|
||||
@ -217,84 +224,347 @@ $ yaourt -S peda
|
||||
#### peda命令
|
||||
- **`aslr`** -- 显示/设置 gdb 的 ASLR
|
||||
- `asmsearch` -- Search for ASM instructions in memory
|
||||
- `asmsearch "int 0x80"`
|
||||
- `asmsearch "add esp, ?" libc`
|
||||
- `assemble` -- On the fly assemble and execute instructions using NASM
|
||||
- `assemble`
|
||||
- ```
|
||||
assemble $pc
|
||||
> mov al, 0xb
|
||||
> int 0x80
|
||||
> end
|
||||
```
|
||||
- **`checksec`** -- 检查二进制文件的安全选项
|
||||
- `cmpmem` -- Compare content of a memory region with a file
|
||||
- `cmpmem 0x08049000 0x0804a000 data.mem`
|
||||
- `context` -- Display various information of current execution context
|
||||
- `context_code` -- Display nearby disassembly at $PC of current execution context
|
||||
- `context_register` -- Display register information of current execution context
|
||||
- `context_stack` -- Display stack of current execution context
|
||||
- `context_code` -- Display nearby disassembly at $PC of current execution context
|
||||
- `context_register` -- Display register information of current execution context
|
||||
- `context_stack` -- Display stack of current execution context
|
||||
- `context reg`
|
||||
- `context code`
|
||||
- `context stack`
|
||||
- `crashdump` -- Display crashdump info and save to file
|
||||
- `deactive` -- Bypass a function by ignoring its execution (eg sleep/alarm)
|
||||
- `deactive setresuid`
|
||||
- `deactive chdir`
|
||||
- `distance` -- Calculate distance between two addresses
|
||||
- **`dumpargs`** -- 在调用指令停止时显示传递给函数的参数
|
||||
- `dumpmem` -- Dump content of a memory region to raw binary file
|
||||
- `dumpmem libc.mem libc`
|
||||
- **`dumprop`** -- 在特定的内存范围显示 ROP gadgets
|
||||
- `dumprop`
|
||||
- `dumprop binary "pop"`
|
||||
- `eflags` -- Display/set/clear/toggle value of eflags register
|
||||
- **`elfheader`** -- 获取正在调试的 ELF 文件的头信息
|
||||
- `elfheader`
|
||||
- `elfheader .got`
|
||||
- **`elfsymbol`** -- 从 ELF 文件中获取没有调试信息的符号信息
|
||||
- `elfsymbol`
|
||||
- `elfsymbol printf`
|
||||
- `gennop` -- Generate abitrary length NOP sled using given characters
|
||||
- `gennop 500`
|
||||
- `gennop 500 "\x90"`
|
||||
- `getfile` -- Get exec filename of current debugged process
|
||||
- `getpid` -- Get PID of current debugged process
|
||||
- `goto` -- Continue execution at an address
|
||||
- `help` -- Print the usage manual for PEDA commands
|
||||
- `hexdump` -- Display hex/ascii dump of data in memory
|
||||
- `hexdump $sp 64`
|
||||
- `hexdump $sp /20`
|
||||
- `hexprint` -- Display hexified of data in memory
|
||||
- `hexprint $sp 64`
|
||||
- `hexprint $sp /20`
|
||||
- `jmpcall` -- Search for JMP/CALL instructions in memory
|
||||
- `jmpcall`
|
||||
- `jmpcall eax`
|
||||
- `jmpcall esp libc`
|
||||
- `loadmem` -- Load contents of a raw binary file to memory
|
||||
- `loadmem stack.mem 0xbffdf000`
|
||||
- **`lookup`** -- 搜索属于内存范围的地址的所有地址/引用
|
||||
- `lookup address stack libc`
|
||||
- `lookup pointer stack ld-2`
|
||||
- `nearpc` -- Disassemble instructions nearby current PC or given address
|
||||
- `nearpc 20`
|
||||
- `nearpc 0x08048484`
|
||||
- `nextcall` -- Step until next 'call' instruction in specific memory range
|
||||
- `nextcall cpy`
|
||||
- `nextjmp` -- Step until next 'j*' instruction in specific memory range
|
||||
- `nextjmp`
|
||||
- `nxtest` -- Perform real NX test to see if it is enabled/supported by OS
|
||||
- **`patch`** -- 使用字符串/十六进制字符串/整形数
|
||||
- `patch $esp 0xdeadbeef`
|
||||
- `patch $eax "the long string"`
|
||||
- `patch (multiple lines)`
|
||||
- **`pattern`** -- 生成,搜索或写入循环 pattern 到内存
|
||||
- `pattern_arg` -- Set argument list with cyclic pattern
|
||||
- `pattern_create` -- Generate a cyclic pattern
|
||||
- `pattern_env` -- Set environment variable with a cyclic pattern
|
||||
- `pattern_offset` -- Search for offset of a value in cyclic pattern
|
||||
- `pattern_patch` -- Write a cyclic pattern to memory
|
||||
- `pattern_search` -- Search a cyclic pattern in registers and memory
|
||||
- `pattern_arg` -- Set argument list with cyclic pattern
|
||||
- `pattern_create` -- Generate a cyclic pattern
|
||||
- `pattern_env` -- Set environment variable with a cyclic pattern
|
||||
- `pattern_offset` -- Search for offset of a value in cyclic pattern
|
||||
- `pattern_patch` -- Write a cyclic pattern to memory
|
||||
- `pattern_search` -- Search a cyclic pattern in registers and memory
|
||||
- `pattern create 2000`
|
||||
- `pattern create 2000 input`
|
||||
- `pattern offset $pc`
|
||||
- `pattern search`
|
||||
- `pattern patch 0xdeadbeef 100`
|
||||
- `payload` -- Generate various type of ROP payload using ret2plt
|
||||
- `payload copybytes`
|
||||
- `payload copybytes target "/bin/sh"`
|
||||
- `payload copybytes 0x0804a010 offset`
|
||||
- `pdisass` -- Format output of gdb disassemble command with colors
|
||||
- `pdisass $pc /20`
|
||||
- `pltbreak` -- Set breakpoint at PLT functions match name regex
|
||||
- `pltbreak cpy`
|
||||
- **`procinfo`** -- 显示调试进程的 /proc/pid/
|
||||
- `procinfo`
|
||||
- `procinfo fd`
|
||||
- `profile` -- Simple profiling to count executed instructions in the program
|
||||
- `pyhelp` -- Wrapper for python built-in help
|
||||
- `pyhelp peda`
|
||||
- `pyhelp hex2str`
|
||||
- **`pshow`** -- 显示各种 PEDA 选项和其他设置
|
||||
- `pshow`
|
||||
- `pshow option context`
|
||||
- **`pset`** -- 设置各种 PEDA 选项和其他设置
|
||||
- `pset arg '"A"*200'`
|
||||
- `pset arg 'cyclic_pattern(200)'`
|
||||
- `pset env EGG 'cyclic_pattern(200)'`
|
||||
- `pset option context "code,stack"`
|
||||
- `pset option badchars "\r\n"`
|
||||
- **`readelf`** -- 获取 ELF 的文件头信息
|
||||
- `readelf libc .text`
|
||||
- `refsearch` -- Search for all references to a value in memory ranges
|
||||
- `refsearch "/bin/sh"`
|
||||
- `refsearch 0xdeadbeef`
|
||||
- `reload` -- Reload PEDA sources, keep current options untouch
|
||||
- **`ropgadget`** -- 获取二进制或库的常见 ROP gadgets
|
||||
- `ropgadget`
|
||||
- `ropgadget libc`
|
||||
- **`ropsearch`** -- 搜索内存中的 ROP gadgets
|
||||
- `ropsearch "pop eax"`
|
||||
- `ropsearch "xchg eax, esp" libc`
|
||||
- **`searchmem|find`** -- 搜索内存中的 pattern; 支持正则表达式搜索
|
||||
- `find "/bin/sh" libc`
|
||||
- `find 0xdeadbeef all`
|
||||
- `find "..\x04\x08" 0x08048000 0x08049000`
|
||||
- `searchmem` -- Search for a pattern in memory; support regex search
|
||||
- `session` -- Save/restore a working gdb session to file as a script
|
||||
- `set` -- Set various PEDA options and other settings
|
||||
- `set exec-wrapper ./exploit.py`
|
||||
- `sgrep` -- Search for full strings contain the given pattern
|
||||
- **`shellcode`** -- 生成或下载常见的 shellcode
|
||||
- `shellcode x86/linux exec`
|
||||
- `show` -- Show various PEDA options and other settings
|
||||
- **`skeleton`** -- 生成 python exploit 代码模板
|
||||
- `skeleton argv exploit.py`
|
||||
- `skipi` -- Skip execution of next count instructions
|
||||
- `snapshot` -- Save/restore process's snapshot to/from file
|
||||
- `snapshot save`
|
||||
- `snapshot restore`
|
||||
- `start` -- Start debugged program and stop at most convenient entry
|
||||
- `stepuntil` -- Step until a desired instruction in specific memory range
|
||||
- `stepuntil cmp`
|
||||
- `stepuntil xor`
|
||||
- `strings` -- Display printable strings in memory
|
||||
- `strings`
|
||||
- `strings binary 4`
|
||||
- `substr` -- Search for substrings of a given string/number in memory
|
||||
- `telescope` -- Display memory content at an address with smart dereferences
|
||||
- `telescope 40`
|
||||
- `telescope 0xb7d88000 40`
|
||||
- `tracecall` -- Trace function calls made by the program
|
||||
- `tracecall`
|
||||
- `tracecall "cpy,printf"`
|
||||
- `tracecall "-puts,fflush"`
|
||||
- `traceinst` -- Trace specific instructions executed by the program
|
||||
- `traceinst 20`
|
||||
- `traceinst "cmp,xor"`
|
||||
- `unptrace` -- Disable anti-ptrace detection
|
||||
- `unptrace`
|
||||
- `utils` -- Miscelaneous utilities from utils module
|
||||
- **`vmmap`** -- 在调试过程中获取段的虚拟映射地址范围
|
||||
- `cmmap`
|
||||
- `vmmap binary / libc`
|
||||
- `vmmap 0xb7d88000`
|
||||
- `waitfor` -- Try to attach to new forked process; mimic "attach -waitfor"
|
||||
- `waitfor`
|
||||
- `waitfor myprog -c`
|
||||
- `xinfo` -- Display detail information of address/registers
|
||||
- `xinfo register eax`
|
||||
- `xinfo 0xb7d88000`
|
||||
- **`xormem`** -- 用一个 key 来对一个内存区域执行 XOR 操作
|
||||
- `xormem 0x08049000 0x0804a000 “thekey”`
|
||||
- `xprint` -- Extra support to GDB's print command
|
||||
- `xrefs` -- Search for all call/data access references to a function/variable
|
||||
- `xuntil` -- Continue execution until an address or function
|
||||
|
||||
#### 使用 PEDA 和 Python 编写 gdb 脚本
|
||||
- 全局类
|
||||
- `pedacmd`:
|
||||
- 交互式命令
|
||||
- 没有返回值
|
||||
- 例如:`pedacmd.context_register()`
|
||||
- `peda`:
|
||||
- 与 gdb 交互的后端功能
|
||||
- 有返回值
|
||||
- 例如:`peda.getreg("eax")`
|
||||
- 小工具
|
||||
- 例如:`to_int()`、`format_address()`
|
||||
- 获得帮助
|
||||
- `pyhelp peda`
|
||||
- `pyhelp hex2str`
|
||||
- 单行/交互式使用
|
||||
- `gdb-peda$ python print peda.get_vmmap()`
|
||||
- ```
|
||||
gdb-peda$ python
|
||||
> status = peda.get_status()
|
||||
> while status == "BREAKPOINT":
|
||||
> peda.execute("continue")
|
||||
> end
|
||||
```
|
||||
- 外部脚本
|
||||
- ```
|
||||
# myscript.py
|
||||
def myrun(size):
|
||||
argv = cyclic_pattern(size)
|
||||
peda.execute("set arg %s" % argv)
|
||||
peda.execute("run")
|
||||
```
|
||||
```
|
||||
gdb-peda$ source myscript.py
|
||||
gdb-peda$ python myrun(100)
|
||||
```
|
||||
|
||||
下面我们通过一道 CTF 题目来练习一下 PEDA 脚本的编写:[asis-ctf-quals-2014 serial-number re-300](../src/Reverse/2.2_serial_number_300)
|
||||
```
|
||||
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
|
||||
{
|
||||
__int64 result; // rax@5
|
||||
int v4; // ecx@9
|
||||
int v5; // ecx@9
|
||||
int v6; // ecx@9
|
||||
int v7; // ecx@9
|
||||
int v8; // ecx@9
|
||||
unsigned __int64 v9; // [sp+8h] [bp-68h]@4
|
||||
int v10; // [sp+10h] [bp-60h]@9
|
||||
int v11; // [sp+14h] [bp-5Ch]@9
|
||||
int v12; // [sp+18h] [bp-58h]@9
|
||||
int v13; // [sp+1Ch] [bp-54h]@9
|
||||
int v14; // [sp+20h] [bp-50h]@9
|
||||
int v15; // [sp+24h] [bp-4Ch]@9
|
||||
int v16; // [sp+28h] [bp-48h]@9
|
||||
int v17; // [sp+2Ch] [bp-44h]@9
|
||||
unsigned __int64 v18; // [sp+38h] [bp-38h]@6
|
||||
int v19; // [sp+44h] [bp-2Ch]@4
|
||||
_QWORD *v20; // [sp+48h] [bp-28h]@1
|
||||
int i; // [sp+54h] [bp-1Ch]@1
|
||||
int v22; // [sp+58h] [bp-18h]@1
|
||||
int v23; // [sp+5Ch] [bp-14h]@1
|
||||
|
||||
v23 = 0;
|
||||
v22 = 1;
|
||||
v20 = malloc(4uLL);
|
||||
for ( i = 0; i <= 3; ++i )
|
||||
{
|
||||
v20[i] = malloc(0xCuLL);
|
||||
*(_DWORD *)(v20[i] + 8LL) = 1;
|
||||
}
|
||||
printf("Enter serial number in hex formet (without 0x prefix) : ", a2);
|
||||
v19 = scanf("%llx", &v9);
|
||||
if ( v19 > 0 )
|
||||
{
|
||||
v18 = v9;
|
||||
while ( v9 )
|
||||
{
|
||||
v22 ^= 1u;
|
||||
if ( *(_DWORD *)*v20 != v22 && v22 )
|
||||
{
|
||||
v14 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v15 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v16 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v17 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v23 = *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)(v16 & v17) & *(_DWORD *)(*v20 + 4LL);
|
||||
v4 = *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & (v14 | (v15 == 0) | v16 | (v17 == 0))) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & ((v14 == 0) | (v15 == 0) | v16 | v17)) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & (v14 | v15 | (v16 == 0) | v17)) & (*(_DWORD *)(*v20 + 4LL) == 0) | *(_DWORD *)(*v20 + 4LL) & *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (v14 == 0) & (v15 == 0) & (unsigned __int8)(v16 & v17);
|
||||
v13 = v4 | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL);
|
||||
v5 = *(_BYTE *)(v20[1] + 4LL) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)((v14 == 0) | v15 | (v16 == 0) | v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)(v14 | (v15 == 0) | v16 | v17) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)((v14 == 0) | v15 | v16 | v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | *(_DWORD *)(*v20 + 4LL) & *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (unsigned __int8)v15 & (unsigned __int8)v16 & (v17 == 0);
|
||||
v12 = v5 | *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL);
|
||||
v6 = (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (v14 == 0) & (unsigned __int8)v15 & (v17 == 0 && v16 == 0) & *(_DWORD *)(*v20 + 4LL) | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0 && *(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0 && *(_DWORD *)(v20[3] + 4LL) == 0 && (v14 == 0 || v15 == 0 || v17 == 0 || v16 == 0)) & (*(_DWORD *)(*v20 + 4LL) == 0) | *(_DWORD *)(*v20 + 4LL) & (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0) & (v16 == 0) & (unsigned __int8)v17;
|
||||
v11 = *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & (v14 | (v15 == 0) | v16 | (v17 == 0))) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (unsigned __int8)v14 & (unsigned __int8)v15 & (v17 == 0 && v16 == 0) & *(_DWORD *)(*v20 + 4LL) | *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)((v14 == 0) | v15 | (v16 == 0) | v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | v6 | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL);
|
||||
v7 = *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0 && *(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)(v14 & v15 & v16 & v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0 && *(_DWORD *)(v20[3] + 4LL) == 0 && *(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(*v20 + 4LL) == 0) & (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)(v16 & v17);
|
||||
v8 = *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)v16 & (v17 == 0) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0 && v17 == 0 && v16 == 0) & (*(_DWORD *)(*v20 + 4LL) == 0) | v7;
|
||||
v10 = *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (v14 == 0) & (unsigned __int8)v15 & (v16 == 0) & (unsigned __int8)v17 & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (v14 == 0) & (v15 == 0) & (unsigned __int8)v16 & (v17 == 0) & (*(_DWORD *)(*v20 + 4LL) == 0) | v8 | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL);
|
||||
sub_40064D((unsigned int)v13, v20[3]);
|
||||
sub_40064D((unsigned int)v12, v20[2]);
|
||||
sub_40064D((unsigned int)v11, v20[1]);
|
||||
sub_40064D((unsigned int)v10, *v20);
|
||||
}
|
||||
*(_DWORD *)v20[3] = v22;
|
||||
*(_DWORD *)v20[2] = v22;
|
||||
*(_DWORD *)v20[1] = v22;
|
||||
*(_DWORD *)*v20 = v22;
|
||||
}
|
||||
if ( v23 == 1 )
|
||||
printf("\nCongratulation! Send \"ASIS_MD5(%llx)\" as the flag!", v18);
|
||||
else
|
||||
printf("Sorry! The serial number is incorrect!");
|
||||
result = 0LL;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid number.");
|
||||
result = 0LL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
上面是在 IDA Pro 中 F5 的结果,可以看到程序中有非常长的位操作逻辑,如果硬着头皮分析的话会非常困难。下面我们借用 PEDA 强大的能力来解决它,首先简化下上面的代码:
|
||||
```
|
||||
int v9; // serial_number
|
||||
int v23; // correct_serial
|
||||
|
||||
v23 = 0;
|
||||
|
||||
while (v9) {
|
||||
v14 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v15 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v16 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v17 = v9 & 1;
|
||||
v9 >>= 1;
|
||||
v23 = v23 = *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)(v16 & v17) & *(_DWORD *)(*v20 + 4LL);
|
||||
(v20, v20[1], v20[2], v20[3]) = very_long_bit_operation_asm((v20, v20[1], v20[2], v20[3]), (v14, v15, v16, v17));
|
||||
}
|
||||
|
||||
if (v23 == 1) {
|
||||
printf("Congratulation!");
|
||||
}
|
||||
```
|
||||
大概就是这样,我们用 `very_long_bit_operation_asm()` 函数代替了近千行的位操作,它的参数可以分为两组,`(v20, v20[1], v20[2], v20[3])` 和 `(v14, v15, v16, v17)`,每个组表示 4 比特的变量。所以,无论这个函数是什么操作,都只有 `16 * 16 = 256` 种可能,我们就可以使用暴力的方式破解它。
|
||||
|
||||
通过设置 `rip` 为循环代码的开始,并在 `` 函数结束处设置断点,我们就可以使代码循环执行了。
|
||||
```text
|
||||
0000000000400768 loc_400768: ; CODE XREF: main+E43
|
||||
...
|
||||
.text:0000000000400788 mov rax, [rbp+var_68]
|
||||
...
|
||||
000000000040149C
|
||||
.text:000000000040149C loc_40149C: ; CODE XREF: main+DC
|
||||
.text:000000000040149C ; main+E6
|
||||
...
|
||||
00000000004014D8
|
||||
.text:00000000004014D8 loc_4014D8: ; CODE XREF: main+C7
|
||||
.text:00000000004014D8 mov rax, [rbp+var_68]
|
||||
```
|
||||
|
||||
参考 http://blog.ztrix.me/blog/2014/05/10/asis-quals-2014-serial-number-writeup/
|
||||
|
||||
#### 更多资料
|
||||
http://ropshell.com/peda/
|
||||
|
||||
|
@ -1 +1,6 @@
|
||||
# Fuzz 测试
|
||||
|
||||
- [AFL](#afl)
|
||||
|
||||
|
||||
## AFL
|
||||
|
@ -1,7 +1,8 @@
|
||||
# Symbolic Execution 符号执行技术
|
||||
# 5.5 符号执行
|
||||
|
||||
- [符号执行的历史](#符号执行的历史)
|
||||
- [什么是符号执行](#什么是符号执行)
|
||||
|
||||
* [符号执行的历史](#符号执行的历史)
|
||||
* [什么是符号执行](#什么是符号执行)
|
||||
|
||||
## 符号执行的历史
|
||||
|
||||
@ -10,8 +11,4 @@
|
||||
或者进入[https://github.com/enzet/symbolic-execution](https://github.com/enzet/symbolic-execution)查看SVG大图。
|
||||
|
||||
|
||||
|
||||
## 什么是符号执行
|
||||
|
||||
|
||||
|
||||
|
BIN
src/Reverse/2.2_serial_number_300
Executable file
BIN
src/Reverse/2.2_serial_number_300
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user