醉梦轩

醉中无日月,梦里有乾坤

0x00 背景

使用基于Chrome的机器人技术可以模拟用户操作,从而实现爬虫薅羊毛等能力。为了避免恶意用户使用这类技术做出危害平台的事情,需要能够检测当前的浏览器环境是否安全。

阅读全文 »

0x00 背景

Linux由于一切皆文件,不管是文件、管道,还是socket,都可以轻易在父子进程间传递;而Windows上会复杂很多。最近有个需求,需要进行父子进程间的通信,常见的方案是在创建子进程时通过stdinstdoutstderr这三个句柄来传递管道句柄,从而达到父子进程间通信的目的。但这种方式最大的问题是:对子进程需要单独处理stdout和stderr,使用上有些限制。

阅读全文 »

0x00 前言

本文介绍了如何使用Scratch开发一款实时的时钟程序,通过这个例子,可以让学员加深对时钟运行规律的理解,同时学习到死循环、事件驱动等编程相关的知识点。

阅读全文 »

0x00 什么是binfmt-misc

binfmt-misc(Miscellaneous Binary Format)是Linux内核提供的一种类似Windows上文件关联的功能,但比文件关联更强大的是,它不仅可以根据文件后缀名判断,还可以根据文件内容(Magic Bytes)使用不同的程序打开。一个典型的使用场景就是:使用qemu运行其它架构平台上的二进制文件。

本文以该场景为例,分析一下其具体的工作原理。

阅读全文 »

0x00 背景

以前研究过一次在iPad上安装Linux系统,当时的方案是:AltStore + UTM,由于没有硬件虚拟化,性能非常差,只能安装服务器版Linux,而且UTM由于签名问题需要每7天续签一次,几乎不具有可玩性。

最近看到有帖子说UTM支持硬件虚拟化了,于是稍微研究了一下,上面的两个问题也都解决了。

阅读全文 »

0x00 前言

KTurtle 是一个KDE开发的 Turtle Graphics(海龟绘图法) 教育编程环境,通过控制海龟的行进,在屏幕上绘制出相应图案的技术。它是根据开源的 GNU通用公共许可证发布。它可以让孩子通过可视化方式学会基本的编程思维,并掌握一定的数学、几何等知识。它的结构非常简单,非常适合儿童学习。

KTurtle 使用TurtleScript语言进行操作,该语言是从Logo语言的基础上开发而来的。

阅读全文 »

0x00 背景

最近重装了一下Deepin v20系统,发现开机时Grub菜单字体变小了,看着很不舒服,就尝试着寻找了下解决方法。

Grub配置文件路径是:/etc/default/grub,所以主要就是修改这个文件。该文件的默认内容为:

INI
1
2
3
4
5
6
7
8
9
# Written by com.deepin.daemon.Grub2
DEEPIN_GFXMODE_ADJUSTED=1
GRUB_BACKGROUND=/boot/grub/themes/deepin-fallback/background.jpg
GRUB_CMDLINE_LINUX_DEFAULT="splash quiet"
GRUB_DEFAULT=0
GRUB_DISTRIBUTOR="`/usr/bin/lsb_release -d -s 2>/dev/null || echo UOS 20`"
GRUB_GFXMODE=3840x2160,1920x1080,1024x768,auto
GRUB_THEME=/boot/grub/themes/deepin-fallback/theme.txt
GRUB_TIMEOUT=5

修改这个文件后,使用update-grub命令更新Grub配置,然后重启电脑。

阅读全文 »

0x00 前言

在Python中,可以使用py2exePyInstaller之类的工具将Python脚本编译成二进制文件,从而提升可移植性,并在一定程度上提升了性能。不过这类工具的实现只是将py文件编译成pyc或pyo,在安全性上还是弱了一些,存在被反编译的风险。

为了测试不同编译方式的性能差异,这里统一使用python2.7中提供的test/pystone.py作为执行脚本。由于这个脚本不支持python3,因此做了下python3的适配。完整的测试代码如下:

PYTHON
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#! /usr/bin/env python

