分类 技术 下的文章

es6中的promise相关

// 例子1
  const testPromise = new Promise(function (resolve, reject) {
    let a = 5
    if (a === 5) {
      resolve('success')
    } else {
      reject('catch error2')
    }
  })
  // resolve 结果没法处理,一直抛出去
  testPromise.then(null, (res) => {
    console.log(res, 1)
  }).then(null, res => {
    console.log(res, 2)
  }).then(res => {
    console.log(res, 3)
  })

// 例子2
const testPromise = new Promise(function (resolve, reject) {
    let a = 5
    if (a === 5) {
      resolve('success')
    } else {
      reject('catch error2')
    }
  })
  testPromise.then(res => { console.log('res1', res); return 123}, err => { console.log('err1', err)})
    .then(res => { console.log('res2', res)}, err => { console.log('err2', err); return Promise.reject(456);})
    .then(res => { console.log('res3', res)}, err => { console.log('err3', err)})
    .then(res => { console.log('res4', res)}, err => { console.log('err4', err)})

87BCF1C372C9D7FF8013EB6EC00D8517.png

AF1C4ADC74288ED1B08554A85194FF08.png

react学习笔记

阮一峰入门教程

jsx 基本语法规则 遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析

// 组件的使用
class HelloMessage extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            liked: false
        }
    }
    static propTypes = {
        title: PropTypes.string.isRequired, // 验证属性
    }
    static defaultProps = {
        name: 'zhorz' // 设置默认属性 
    }
    toggle() {
        this.setState({liked: this.state.liked}) // 重新渲染组件
    }
    render() {
        return <h1>hello {this.props.name} <button onClick={this.toggle.bind(this)}>change</button></h1> 
        // 只能包含一个顶层标签,属性通过 this.props 对象获取
        // 通过 this.props.children (可以用React.Children代替) 可以获取组件子节点,vue中使用插槽 solt 实现
    }
}

// 注意属性名 class -> className,for -> htmlFor
ReactDOM.render(<HelloMessage name="zhorz"/>, document.getElementById('example'))


// react 获取 dom 的几种方式

class HelloMessage extends React.Component {
    handleClick() {
        this.refs.my.focus()
    }
    render() {
        return (
            <div>
                <input type="text" ref="my" />
                <input type="button" value="Focus the text input" onClick={this.handleClick.bind(this)} />
            </div>
        );
    }
}

class HelloMessage extends React.Component {
    constructor(props) {
        super(props)
        this.my = React.createRef()
    }
    handleClick() {
        this.my.current.focus()
    }
    render() {
        return (
            <div>
                <input type="text" ref={this.my} />
                <input type="button" value="Focus the text input" onClick={this.handleClick.bind(this)} />
            </div>
        );
    }
}

class HelloMessage extends React.Component {
    handleClick() {
        this.my.focus()
    }
    handleClick2 = () => {
        this.my.focus() // 使用箭头 函数,这种方式就不用 bind 了,this 指向定义时所在的对象
    }
    render() {
        return (
            <div>
                <input type="text" ref={(el) => { this.my = el}} />
                <input type="button" value="Focus the text input" onClick={this.handleClick2} />
            </div>
        );
    }
}

ReactDOM.render(
    <HelloMessage name="zhorz" />,
    document.getElementById('example')
);

style={{opacity: this.state.opacity}}
// 因为 React 组件样式是一个对象,所以第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象

极客时间demo

create-react-app 模块按需加载

create-react-app 引入组件

php+redis实现令牌桶限流

<?php
class RateLimit
{
    private $minNum = 60; //单个用户每分访问数
    private $dayNum = 10000; //单个用户每天总的访问量

    public function minLimit($uid)
    {
        $minNumKey = $uid . '_minNum';
        $dayNumKey = $uid . '_dayNum';
        $resMin    = $this->getRedis($minNumKey, $this->minNum, 60);
        $resDay    = $this->getRedis($minNumKey, $this->minNum, 86400);
        if (!$resMin['status'] || !$resDay['status']) {
            exit($resMin['msg'] . $resDay['msg']);
        }
    }

