osquery审计

medium.com/palantir/auditing-with-osquery-part-two-configuration-and-implementation-87a8bba0ef48

介绍使用osquery启用审计。

如何配置以及对系统性能的影响。

回文数

题目

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:

1
2
输入: 121
输出: true

示例 2:

1
2
3
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

示例 3:

1
2
3
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。

思路

先判断是否为负,为负数则返回false,然后循环取出每一位存到另一个int变量中,每次变量在自乘10,完事之后对比一下就可以了。

代码

1

bool isPalindrome(int x) {
int a=x;
long int sum=0;
if(x<0)
return false;
else
{
while(a)
{
sum=sum*10+a%10;
a=a/10;
}
if(x==sum)
return true;
else
return false;
}
}

1

sync

分享一个Linux命令sync

sync作用是,将有关文件系统的存储器常驻信息送入物理介质内。

Linux文件系统更新是一个复杂的过程,当用户程序对文件系统进行修改以后,例如进行了写操作,文件数据把修改记录在内核缓冲中,在数据没有写到磁盘的时候,依然能够执行用户进程,所有数据的改变都在inode的内容中得到反映。磁盘的数据更新实际上是异步进行的,很有可能在写操作已经完成很长时间以后才真正对磁盘的数据进行更新。

我一般在准备强制关机前,执行sync命令防止数据丢失。

单用户修改Linux用户密码

有时候旧电脑中的Linux系统长时间不使用,忘记了密码,但是又想拿到里面的数据,这时候我们可以使用单用户登陆的方式登陆系统,并更改root用户密码。

以CentOS为例,系统启动后进入grub,按e编辑内核引导参数选项,在内核引导参数后面加上

-single

然后进入系统,就是单用户模式了,这时候可以直接使用passwd命令修改root用户密码,修改成功后重启机器,我们就可以使用修改后的密码登陆到系统当中了。

Linux审计框架

wiki.archlinux.org/index.php/Audit_framework

这是一篇介绍Linux系统审计框架的文档,Linux的审计功能并不提供额外的安全特性,但是可以用来辅助追踪安全问题。用户也可以根据自己的需求定制审计规则以及配置文件。

两数之和

题目

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

1
2
3
4
给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

思路

想到两种方法,一个是嵌套两层循环查找,一个是用hash map,但是c手撸hash map有点麻烦,偷懒用了循环查找,题目比较简单,就不详细说了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target) {
static int a[2]={0};


for (int i = 0; i < numsSize - 1; i++)
{
for (int j = i+1; j < numsSize; j++)
{
if (nums[i] + nums[j] == target)
{
a[0] = i;
a[1] = j;
return a;
}
}
}
return 0;
}
​```

ptrace

分享一个Linux的系统调用ptrace

ptrace函数的参数:

1
2
3
4
long ptrace(enum __ptrace_request request,
pid_t pid,
void *addr,
void *data);

具体使用方法可以man一下,很强大,linux下调试工具gdb主要使用的就是ptrace。ptrace可以实现对另一进程的断点调试和跟踪系统调用,同样我们也可以使用这个调用来做反调试,防止我们的进程被跟踪调试,感兴趣的可以自己看一下ptrace的man手册。

加密grub

现在用Linux的人很多,但是默认的grub是不加密的,在grub引导内核的参数后面添加 –single就可以进入单用户模式并轻易修改用户的登录密码,这很不安全,为此可以给grub加个秘密简单防御一下。

使用工具

grub-md5-crypt

这个不用也可以,可以将grub的密码明文存储在文件中,就不说了。

运行grub-md5-crypt,提示输入两次密码,输入完成之后,会得到一个经过加密后的密文,接着编辑文件**/etc/grub.conf**,在末尾添加一行

passwd –md5 刚才得到的密文

完成,重启系统,进入grub就需要密码了。

Linux running on the L4 microkernel

news.ycombinator.com/item?id=18944165

并不算一篇文章,是L4内核一个社区的讨论,主要是讨论L4微内核的安全问题,在L4微内核上跑Linux驱动以及跑Linux应用的前景,但是L4有个弊端就是L4内核太小了,想要方便的使用,现在是需要借助其他操作系统的一些功能,最常见的就是现在的L4linux。

另外L4微内核是一种内核的代称,L4内核都具有同名内核接口,现在比较常见的有minix3和fiasco。这些讨论里也有人说苹果的t1和t2芯片上跑的也是微内核,大家也期望微内核未来能成为docker的替代品。

字符串转换整数

题目

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,qing返回 INT_MAX (2^31 − 1) 或 INT_MIN (−2^31) 。

示例 1:

1
2
输入: "42"
输出: 42

示例 2:

1
2
3
4
输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

1
2
3
输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:

1
2
3
4
输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
因此无法执行有效的转换。

示例 5:

1
2
3
4
输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
因此返回 INT_MIN (−231) 。

思路

先逐个判断,若不为‘+’‘-’并且小于0大于9,若都不符合返回0,若满足条件,再判断是否是‘+’‘-’,并根据‘-’号设置一个标志位用来最后返回值处理正负。
声明一个int的num用来存当前元素的整数值,一个unsigned int 的res用来存返回值,然后逐位判断元素是否在0-9内,把当前元素的值减去‘0’(ascii码相减) 就是他的数值存到num中,并根据flag值分别判断是否超过正负的范围,最小最大值分别是-2147483648和2147483647,主要是最后一位分开判断,分别是7和8,然后res×10+num,最后根据flag判断下正负,分别返回一下就可以了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int myAtoi(char* str) {
char *p =str;
while (*p == ' ') p++;
if(*p != '-' && *p != '+' && *p < '0' && *p > '9')
return 0;
char flag = (*p == '-')?1:2;
(*p == '-' || *p == '+') ? ++p:p;
int num = 0;
unsigned int res =0;
while (*p <= '9' && *p >= '0')
{
num = *p -'0';
if ((flag == 1) && ((res == INT_MAX/10 && num >8) || res >(INT_MAX/10))) return INT_MIN;
if ((flag == 2) && ((res == INT_MAX/10 && num >7) || res >(INT_MAX/10))) return INT_MAX;
res=res*10+num;
++p;
}
if (flag == 2)
return res;
else return res * -1;
}