"""
"PYSTONE" Benchmark Program

Version: Python/1.1 (corresponds to C/1.1 plus 2 Pystone fixes)

Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013.

Translated from ADA to C by Rick Richardson.
Every method to preserve ADA-likeness has been used,
at the expense of C-ness.

Translated from C to Python by Guido van Rossum.

Version History:

Version 1.1 corrects two bugs in version 1.0:

First, it leaked memory: in Proc1(), NextRecord ends
up having a pointer to itself. I have corrected this
by zapping NextRecord.PtrComp at the end of Proc1().

Second, Proc3() used the operator != to compare a
record to None. This is rather inefficient and not
true to the intention of the original benchmark (where
a pointer comparison to None is intended; the !=
operator attempts to find a method __cmp__ to do value
comparison of the record). Version 1.1 runs 5-10
percent faster than version 1.0, so benchmark figures
of different versions can't be compared directly.

"""

LOOPS = 50000

try:
from time import perf_counter as clock
except ImportError:
from time import clock

__version__ = "1.1"

[Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6)

class Record:

def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0,
IntComp = 0, StringComp = 0):
self.PtrComp = PtrComp
self.Discr = Discr
self.EnumComp = EnumComp
self.IntComp = IntComp
self.StringComp = StringComp

def copy(self):
return Record(self.PtrComp, self.Discr, self.EnumComp,
self.IntComp, self.StringComp)

TRUE = 1
FALSE = 0

def main(loops=LOOPS):
benchtime, stones = pystones(loops)
print("Pystone(%s) time for %d passes = %g" % \
(__version__, loops, benchtime))
print("This machine benchmarks at %g pystones/second" % stones)


def pystones(loops=LOOPS):
return Proc0(loops)

IntGlob = 0
BoolGlob = FALSE
Char1Glob = '\0'
Char2Glob = '\0'
Array1Glob = [0]*51
Array2Glob = list(map(lambda x: x[:], [Array1Glob]*51))
PtrGlb = None
PtrGlbNext = None

def Proc0(loops=LOOPS):
global IntGlob
global BoolGlob
global Char1Glob
global Char2Glob
global Array1Glob
global Array2Glob
global PtrGlb
global PtrGlbNext

starttime = clock()
for i in range(loops):
pass
nulltime = clock() - starttime

PtrGlbNext = Record()
PtrGlb = Record()
PtrGlb.PtrComp = PtrGlbNext
PtrGlb.Discr = Ident1
PtrGlb.EnumComp = Ident3
PtrGlb.IntComp = 40
PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING"
String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING"
Array2Glob[8][7] = 10

starttime = clock()

for i in range(loops):
Proc5()
Proc4()
IntLoc1 = 2
IntLoc2 = 3
String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING"
EnumLoc = Ident2
BoolGlob = not Func2(String1Loc, String2Loc)
while IntLoc1 < IntLoc2:
IntLoc3 = 5 * IntLoc1 - IntLoc2
IntLoc3 = Proc7(IntLoc1, IntLoc2)
IntLoc1 = IntLoc1 + 1
Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3)
PtrGlb = Proc1(PtrGlb)
CharIndex = 'A'
while CharIndex <= Char2Glob:
if EnumLoc == Func1(CharIndex, 'C'):
EnumLoc = Proc6(Ident1)
CharIndex = chr(ord(CharIndex)+1)
IntLoc3 = IntLoc2 * IntLoc1
IntLoc2 = IntLoc3 / IntLoc1
IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1
IntLoc1 = Proc2(IntLoc1)

benchtime = clock() - starttime - nulltime
if benchtime == 0.0:
loopsPerBenchtime = 0.0
else:
loopsPerBenchtime = (loops / benchtime)
return benchtime, loopsPerBenchtime

def Proc1(PtrParIn):
PtrParIn.PtrComp = NextRecord = PtrGlb.copy()
PtrParIn.IntComp = 5
NextRecord.IntComp = PtrParIn.IntComp
NextRecord.PtrComp = PtrParIn.PtrComp
NextRecord.PtrComp = Proc3(NextRecord.PtrComp)
if NextRecord.Discr == Ident1:
NextRecord.IntComp = 6
NextRecord.EnumComp = Proc6(PtrParIn.EnumComp)
NextRecord.PtrComp = PtrGlb.PtrComp
NextRecord.IntComp = Proc7(NextRecord.IntComp, 10)
else:
PtrParIn = NextRecord.copy()
NextRecord.PtrComp = None
return PtrParIn