    public function getRedis($key, $initNum, $expire)
    {
        $nowtime  = time();
        $result   = ['status' => true, 'msg' => ''];
        $redisObj = $this->di->get('redis');
        $redis->watch($key); // redis watch 处理并发
        $limitVal = $redis->get($key);
        if ($limitVal) {
            $limitVal = json_decode($limitVal, true);
            $newNum   = min($initNum, ($limitVal['num'] - 1) + (($initNum / $expire) * ($nowtime - $limitVal['time'])));
            if ($newNum > 0) {
                $redisVal = json_encode(['num' => $newNum, 'time' => time()]);
            } else {
                return ['status' => false, 'msg' => '当前时刻令牌消耗完!'];
            }
        } else {
            $redisVal = json_encode(['num' => $initNum, 'time' => time()]);
        }
        $redis->multi();
        $redis->set($key, $redisVal);
        $rob_result = $redis->exec();
        if (!$rob_result) {
            $result = ['status' => false, 'msg' => '访问频次过多!'];
        }
        return $result;
    }
}

记一次Linux木马清除过程

记一次Linux木马清除过程

原文地址

xyl870612 FreeBuf 1周前
前段时间公司发生了一起服务器入侵事件,在此分享给大家也顺便理顺下linux入侵应急响应思路。

一、事件描述
某天监控同事反馈有台机器cpu飙高到2000%,可能机器已经被黑。于是登录上去查看,果然有个进程名为"HT8sUy71"的进程在作祟,这一看名字就不大可能是正常进程。

二、处理过程
2.1 查杀病毒进程
cpu占用率如此之高,基本可判断为挖矿程序无疑了,使用在线威胁情报系统对进程进行检测,不出所料,得出的标签是coinminer。这种挖矿进程一般都有自动重启机制,可能是某个进程的子进程,也可能在cron定时任务里出现。

首先,检查cron定时任务,发现/var/spool/cron/crontabs/root和/etc/cron.d/tomcat文件修改时间有变化,但是内容却无改动。

然后,使用ps -ef进行查找主进程,并无收获。同时发现此挖矿进程正在和“172.105.114.84”这个ip的8443端口进行通信,可能是黑客的一台远控服务器。

之后,lsof查看此进程在操作哪些文件,也无实际收获。

推测一定是有某个主进程在工作,so,继续通过ps和netstat查找监听所监听端口的异常。果不其然,看到异常进程,正在批量爆破,看来是被当做肉鸡了。同时使用lsof查看此进程文件,发现在调用/root/.ddg/4003.db文件,貌似是个加密的社工库。

判断是此程序即是主程序,kill掉挖矿进程后,使用strace -T -tt -e strace=full进行跟踪,发现主进程先对挖矿进程增加可执行权限,之后拉起进程。

那么现在kill掉主进程吧,发生个小插曲,发现主进程pid一直在变化,好吧,直接killall osryfa3。

至此,算是暂时消停一下,简单总结一下此病毒特征,其一方面释放挖矿病毒进行挖矿,同时又对公网ssh服务进行爆破以扩大感染面。在这里同时给了我一个提醒,或许这台服务器就是通过ssh爆破被入侵的。

2.2 查找入侵痕迹
一般情况下,入侵可能有以下几种方式:

a.各种弱口令爆破

b.系统漏洞的利用

c.应用漏洞的利用

上面说了,可能是通过ssh爆破被入侵的,我们先来验证一下。

查看登录日志,发现异常(下图是已经过滤掉正常登录的日志),基本可断定是通过ssh爆破入侵了,也可以断定ssh的访问控制已经失效。

cat /var/log/secure* | grep Accepted

结合以上ip查看爆破日志,确认以上ip的用户不是同一个人,是刚好有这么多ip同时爆破了root账户,而且最短的爆破时间只花了1分钟。想来这个root账户必然是个弱密码了。继续查找Failed日志的最早时间如下:

cat /var/log/secure* | grep Failed

基本可断定在这之前有人动过访问控制策略了,询问运维人员无果。

