mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-24 19:21:15 +07:00
fix
This commit is contained in:
parent
541fe22448
commit
6cebda926b
131
doc/2.2_gdb.md
131
doc/2.2_gdb.md
@ -459,140 +459,11 @@ $ yaourt -S peda
|
||||
gdb-peda$ python myrun(100)
|
||||
```
|
||||
|
||||
下面我们通过一道 CTF 题目来练习一下 PEDA 脚本的编写:[asis-ctf-quals-2014 serial-number re-300](../src/Others/2.2_gdb/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/
|
||||
|
||||
|
||||
## GEF/pwndbg
|
||||
除了 PEDA 外还有一些优秀的 gdb 增强工具,功能大致相同,可以看情况选用。
|
||||
除了 PEDA 外还有一些优秀的 gdb 增强工具,特别是增加了一些查看堆的命令,可以看情况选用。
|
||||
- [GEF](https://github.com/hugsy/gef) - Multi-Architecture GDB Enhanced Features for Exploiters & Reverse-Engineers
|
||||
- [pwndbg](https://github.com/pwndbg/pwndbg) - Exploit Development and Reverse Engineering with GDB Made Easy
|
||||
|
@ -22,6 +22,7 @@
|
||||
- [调试(debugging)](#调试debugging)
|
||||
- [视图模式](#视图模式)
|
||||
- [Web 界面使用](#web-界面使用)
|
||||
- [cutter GUI](#cutter-gui)
|
||||
- [在 CTF 中的运用](#在-ctf-中的运用)
|
||||
- [更多资源](#更多资源)
|
||||
|
||||
@ -1104,6 +1105,25 @@ $ r2 -c=H [filename]
|
||||
默认地址为 `http://localhost:9090/`,这样你就可以在 Web 中进行操作了,但是我强烈建议你强迫自己使用命令行的操作方式。
|
||||
|
||||
|
||||
## cutter GUI
|
||||
cutter 是 r2 官方的 GUI,已经在快速开发中,基本功能已经有了,喜欢界面操作的读者可以试一下(请确保 r2 已经正确安装):
|
||||
```
|
||||
$ yaourt -S qt
|
||||
```
|
||||
```
|
||||
$ git clone https://github.com/radareorg/cutter
|
||||
$ cd cutter
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ qmake ../src
|
||||
$ make
|
||||
```
|
||||
然后就可以运行了:
|
||||
```
|
||||
./cutter
|
||||
```
|
||||
|
||||
|
||||
## 在 CTF 中的运用
|
||||
- [IOLI crackme](https://github.com/firmianay/Life-long-Learner/blob/master/binary-security/IOLI-crackme-Writeup.md)
|
||||
- [radare2-explorations-binaries](https://github.com/monosource/radare2-explorations-binaries)
|
||||
|
Loading…
Reference in New Issue
Block a user