def Proc2(IntParIO):
IntLoc = IntParIO + 10
while 1:
if Char1Glob == 'A':
IntLoc = IntLoc - 1
IntParIO = IntLoc - IntGlob
EnumLoc = Ident1
if EnumLoc == Ident1:
break
return IntParIO

def Proc3(PtrParOut):
global IntGlob

if PtrGlb is not None:
PtrParOut = PtrGlb.PtrComp
else:
IntGlob = 100
PtrGlb.IntComp = Proc7(10, IntGlob)
return PtrParOut

def Proc4():
global Char2Glob

BoolLoc = Char1Glob == 'A'
BoolLoc = BoolLoc or BoolGlob
Char2Glob = 'B'

def Proc5():
global Char1Glob
global BoolGlob

Char1Glob = 'A'
BoolGlob = FALSE

def Proc6(EnumParIn):
EnumParOut = EnumParIn
if not Func3(EnumParIn):
EnumParOut = Ident4
if EnumParIn == Ident1:
EnumParOut = Ident1
elif EnumParIn == Ident2:
if IntGlob > 100:
EnumParOut = Ident1
else:
EnumParOut = Ident4
elif EnumParIn == Ident3:
EnumParOut = Ident2
elif EnumParIn == Ident4:
pass
elif EnumParIn == Ident5:
EnumParOut = Ident3
return EnumParOut

def Proc7(IntParI1, IntParI2):
IntLoc = IntParI1 + 2
IntParOut = IntParI2 + IntLoc
return IntParOut

def Proc8(Array1Par, Array2Par, IntParI1, IntParI2):
global IntGlob

IntLoc = IntParI1 + 5
Array1Par[IntLoc] = IntParI2
Array1Par[IntLoc+1] = Array1Par[IntLoc]
Array1Par[IntLoc+30] = IntLoc
for IntIndex in range(IntLoc, IntLoc+2):
Array2Par[IntLoc][IntIndex] = IntLoc
Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1
Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc]
IntGlob = 5

def Func1(CharPar1, CharPar2):
CharLoc1 = CharPar1
CharLoc2 = CharLoc1
if CharLoc2 != CharPar2:
return Ident1
else:
return Ident2

def Func2(StrParI1, StrParI2):
IntLoc = 1
while IntLoc <= 1:
if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1:
CharLoc = 'A'
IntLoc = IntLoc + 1
if CharLoc >= 'W' and CharLoc <= 'Z':
IntLoc = 7
if CharLoc == 'X':
return TRUE
else:
if StrParI1 > StrParI2:
IntLoc = IntLoc + 7
return TRUE
else:
return FALSE

def Func3(EnumParIn):
EnumLoc = EnumParIn
if EnumLoc == Ident3: return TRUE
return FALSE

if __name__ == '__main__':
import sys
def error(msg):
print >>sys.stderr, msg,
print >>sys.stderr, "usage: %s [number_of_loops]" % sys.argv[0]
sys.exit(100)
nargs = len(sys.argv) - 1
if nargs > 1:
error("%d arguments are too many;" % nargs)
elif nargs == 1:
try: loops = int(sys.argv[1])
except ValueError:
error("Invalid argument %r;" % sys.argv[1])
else:
loops = LOOPS
main(loops)

以下测试数据均为连续执行3次,取最大值。

阅读全文 »

0x00 背景

在某些场景下SSH服务器会禁用掉端口转发的能力,以降低安全风险。这会导致很多依赖SSH端口转发的工具无法正常工作。

这里主要是修改了/etc/ssh/sshd_config文件中以下几项实现的:

PLAINTEXT
1
2
3
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#X11Forwarding yes

此时,SSH服务器基本就变成了只能执行shell命令的工具,无法用于建立通信通道。

是否有办法可以绕过这一限制呢?答案是肯定的。

阅读全文 »

0x00 前言

为了加深对SSH协议的理解,准备自己实现一个SSH服务端,需要同时支持WindowsLinuxMacOS三大系统。为了尽量提升性能,准备使用协程(asyncio)来开发。

阅读全文 »