stats查看iptables、/etc/hosts.allow和/etc/hosts.deny文件状态,结合.bash_history命令,一切真相大白,一言难尽,你们自己体会。

2.3 病毒文件的清理
首先,使用stat查看上面两个进程的修改时间,大约在7月8号早上6点多,而ssh系统最早爆破时间是7月6号16:41。

然后,结合这两个时间来查找敏感目录中被修改过的系统文件,进行检查修复和清除。

find /etc/ /usr/bin/ /usr/sbin/ /bin/ /usr/local/bin/ /var/spool/cron/ -type f -mtime -3 | xargs ls -l

最后 ,使用chkrootkit、clamav、rkhunter一通查杀,当然,还是重装系统最保险。

三、总结
首先啰嗦一下,关于linux主机,高危端口真得万万不能全网开放。看了日志后,发现黑客真是时时刻刻在爆破啊。

关于linux入侵的排查思路,总结如下:

1.查看异常进程活动-查找是否有异常进程和端口占用
1.1查找占用cpu最多的进程,相关命令:运行top命令后,键入大写字母P按cpu排序;

1.2查找占用内存最多的进程,相关命令:运行top命令后,键入大写字母M

ps aux | sort -k4nr
1.3查找进程文件:

ls -la /proc/$pid/exe
1.4跟踪异常进程运行情况:

strace -tt -T -e trace=all -p $pid
1.5查看进程打开的文件

lsof -p $pid
1.6 查看进程端口情况

netstat -anltp | grep $pid
2.查看账号安全
2.1查看是否有存在新增异常账号:

a.查找特权用户

awk -F ":" '$3==0{print $1}' /etc/passwd
b.查找可以远程登录的账号信息

awk '/$1|$6/{print $1}' /etc/shadow
c.查找sudo权限账户

cat /etc/sudoers | grep -v "^#|^$" | grep "ALL=(ALL)"
2.2 查看是否有账号异常登录情况:

a.查看当前登录用户和其行为

w
b.查看所有用户最后一次登录的时间

lastlog
c.查看所有用户的登录注销信息及系统的启动、重启及关机事件

last
d.查看登录成功的日期、用户名及ip

grep "Accepted " /var/log/secure* | awk '{print $1,$2,$3,$9,$11}'
e.查看试图爆破主机的ip
grep refused /var/log/secure* | awk {'print $9'} | sort | uniq -c |sort -nr | moregrep "Failed password" /var/log/secure* | grep -E -o "(([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}))" | uniq -c
f.查看有哪些ip在爆破主机的root账号

grep "Failed password for root" /var/log/secure | awk '{print $11}' | sort
g.查看爆破用户名字典

grep "Failed password" /var/log/secure | awk {'print $9'} | sort | uniq -c | sort -nr
3.查找异常文件
3.1 查找cron文件中是否存在恶意脚本

/var/spool/cron//etc/crontab /etc/cron.d/ /etc/cron.daily/* /etc/cron.hourly/* /etc/cron.monthly/* /etc/cron.weekly/ /etc/anacrontab /var/spool/anacron/* 3.2 查看最近一段时间内被修改的系统文件
find /etc/ /usr/bin/ /usr/sbin/ /bin/ /usr/local/bin/ -type f -mtime -T | xargs ls -la
3.3 按时间排序,确认最近是否有命令被替换,可以结合rpm -Va命令

ls -alt /usr/bin /usr/sbin /bin /usr/local/binrpm -Va>rpm.log
3.4 确认是否有异常开机启动项

cat /etc/rc.localchkconfig --list
4.借助工具查杀病毒和rootkit
4.1 查杀rootkit

chkrootkit (下载地址-http://www.chkrootkit.org)rkhunter (下载地址-http://rkhunter.sourceforge.net)
4.2 查杀病毒

clamav(下载地址-http://www.clamav.net/download.html)
4.3 查杀webshell

cloudwalker(下载地址-http://github.com/chaitin/cloudwalker)
工具用法不再赘述,大家自行查阅。

*本文原创作者:xyl870612,本文属于FreeBuf原创奖励计划,未经许可禁止转载